function CBH = cbfit(varargin)
%CBFIT Changes COLORMAP and CAXIS to fit between colorbar's ticks.
%
% SYNTAX:
% cbfit
% cbfit(NBANDS) % Or LBANDS
% cbfit(NBANDS,CENTER)
% cbfit(...,'force')
% cbfit(H,...)
% CBH = cbfit(...);
%
% INPUTS:
% NBANDS - If scalar, fits NBANDS colors between each colorbar ticks.
% If vector, fits a single color between specified LBANDS
% ticks.
% DEFAULT: 5
% CENTER - Centers the colormap to this reference.
% DEFAULT: [] (do not centers)
% 'force' - By default, CBFIT changes the actual ticks. Use this
% option to use the actual ones or the ones at LBANDS.
% H - Uses this colorbar handle (or peer axes, or figure)
% instead of current one.
%
% OUTPUTS (all optional):
% CBH - Returns the colorbar axes handle.
%
% DESCRIPTION:
% Draws a colorbar with specified number of color bands between its
% ticks by modifying the current colormap and caxis.
%
% NOTE:
% * Optional inputs use its DEFAULT value when not given or [].
% * Optional outputs may or not be called.
% * Sets the color limits, CAXIS, and color map, COLORMAP, before using
% this function. Use them after this function to get the
% modifications.
%
% EXAMPLE:
% Z = peaks; Z(Z<0) = Z(Z<0)*3;
% figure(1)
% surf(Z)
% colorbar
% title({'Normal "ugly" COLORBAR'; ...
% 'with colorbar ticks anywhere'; ...
% 'and "green" centered at -5!'})
% figure(2)
% surf(Z)
% cbfit(4,0)
% title({'CBFIT(4,0)'; ...
% 'Fitted 4 color bands between ticks'; ...
% 'and "green" centered at zero'})
%
% SEE ALSO:
% COLORBAR
% and
% CBFREEZE, CMFIT by Carlos Vargas
% at http://www.mathworks.com/matlabcentral/fileexchange
%
%
% ---
% MFILE: cbfit.m
% VERSION: 3.0 (Jun 05, 2014) (<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 COLORBARFIT.M. (Mar 11, 2008)
% 1.1 Fixed bug when CAXIS is used before this function. (Jul 01,
% 2008)
% 1.2 Works properly when CAXIS is used before this function. Bug
% fixed on subfunction and rewritten code. (Aug 21, 2008)
% 2.0 Rewritten code. Instead of the COLORBAND subfunction, now uses
% the CMFIT function. Changed its name from COLORBARFIT to
% CBFIT. (Jun 08, 2008)
% 2.1 Fixed bug and help with CBH input. (Sep 30, 2009)
% 3.0 Rewritten code. Changed optional input 'manual' to 'force'.
% Now accepts axes and figure handles as inputs. (Jun 05, 2014)
% DISCLAIMER:
% cbfit.m is provided "as is" without warranty of any kind, under the
% revised BSD license.
% Copyright (c) 2008-2014 Carlos Adrian Vargas Aguilera
% INPUTS CHECK-IN
% -------------------------------------------------------------------------
% Sets defaults:
NBANDS = 5;
LBANDS = [];
CENTER = [];
FORCE = false;
H = get(get(0,'CurrentFigure'),'CurrentAxes');
% Checks inputs/outputs number:
assert(nargin<=4, 'CVARGAS:cbfit:tooManyInputs',...
'At most 4 inputs are allowed.')
assert(nargout<=1, 'CVARGAS:cbfit:tooManyOutputs',...
'At most 1 output is allowed.')
% Reads FORCE:
if ~isempty(varargin) && ~isempty(varargin{end}) && ...
ischar(varargin{end})
if numel(varargin{end})==size(varargin{end},2)
switch lower(varargin{end})
case {'force','forc','for','fo','f'}
FORCE = true;
end
end
varargin(end) = [];
end
% Reads NBANDS and CENTER:
if ~isempty(varargin) && isnumeric(varargin{end})
if (length(varargin)>1) && isnumeric(varargin{end-1})
CENTER = varargin{end};
varargin(end) = [];
end
if numel(varargin{end})==1
NBANDS = varargin{end};
LBANDS = [];
else
LBANDS = reshape(varargin{end},[],1);
NBANDS = [];
end
varargin(end) = [];
end
% Reads H:
if (length(varargin)==1) && ~isempty(varargin{1}) && ...
all(reshape(ishandle(varargin{1}),[],1))
H = varargin{1};
end
% Gets colorbar handles or creates them:
CBH = cbhandle(H,'force');
Ncbh = length(CBH);
% -------------------------------------------------------------------------
% MAIN
% -------------------------------------------------------------------------
for icb = 1:Ncbh
% Generates a preliminary colorbar:
% Colorbar handle:
cbh = double(CBH(icb));
% Gets limits and orientation:
XYstr = 'Y';
ticks = get(cbh,[XYstr 'Tick']);
if isempty(ticks)
XYstr = 'X';
ticks = get(cbh,[XYstr 'Tick']);
end
XYLim = get(cbh,[XYstr 'Lim']);
tempp = ticks;
% Gets peer axes
peer = cbhandle(cbh,'peer');
% Gets width and ref:
if ~isempty(NBANDS)
% Force positive integers:
NBANDS = round(abs(NBANDS));
% Ignores ticks outside the limits:
if XYLim(1)>ticks(1)
ticks(1) = [];
end
if XYLim(2)<ticks(end)
ticks(end) = [];
end
% Get the ticks step and colorband:
tstep = ticks(2)-ticks(1);
WIDTH = tstep/NBANDS;
LBANDS = ticks;
% LBANDS = [fliplr(ticks(1)-WIDTH:-WIDTH:XYLim(1)) ...
% ticks(1):WIDTH:XYLim(2)];
% Sets color limits
if strcmp(get(peer,'CLimMode'),'auto')
caxis(XYLim);
end
% Forces old colorbar limits:
set(cbh,[XYstr 'Lim'],XYLim) % ,[XYstr 'Tick'],ticks)
else % ~isempty(LBANDS)
% Nonlinear colorbar:
ticks = LBANDS;
WIDTH = ticks;
% Scales to CLIM:
if strcmp(get(peer,'CLimMode'),'manual')
ticks = ticks-ticks(1);
ticks = ticks/ticks(end);
ticks = ticks*diff(XYLim) + XYLim(1);
end
XYLim = [ticks(1) ticks(end)];
caxis(peer,XYLim)
CBIH = get(cbh,'Children');
% Change ticks:
set(CBIH,[XYstr 'Data'],ticks)
% Sets limits:
set(cbh,[XYstr 'Lim'],XYLim)
end
% Get reference mark
if ~isempty(CENTER)
REF = CENTER;
CENTER = true;
else
REF = ticks(1);
CENTER = false;
end
% Fits the colormap and limits:
fig = get(peer,'Parent');
CMAP = colormap(fig);
cmfit(CMAP,XYLim,WIDTH,REF,CENTER);
% Sets ticks:
if FORCE
set(cbh,[XYstr 'Tick'],LBANDS)
end
end
% OUTPUTS CHECK-OUT
% -------------------------------------------------------------------------
if ~nargout
clear CBH
end
end
% [EOF] CBFIT.M by Carlos A. Vargas A.