www.gusucode.com > Ogive_optimization_1.0.6 > tools/cm_and_cb_utilities/cmjoin.m
function [CMAP,LEV,WID,CLIM] = cmjoin(varargin) %CMJOIN Joins colormaps at certain levels. % % SYNTAX: % cmjoin(CMAPS) % cmjoin(CMAPS,LEV) % cmjoin(CMAPS,LEV,WID) % cmjoin(CMAPS,LEV,WID,CLIM) % cmjoin(AX,...) % [CMAP,LEV,WID,CLIM] = cmjoin(...); % % INPUT: % CMAPS - Cell with the N colormaps handles, names or RGB colors to be % joined. See NOTE below. % LEV - One of: % a) N-1 scalars specifying the color levels where the % colormaps will be joined (uses CAXIS). See NOTE below. % b) N integers specifying the number of colors for each % colormap. % c) N+1 scalars specifying the color limits for each % colormap (sets CAXIS). See NOTE below. % DEFAULT: Tries to generate a CMAP with default length. % WID - May be one (or N) positive scalar specifying the width for % every (or each) color band. See NOTE below. % DEFAULT: uses CAXIS and LEV to estimate it. % CLIM - 2 elements row vector specifying the color limits values. May % be changed at the end, because of the discretization of the % colormaps. % DEFAULT: uses CAXIS or [0 1] if there are no axes. % AX - Uses the specified axes handle to get/set the CMAPS. If used, % must be the first input. % DEFAULT: gca % % OUTPUT (all optional): % CMAP - RGB colormap output matrix, M-by-3. % LEV - Final levels used. % WID - Final widths used. % CLIM - Final color limits used. % % DESCRIPTION: % This function join two colormaps at specific level. Useful for % joining colormaps at zero (for example) and distinguish from positive % and negative values. % % NOTE: % * Optional inputs use its DEFAULT value when not given or []. % * Optional outputs may or not be called. % * If no output is required or an axes handle were given, the current % COLORMAP and CAXIS are changed. % * If any of the inputs on CMAPS is a function name, 'jet', for % example, it can be used backwards (because CMAPPING is used) if % added a '-' at the beggining of its name: '-jet'. % * When LEV is type b) and WID is specifyed, the latter is taken as % relative colorbans widths between colormaps. % % EXAMPLE: % figure(1), clf, surf(peaks) % cmjoin({'copper','-summer'},2.5) % shading interp, colorbar, axis tight, zlabel('Meters') % title('Union at 2.5 m') % % % figure(2), clf, surf(peaks) % cmjoin({'copper','-summer'},2.5,0.5) % shading interp, colorbar, axis tight, zlabel('Meters') % title('Union at 2.5 m and different color for each 0.5 m band') % % % figure(3), clf, surf(peaks) % cmjoin({'copper','summer'},2.5,[2 0.5]) % shading interp, colorbar, axis tight, zlabel('Metros') % title('Union at 2.5 m with lengths 2 and 0.5') % % % figure(4), clf, surf(peaks) % cmjoin({'copper','summer'},[-10 2.5 10],[2 0.5]) % shading interp, colorbar, axis tight, zlabel('Metros') % title('Union at 2.5 m with lengths 2 and 0.5 and specified levels') % % % figure(5), clf, surf(peaks) % cmjoin({'copper','summer'},[10 8],[4 1]) % shading interp, colorbar, axis tight, zlabel('Metros') % title('Union at 2.5 m with specified levels number of colors and widths 4:1') % % SEE ALSO: % COLORMAP, COLORMAPEDITOR % and % CMAPPING by Carlos Vargas % at http://www.mathworks.com/matlabcentral/fileexchange % % % --- % MFILE: cmjoin.m % VERSION: 2.0 (Jun 08, 2009) (<a href="matlab:web('http://www.mathworks.com/matlabcentral/fileexchange/authors/11258')">download</a>) % MATLAB: 7.7.0.471 (R2008b) % AUTHOR: Carlos Adrian Vargas Aguilera (MEXICO) % CONTACT: nubeobscura@hotmail.com % REVISIONS: % 1.0 Released as SETCOLORMAP. (Nov 07, 2006) % 1.1 English translation. (Nov 11, 2006) % 2.0 Rewritten and renamed code (from SETCOLORMAPS to CMJOIN. Now % joins multiple colormaps. Inputs changed. (Jun 08, 2009) % DISCLAIMER: % cmjoin.m is provided "as is" without warranty of any kind, under the % revised BSD license. % Copyright (c) 2006,2009 Carlos Adrian Vargas Aguilera % INPUTS CHECK-IN % ------------------------------------------------------------------------- % Parameters: tol = 1; % When rounding the levels. % Checks inputs and outputs number: if nargin<1 error('CVARGAS:cmjoin:notEnoughInputs',... 'At least 1 input is required.') end if nargin>5 error('CVARGAS:cmjoin:tooManyInputs',... 'At most 5 inputs are allowed.') end if nargout>4 error('CVARGAS:cmjoin:tooManyOutputs',... 'At most 4 outputs are allowed.') end % Checks AX: AX = {get(get(0,'CurrentFigure'),'CurrentAxes')}; if isempty(AX{1}) AX = {}; end if (length(varargin{1})==1) && ishandle(varargin{1}) && ... strcmp(get(varargin{1},'Type'),'axes') AX = varargin(1); varargin(1) = []; if isempty(varargin) error('CVARGAS:cmjoin:notEnoughInputs',... 'CMAPS input must be given.') end end % Checks CMAPS: CMAPS = varargin{1}; Ncmaps = length(CMAPS); if ~iscell(CMAPS) || (Ncmaps<2) error('CVARGAS:cmjoin:incorrectCmapsType',... 'CMAPS must be a cell input with at least 2 colormaps.') end varargin(1) = []; Nopt = length(varargin); % Checks LEV and sets Ncol and Jlev: Ncol = []; % Number of colors for each colormap. Jlev = []; % Join levels. LEV = []; % Levels at which each CMAPS begins and ends. if (Nopt<1) || isempty(varargin{1}) % continue as empty elseif ~all(isfinite(varargin{1}(:))) error('CVARGAS:cmjoin:incorrectLevValue',... 'LEV must be integers or scalars.') else Nopt1 = length(varargin{1}(:)); if (Nopt1==Ncmaps) % Specifies number of colors: Ncol = varargin{1}(:); if ~all(Ncol==round(Ncol)) error('CVARGAS:cmjoin:incorrectLevInput',... 'LEV must be integers when defines number of colors.') end elseif ~all(sort(varargin{1})==varargin{1}) error('CVARGAS:cmjoin:incorrectLevInput',... 'LEV must be monotonically increasing.') elseif Nopt1==(Ncmaps-1) Jlev = varargin{1}(:); elseif Nopt1==(Ncmaps+1) LEV = varargin{1}(:); else error('CVARGAS:cmjoin:incorrectLevLength',... 'LEV must have any of length(CMAPS)+[-1 0 1] elements.') end end % Checks WID: Tcol = []; % Total number of colors for output colormap. if (Nopt<2) || isempty(varargin{2}) % Tries to generate a colormap with default length with every colorband % of the same width: WID = []; if ~isempty(AX) Tcol = size(colormap(AX{:}),1); else Tcol = size(get(0,'DefaultFigureColormap'),1); end else WID = varargin{2}(:); WID(~isfinite(WID) | (WID<0)) = 0; if ~any(WID>0) error('CVARGAS:cmjoin:incorrectWidInput',... 'At least one WID must be positive.') end if length(WID)==1 WID = repmat(abs(varargin{2}),Ncmaps,1); elseif length(WID)~=Ncmaps error('CVARGAS:cmjoin:incorrectWidLength',... 'WID must have length 1 or same as CMAPS.') end end % Checks CLIM: if (Nopt<3) || isempty(varargin{3}) % Sets default CLIM: if ~isempty(LEV) CLIM = [LEV(1) LEV(end)]; elseif ~isempty(AX) CLIM = caxis(AX{:}); else CLIM = [0 1]; end else CLIM = varargin{3}(:).'; if (length(CLIM)==2) && (diff(CLIM)>0) && isfinite(diff(CLIM)) % continue else error('CVARGAS:cmjoin:incorrectClimInput',... 'CLIM must be a valid color limits. See CAXIS for details.') end end % ------------------------------------------------------------------------- % MAIN % ------------------------------------------------------------------------- % Gets rounding precision: temp = warning('off','MATLAB:log:logOfZero'); if ~isempty(WID) tempp = WID; precision = floor(log10(abs(tempp))); precision(tempp==0) = 0; precision = min(precision)-tol; % Rounds: WID = round(WID*10^(-precision))*10^precision; if ~isempty(LEV) LEV(1) = floor(LEV(1) *10^(-precision))*10^precision; LEV(2:end-1) = round(LEV(2:end-1) *10^(-precision))*10^precision; LEV(end) = ceil(LEV(end) *10^(-precision))*10^precision; elseif ~isempty(Jlev) Jlev(1) = floor(Jlev(1) *10^(-precision))*10^precision; Jlev(2:end-1) = round(Jlev(2:end-1)*10^(-precision))*10^precision; Jlev(end) = ceil(Jlev(end) *10^(-precision))*10^precision; end elseif ~isempty(LEV) tempp = diff(LEV); precision = floor(log10(abs(tempp))); precision(tempp==0) = 0; precision = min(precision)-tol; % Rounds: LEV(1) = floor(LEV(1) *10^(-precision))*10^precision; LEV(2:end-1) = round(LEV(2:end-1)*10^(-precision))*10^precision; LEV(end) = ceil(LEV(end) *10^(-precision))*10^precision; elseif ~isempty(Jlev) tempp = diff(Jlev); if isempty(tempp) tempp = Jlev; end precision = floor(log10(abs(tempp))); precision(tempp==0) = 0; precision = min(precision)-tol; % Rounds: if length(Jlev)==1 Jlev = round(Jlev*10^(-precision))*10^precision; else Jlev(1) = floor(Jlev(1) *10^(-precision))*10^precision; Jlev(2:end-1) = round(Jlev(2:end-1)*10^(-precision))*10^precision; Jlev(end) = ceil(Jlev(end) *10^(-precision))*10^precision; end else tempp = CLIM; precision = floor(log10(abs(tempp))); precision(tempp==0) = 0; precision = min(precision)-tol; end % Rounds: CLIM(1) = floor(CLIM(1)*10^(-precision))*10^precision; CLIM(2) = ceil(CLIM(2)*10^(-precision))*10^precision; warning(temp.state,'MATLAB:log:logOfZero') % Completes levels when only join levels are specified: if ~isempty(Jlev) cedge = CLIM; % First limit: if cedge(1)<=Jlev(1) if ~isempty(WID) cedge(1) = Jlev(1); if WID(1)~=0 cedge(1) = cedge(1) - WID(1)*ceil((Jlev(1)-CLIM(1))/WID(1)); end else % continue end else if (Ncmaps==2) cedge(1) = Jlev(1); else for k = 2:length(Jlev) if cedge(1)<=Jlev(k) cedge(1) = Jlev(k-1); break else Jlev(k-1) = Jlev(k); end end end end % Last limit: if cedge(2)>=Jlev(end) if ~isempty(WID) cedge(2) = Jlev(end); if WID(end)~=0 cedge(2) = cedge(2) + WID(end)*ceil((CLIM(2)-Jlev(end))/WID(end)); end else % continue end else if (Ncmaps==2) cedge(2) = Jlev(end); else for k = length(Jlev)-1:-1:1 if cedge(2)>=Jlev(k) cedge(2) = Jlev(k+1); break else Jlev(k+1) = Jlev(k); end end end end % New Levels: LEV = [cedge(1); Jlev; cedge(2)]; end % Gets colorband width and sets WID: if ~isempty(Ncol) if isempty(WID) % Treats all colorbands with equal widths: Cwid = diff(CLIM)/sum(abs(Ncol)); Cwid = round(Cwid*10^(-(precision-1)))*10^(precision-1); WID = repmat(Cwid,Ncmaps,1); LEV = [CLIM(1); CLIM(1)+cumsum(abs(Ncol))*Cwid]; else % Treats WID as colorbands withs relations: WID = WID/min(WID(WID~=0)); Ncol2 = WID.*Ncol; Cwid = diff(CLIM)/sum(abs(Ncol2)); Cwid = round(Cwid*10^(-(precision-1)))*10^(precision-1); WID = WID*Cwid; LEV = [CLIM(1); CLIM(1)+cumsum(abs(Ncol2))*Cwid]; end elseif ~isempty(WID) % Gets colorband width: Cwid = WID(1)*10^(-precision); for k = 2:Ncmaps Cwid = gcd(Cwid,WID(k)*10^(-precision)); end Cwid = Cwid*10^precision; else % Gets relation between colomaps width: if isempty(LEV) r = ones(Ncmaps,1); d = diff(CLIM); else r = diff(LEV); temp = warning('off','MATLAB:log:logOfZero'); precision = floor(log10(abs(r))); % r = Str.XXX x 10^precision. precision(r==0) = 0; % precision=0 if Ncol=0. warning(temp.state,'MATLAB:log:logOfZero') precision = min(precision)-tol; r = round(r*10^(-precision)); rgcd = r(1); for k = 2:Ncmaps rgcd = gcd(rgcd,r(k)); end r = r/rgcd; d = (LEV(end)-LEV(1)); end % Gets colorband width: r = r*ceil(Tcol/sum(r)); Cwid = d/sum(r); WID = repmat(Cwid,Ncmaps,1); end % Sets LEV when empty: if isempty(LEV) LEV = linspace(CLIM(1),CLIM(2),Ncmaps+1)'; end % Gets number of colors for each colormap: Ncol2 = round(diff(LEV)/Cwid); if ~isempty(Ncol) % continue else Ncol = round(diff(LEV)./WID); Ncol(~isfinite(Ncol)) = 0; if ~all(Ncol==round(Ncol)) error('CVARGAS:cmjoin:incorrectWidColor',... 'Colorband do not match each colormap width. Modify LEV or WID.') end end % Generates the colormaps: CMAP = zeros(sum(abs(Ncol2)),3); xband = zeros(sum(abs(Ncol2))+1,1); tempr = []; for k = 1:Ncmaps if Ncol(k) r = sum(abs(Ncol2(1:k-1)))+(1:abs(Ncol2(k))); if Ncol(k)~=Ncol2(k) CMAP(r,:) = cmapping(Ncol2(k),cmapping(Ncol(k),CMAPS{k}),'discrete'); else CMAP(r,:) = cmapping(Ncol(k),CMAPS{k}); end tempr = linspace(LEV(k),LEV(k+1),abs(Ncol2(k))+1)'; xband(r) = tempr(1:end-1); end end if ~isempty(tempr) xband(end) = tempr(end); end % Cuts edges: ind = find((xband>=CLIM(1)) & (xband<=CLIM(2))); if (ind(1)~=1) && ~(any(xband==CLIM(1))) ind = [ind(1)-1; ind]; end if (ind(end)~=length(ind)) && ~(any(xband==CLIM(2))) ind = [ind; ind(end)+1]; end CMAP = CMAP(ind(1:end-1),:); clim2 = xband(ind([1 end])); % OUTPUTS CHECK-OUT % ------------------------------------------------------------------------- if ~nargout colormap(AX{:},CMAP) caxis(AX{:},clim2(:)'); clear CMAP else if ~isempty(AX) colormap(AX{:},CMAP) caxis(AX{:},clim2(:)'); end CLIM = clim2; WID = diff(LEV)./max([Ncol ones(Ncmaps,1)],[],2); end % [EOF] cmjoin.m