Code covered by the BSD License  

Highlights from
addaxes.m v1.1 (Sep 2009)

image thumbnail
from addaxes.m v1.1 (Sep 2009) by Carlos Adrian Vargas Aguilera
Adds a new linked axis related by ANY monotonic function. Includes ZOOM/PAN and DATETICK utility!

addaxes(varargin)
function HA = addaxes(varargin)
%ADDAXES   Adds a new linked axis related by any monotonic function.
%
%   SYNTAX:
%          addaxes(...,'PropertyName',PropertyValue)
%          addaxes('off')
%          addaxes(AX,...)
%     HA = addaxes(...);
%
%   INPUT:
%     AX      - Uses given axes handle instead of current one.
%               DEFAULT: gca
%     'PN'/PV - Paired property/value inputs to define the new axes, at
%               least one of the following (see NOTE below):
%
%                --------------|---------------------|--------------------
%                   'NAME'             VALUE                DEFAULT
%                --------------|---------------------|--------------------
%                 'XFunction'     Function name or     @(x)interp1(...
%                     or              handle            get(AX,'XLim'),...
%                   'xfun'                              get(AX,'XLim'),...
%                                                       x,'linear',...,
%                                                         'extrap')
%
%                 'XInverse'     Function name or       Inverse function
%                     or              handle          of 'xfun' estimated
%                   'xinv'                                with FZERO.
%
%                 'XLegend'        XLABEL legend          '' (none)
%                     or
%                   'xleg'
%
%                   'XDate'     true, false, 'tlabel'    false (TLABEL not 
%                     or           or 'datetick'            used)
%                   'xdat'
%                --------------|---------------------|--------------------
%
%     'off'   - Deletes any axes previously added. See NOTE below.
%
%   OUTPUT:
%     HA - Handle of new axes. Not recommended to modify it. See NOTE
%          below.
%
%   DESCRIPTION:
%     This functions adds axes to an existent axes, and links them to work
%     with ZOOM/PAN and DATETICK (or TLABEL) if required.
%
%     The big difference with the PLOTYY function (besides of working with
%     the x-axis as well) is that the added axis is not forced to be
%     linearly related with the old one. See the EXAMPLE below.
%
%     The idea behind this function, is the creation of temporal invisible
%     axes to get the Ticks and TickLabels acoordingly to the specifyed
%     relationship. Then other axes are drawn above the current one with
%     the same limits but with the Ticks mapped by inverting the
%     relationships using the FZERO formulae or the given inverse function.
%     See NOTE below for some warnings.
%
%   NOTE:
%     * Optional inputs use its DEFAULT value when not given or [].
%     * Optional outputs may or not be called.
%     * Besides from the paired optional inputs in Table above, the
%       following normal axes properties may be used: 
%         'XColor'  'XTick'  'XTickLabel'
%       for  axis customization and 
%         'CLim'        'FontAngle'   'FontName'  'FontSize'
%         'FontUnits'   'FontWeight'  'Layer'     'LineWidth'   
%         'TickDir'     'TickLength' 
%       for axes customization.
%     * Of course, 'Y' axis properties as 'YFunction', 'YColor', etc., may
%       be used as well, but not for 'Z'.
%     * 'xFun', 'yFun', 'xInv' and 'yInv' must return an array of the same
%       size as the input and must be monotonically increasing or
%       decreasing.
%     * When the relationships 'xFun' and 'yFun' are not linear and given
%       by an interpolation (INTERP1 for example) the user must use them
%       carefully taking into account extrapolations and the approximations
%       results of the invertion formulae provided by FZERO.
%     * If the new axis are dates, use the 'XDate'or 'YDate' options like
%       in the following EXAMPLE.
%     * By now, the function only can be used to add another axes once.
%       That is, multiple axes cannot be added, and to include both x- and
%       y-axis give both 'xFun' and 'yFun' functions.
%
%   EXAMPLE:
%     % DATA
%      t = sort(unique(round(rand(50,1)*100)/100),'descend');
%      [X,Y,Z] = peaks(length(t));
%      xFun = @(x)interp1(X(1,:)',exp(t),x,'linear','extrap');  % Numerical
%      yFun = @(x)x.*abs(x)+datenum(date);                      % Cuadratic
%      xInv = @(x)interp1(exp(t),X(1,:)',x,'linear','extrap');  % Numerical
%     % PLOT
%      figure
%       imagesc(X(1,[1 end]),Y([1 end],1),Z), set(gca,'Layer','top')
%       addaxes(...                           % <- THE CLUE
%        'XFun'   ,xFun,...
%        'YFun'   ,yFun,...
%        'XInv'   ,xInv,...
%        'XLeg'   ,func2str(xFun),...
%        'YDat'   ,'tlabel',...     % date ticks!
%        'XColor' ,'b',...
%        'YColor' ,'r');
%        zoom on
%     
%   SEE ALSO:
%     AXES, PLOT, PLOTYY, FUNCTION_HANDLE, FZERO, DATETICK
%     and
%     TLABEL by Carlos Vargas
%     at http://www.mathworks.com/matlabcentral/fileexchange
%
%
%   ---
%   MFILE:   addaxes.m
%   VERSION: 1.1 (Sep dd, 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. (Jul 29, 2009)
%   1.1      Fixed bug with function inversion, thanks to Allen Hall. Added
%            'Inverse' options and 'Position' link. Fixed small bug related
%            with 'off' option. (Sep dd, 2009)

%   DISCLAIMER:
%   addaxes.m is provided "as is" without warranty of any kind, under the
%   revised BSD license.

%   Copyright (c) 2009 Carlos Adrian Vargas Aguilera

% INPUTS CHECK-IN
% -------------------------------------------------------------------------

% Parameters.
myAppName   = 'addAxes'; % Application data name.
zoomAppName = 'zoom_zoomOrigAxesLimits';

% Checks number of inputs and outputs.
if     nargin<1
 error('CVARGAS:addaxes:notEnoughInputs',...
  'At least 1 input is required.')
elseif nargout>1
 error('CVARGAS:addaxes:tooManyOutputs',...
  'At most 1 output is allowed.')
end


% -------------------------------------------------------------------------
% MAIN
% -------------------------------------------------------------------------
 
if ~((nargin==2) && isstruct(varargin{2}))
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % ADDAXES called from command window or a M-file
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 % Default.
 AX   = gca;
 xFun = @(x) interp1(get(AX,'XLim'),get(AX,'XLim'),x,'linear','extrap');
 yFun = @(x) interp1(get(AX,'YLim'),get(AX,'YLim'),x,'linear','extrap');
 xInv = [];
 yInv = [];
 xLeg = '';
 yLeg = '';
 dFun = 'tlabel';      % Function to use on date axis.
 nSeg = 0.25;          % Second to wait for double-click.
 
 % Program data. To be saved as application data named appname.
 data.AX   = AX;
 data.HA   = [];
 data.HF   = [];
 data.xNew = 0;
 data.yNew = 0;
 data.xFun = xFun;
 data.yFun = yFun;
 data.xInv = xInv;
 data.yInv = yInv;
 data.xLeg = xLeg;
 data.yLeg = yLeg;
 data.xDat = false;
 data.yDat = false;
 data.aOpt = {};
 data.aNam = myAppName;
 data.nSeg = nSeg;
 
 % Parse inputs.
 [data,xTic,yTic,xTLa,yTLa,flag] = parseInputs(data,dFun,varargin{:});
 clear varargin
 
 % Checks if 'off' option.
 if flag
  data = getappdata(data.AX,myAppName);
  if ~isempty(data)
   if ishandle(data.AX) % Fixed bug, Sep 2009
    zh = zoom(data.AX);
    ph = pan(data.HF);
    set(zh,'ActionPostCallback',[])
    set(ph,'ActionPostCallback',[])
    rmappdata(data.AX,myAppName)
    if ishandle(data.HA)
     linkaxes([data.AX data.HA],'off')
    end
   end
   if ishandle(data.HA)
    delete(data.HA)
   end
  end
  if nargout<0, HA = []; end
  return
 end
 
 % Gets axis parent.
 data.HF = ancestor(data.AX,{'figure','uipanel'});

 % Changes some aspects on old axes.
 view(data.AX,2)
 box (data.AX,'off')
 grid(data.AX,'off')
 
 % Gets new axis locations in front of old one.
 pxLoc = get(data.AX,'XAxisLocation');
 pyLoc = get(data.AX,'YAxisLocation');
 xLoc  = 'top';   if strcmp(pxLoc,xLoc), xLoc = 'bottom'; end
 yLoc  = 'right'; if strcmp(pyLoc,yLoc), yLoc = 'left';   end
 
 % Generates new axes.
 tempF = get(0    ,'CurrentFigure');
 tempA = get(tempF,'CurrentAxes');
 data.HA = axes(...
  'Parent'          ,data.HF,...
  'Color'           ,'none',...
  'Box'             ,'off',...
  'Units'           ,get(data.AX,'Units'),...
  'Position'        ,get(data.AX,'Position'),...
  'View'            ,get(data.AX,'View'),...
  'FontUnits'       ,get(data.AX,'FontUnits'),...
  'FontSize'        ,get(data.AX,'FontSize'),...
  'FontName'        ,get(data.AX,'FontNam'),...
  'FontWeight'      ,get(data.AX,'FontWeight'),...
  'FontAngle'       ,get(data.AX,'FontAngle'),...
  'Layer'           ,get(data.AX,'Layer'),...
  'LineWidth'       ,get(data.AX,'LineWidth'),...
  'Projection'      ,get(data.AX,'Projection'),...
  'TickLength'      ,get(data.AX,'TickLength'),...
  'TickDir'         ,get(data.AX,'TickDir'),...
  'XColor'          ,get(data.AX,'XColor'),...
  'YColor'          ,get(data.AX,'YColor'),...
  'XDir'            ,get(data.AX,'XDir'),...
  'YDir'            ,get(data.AX,'YDir'),...
  'XAxisLocation'   ,xLoc,...
  'YAxisLocation'   ,yLoc,...
  'XTick'           ,[],...
  'YTick'           ,[],...
  'Tag'             ,'addaxes',...
  data.aOpt{:});
 set(0    ,'CurrentFigure',tempF)
 set(tempF,'CurrentAxes'  ,tempA)
 
 % Links properties.
 theLinks = linkprop([data.AX data.HA],{'Units','Position','View'});
 setappdata(data.AX,[data.aNam 'Links'],theLinks);
 setappdata(data.HA,[data.aNam 'Links'],theLinks);
 
 % Fixes title.
 if strcmp(xLoc,'top')
  title(data.HA,get(get(data.AX,'Title'),'String'))
  title(data.AX,'')
  set(data.HA,'Position',get(data.AX,'Position')) % In case it moves
 end
 
 % Updates Ticks's and TickLabel's.
 updateTickAndTickLabel(data,xTic,yTic,xTLa,yTLa)
 
 % Sets ZOOM and PAN functionalities.
 zoom(data.AX,'reset')
 zh = zoom(data.AX);
 ph = pan(data.HF);
 set(zh,'ActionPostCallback',@addaxes)
 set(ph,'ActionPostCallback',@addaxes)

 % Links axes.
 linkaxes([data.AX data.HA])
 
 % Saves data.
 setappdata(data.HA,data.aNam,data)
 setappdata(data.AX,data.aNam,data)
 
else
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % ADDAXES called after ZOOM or PAN
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 % Loads data.
 data = getappdata(varargin{2}.Axes,myAppName);
 if isempty(data)
  if nargout==1, HA = data.HA; end
  return
 end
 
 % Checks axes.
 if any(~ishandle([data.AX data.HA]))
  if nargout==1, HA = data.HA; end
  return
 end
 
 % Finds out if double-click.
 pause(data.nSeg)
 drawnow
 doubleclick = strcmp(get(data.HF,'SelectionType'),'open');
 if doubleclick
  axis(data.AX,getappdata(data.AX,zoomAppName))
 end
 
 % Initializes.
 xTic = [];  xTLa = '';
 yTic = [];  yTLa = '';
 
 % Updates Ticks's and TickLabel's.
 updateTickAndTickLabel(data,xTic,yTic,xTLa,yTLa);
 
end
 

% OUTPUTS CHECK-OUT
% -------------------------------------------------------------------------

if nargout==1, HA = data.HA; end


% =========================================================================
% SUBFUNCTIONS
% -------------------------------------------------------------------------

function updateTickAndTickLabel(data,xTic,yTic,xTLa,yTLa)
% Updates Ticks's and TickLabel's.

% Gets axis limits.
pxLim = get(data.AX,'XLim');
pyLim = get(data.AX,'YLim');
set(data.HA,...
 'XLim'         ,pxLim,...
 'YLim'         ,pyLim)
xLim  = sort(data.xFun(pxLim));
yLim  = sort(data.yFun(pyLim));
if any(~isfinite(xLim)) || ~(diff(xLim)>eps(xLim(1)))
 warning('CVARGAS:addaxes:incorrectXfunctionLim',...
  ['"' func2str(data.xFun) '" is not a monotonical function ' ...
   'or generates NaNs within current X-axis range.'])
 return
end
if any(~isfinite(yLim)) || ~(diff(yLim)>eps(yLim(1)))
 warning('CVARGAS:addaxes:incorrectYfunctionLim',...
  ['"' func2str(data.yFun) '" is not a monotonical function ' ...
   'or generates NaNs within current Y-axis range.'])
 return
end

% Generates a temporal axes with new limits.
tempF = get(0    ,'CurrentFigure');
tempA = get(tempF,'CurrentAxes');
fTemp = figure(...
 'Visible'         ,'off',...
 'Units'           ,get(data.HF,'Units'),...
 'Position'        ,get(data.HF,'Position'));
aTemp = axes(...
 'Parent'          ,fTemp,...
 'Units'           ,get(data.AX,'Units'),...
 'Position'        ,get(data.AX,'Position'),...
 'View'            ,get(data.AX,'View'),...
 'XLim'            ,xLim,...
 'YLim'            ,yLim,...
 data.aOpt{:});
set(0    ,'CurrentFigure',tempF);
set(tempF,'CurrentAxes'  ,tempA);

% Sets date TickLabel's.
if data.xDat
 if strcmpi(data.xDat,'tlabel')
  try
   tlabel(aTemp,'x','keeplimits')
   if isempty(data.xLeg)
    data.xLeg = get(get(aTemp,'XLabel'),'String');
   end
  catch
   % A possible error is to zoom in beyond seconds!
   warning('CVARGAS:addaxes:zoomBeyondSecons',...
    'TLABEL does not work beyond seconds.')
   datetick(aTemp,'x','keeplimits') 
  end
 else
  datetick(aTemp,'x','keeplimits')
 end
end
if data.yDat
 if strcmpi(data.yDat,'tlabel')
  try
   tlabel(aTemp,'y','keeplimits')
   if isempty(data.yLeg)
    data.yLeg = get(get(aTemp,'YLabel'),'String');
   end
  catch
   % A possible error is to zoom in beyond seconds!
   warning('CVARGAS:addaxes:zoomBeyondSecons',...
    'TLABEL does not work beyond seconds.')
   datetick(aTemp,'y','keeplimits')
  end
 else
  datetick(aTemp,'y','keeplimits')
 end
end

% Changes Tick's and TickLabel's.
if (data.xNew~=0) && isempty(xTic)
 % Fixed bug, Sep 2009
 [xTic,xTLa] = changeTickAndTicklabel(...
  get(aTemp,'XTick'),get(aTemp,'XTickLabel'),data.xFun,data.xInv,pxLim,...
                                                                data.xDat);
 if (length(xTic)<2)
  warning('CVARGAS:addaxes:zoomXOut',...
   'Too depth ZOOM on x-axis!')
 else
  dTic = diff(xTic);
  if any(dTic<=eps(min(dTic)))
   warning('CVARGAS:addaxes:incorrectXfunctionTick',...
    ['"' func2str(data.xFun) '" is not a monotonical function ' ...
     'within current X-axis range.'])
   return
  end
 end
end
if (data.yNew~=0) && isempty(yTic)
 % Fixed bug, Sep 2009
 [yTic,yTLa] = changeTickAndTicklabel(...
  get(aTemp,'YTick'),get(aTemp,'YTickLabel'),data.yFun,data.yInv,pyLim,...
                                                                data.yDat);
 if (length(yTic)<2)
  warning('CVARGAS:addaxes:zoomYOut',...
   'Too depth ZOOM on y-axis!')
 else
  dTic = diff(yTic);
  if any(dTic<=eps(min(dTic)))
   warning('CVARGAS:addaxes:incorrectYfunctionTick',...
    ['"' func2str(data.yFun) '" is not a monotonical function ' ...
     'within current Y-axis range.'])
   return
  end
 end
end

% Deletes temporal axes.
delete(aTemp), delete(fTemp)
 
% Updates axes
set(data.HA,...
 'XTick'        ,xTic,...
 'YTick'        ,yTic,...
 'XTickLabel'   ,xTLa,...
 'YTickLabel'   ,yTLa);
 
% Sets legends.
if ~isempty(data.xLeg), set(get(data.HA,'XLabel'),'String',data.xLeg), end
if ~isempty(data.yLeg), set(get(data.HA,'YLabel'),'String',data.yLeg), end

function [Tic,TLa] = changeTickAndTicklabel(Tic,TLa,FUN,INV,LIM,DAT)
% Changes Tick's and TickLabel's.
if ~DAT
 ind = 1; if (str2double(TLa(ind,:))*Tic(ind))==0, ind = 2; end
 if str2double(TLa(ind,:))~=Tic(ind)
  expstr = int2str(log10(Tic(ind)/str2double(TLa(ind,:))));
  if ~strcmp(expstr,'0') && ~strcmp(expstr,'-0')
   ind = double(isspace(TLa));
   ini = arrayfun(@(x)repmat(' ',1,x),sum(cumprod(ind,2),2),...
                                                    'Uniformoutput',false);
   ind = fliplr(ind);
   fin = arrayfun(@(x)repmat(' ',1,x),sum(cumprod(ind,2),2),...
                                                    'Uniformoutput',false);
   TLa = strcat(ini,strtrim(cellstr(TLa)),['e' expstr],fin);
   if iscellstr(TLa), TLa = char(TLa); end
  end
 end
end

for k = 1:length(Tic)
 % Fixed Bug (thanks to Allen Hall), Sep 2009
 if isempty(INV)
  temp = fzero(@(x) FUN(x)-Tic(k),LIM(1));
  if ~((temp>=LIM(1) && (temp<=LIM(2))))
   temp = fzero(@(x) FUN(x)-Tic(k),LIM(2))
   if ~((temp>=LIM(1) && (temp<=LIM(2))))
    temp = fzero(@(x) FUN(x)-Tic(k),mean(LIM))
    datenum(temp)
    if ~((temp>=LIM(1) && (temp<=LIM(2))))
     error('CVARGAS:addaxes:unableToGetInverse',...
      ['Unable to get ''x'' from ' func2str(FUN) ' = ' num2str(Tic(k)) ...
       '. Better try given the inverse formulae.'])
    end
   end
  end
 else
  try
   temp = INV(Tic(k));
  catch
   error('CVARGAS:addaxes:errorWithInverse',...
     ['Unable to get ''x'' from ' func2str(INV) ' = ' num2str(Tic(k)) ...
     '. Error while evaluating.'])
  end
  if ~((temp>=LIM(1) && (temp<=LIM(2))))
     error('CVARGAS:addaxes:incorrectInverse',...
      ['Unable to get ''x'' from ' func2str(INV) ' = ' num2str(Tic(k)) ...
       '. Value out of bounds.'])
  end
 end
 Tic(k) = temp;
end
ind        = ~isfinite(Tic);
Tic(ind)   = [];
TLa(ind,:) = [];
if (length(Tic)>1) && (Tic(1)>Tic(2))
 Tic = sort(Tic);
 TLa = flipud(TLa);
end

function [data,xTic,yTic,xTLa,yTLa,flag] = parseInputs(data,dFun,varargin)
% Parses inputs.

% Defaults.
xTic = [];  xTLa = '';
yTic = [];  yTLa = '';

% Gets axes.
if ~isempty(varargin) && (length(varargin{1})==1) && ishandle(varargin{1})
 data.AX = varargin{1};
 if ~strcmp(get(data.AX,'Type'),'axes')
  error('CVARGAS:addaxes:incorrectHandleInput',...
   'First input must ve a valid axes handle.')
 end
 varargin(1) = [];
 % Updates functions.
 AX        = data.AX;
 data.xFun = eval(func2str(data.xFun));
 data.yFun = eval(func2str(data.yFun));
end

% Checks 'off' option.
flag = false;
if length(varargin)==1
 if isempty(varargin{1})
  % continue
 elseif strcmp(varargin{1},'off')
  flag = true;
  return
 end
 varargin(1) = [];
end

% Checks already used function.
if isappdata(data.AX,data.aNam)
 error('CVARGAS:addaxes:invalifFunctionUse',...
  'By now ADDAXES only can be used once. Use ''off'' option before.')
end

% Checks if paired options.
if rem(length(varargin),2)~=0
 error('CVARGAS:addaxes:incorrectPairedOptions',...
  'Option(s) must be paired property/value(s).')
end

% Saves defaults temporarly in case the given one is empty.
dxFun = data.xFun;
dyFun = data.yFun;

% Loop.
while ~isempty(varargin)
 if isempty(varargin{1})
  error('CVARGAS:addaxes:emptyPropertyName',...
   'Input property name can not be empty.')
 elseif ischar(varargin{1})
  n = length(varargin{1});
  if     strncmpi(varargin{1},'XFunction' ,max(4,n)), data.xFun = varargin{2}; data.xNew = 1;
  elseif strncmpi(varargin{1},'YFunction' ,max(4,n)), data.yFun = varargin{2}; data.yNew = 1;
  elseif strncmpi(varargin{1},'XInverse'  ,max(4,n)), data.xInv = varargin{2};
  elseif strncmpi(varargin{1},'YInverse'  ,max(4,n)), data.yInv = varargin{2};
  elseif strncmpi(varargin{1},'XLegend'   ,max(4,n)), data.xLeg = varargin{2};
  elseif strncmpi(varargin{1},'YLegend'   ,max(4,n)), data.yLeg = varargin{2};
  elseif strncmpi(varargin{1},'XDate'     ,max(4,n)), data.xDat = varargin{2};
  elseif strncmpi(varargin{1},'YDate'     ,max(4,n)), data.yDat = varargin{2};
  elseif strncmpi(varargin{1},'XTick'     ,max(5,n)), xTic      = varargin{2};
  elseif strncmpi(varargin{1},'YTick'     ,max(5,n)), yTic      = varargin{2};
  elseif strncmpi(varargin{1},'XTickLabel',max(6,n)), xTLa      = varargin{2}; 
  elseif strncmpi(varargin{1},'YTickLabel',max(6,n)), yTLa      = varargin{2}; 
  elseif strncmpi(varargin{1},'XColor'            ,max(2,n)) || ...
         strncmpi(varargin{1},'YColor'            ,max(2,n)) || ...
         strncmpi(varargin{1},'CLim'              ,max(2,n)) || ...
         strncmpi(varargin{1},'FontAngle'         ,max(5,n)) || ...
         strncmpi(varargin{1},'FontName'          ,max(5,n)) || ...
         strncmpi(varargin{1},'FontSize'          ,max(5,n)) || ...
         strncmpi(varargin{1},'FontUnits'         ,max(5,n)) || ...
         strncmpi(varargin{1},'FontWeight'        ,max(5,n)) || ...
         strncmpi(varargin{1},'Layer'             ,max(2,n)) || ...
         strncmpi(varargin{1},'LineWidth'         ,max(5,n)) || ...
         strncmpi(varargin{1},'TickDir'           ,max(3,n)) || ...
         strncmpi(varargin{1},'TickLength'        ,max(5,n))
    data.aOpt = {data.aOpt{:},varargin{1},varargin{2}};
  else
    error('CVARGAS:addaxes:invalidProperty',...
     ['Invalid property ''' varargin{1} '''.'])
  end
 else
  error('CVARGAS:addaxes:invalidPropertyType',...
   'Property name must be a valid one.')
 end
 varargin(1:2) = [];
end

% Checks empty functions.
if isempty(data.xFun), data.xFun = dxFun; end
if isempty(data.yFun), data.yFun = dyFun; end

% Checks string functions.
if ischar(data.xFun), data.xFun = str2func(data.xFun); end
if ischar(data.yFun), data.yFun = str2func(data.yFun); end

% Checks ticks and labels.
if ((size(xTLa,1)~=0) && (length(xTic)~=size(xTLa,1))) || ...
   ((size(yTLa,1)~=0) && (length(yTic)~=size(yTLa,1)))
 error('CVARGAS:addaxes:invalidLabels',...
  ['When ''TickLabel''s are specified, '...
   'the respective ''Tick''s should be given too.'])
end

% Checks date axis.
if data.xDat
 if ~ischar(data.xDat)
  data.xDat = dFun;
 else
  data.xDat = lower(data.xDat);
  if ~strcmp(data.xDat,'tlabel') && ~strcmp(data.xDat,'datetick')
   error('CVARGAS:addaxes:invalidDateFunction',...
    ['Unrecognized ''' data.xDat ''' function. ' ...
     'Must be one of ''tlabel'' or ''datetick''.'])
  end
 end
end
if data.yDat
 if ~ischar(data.yDat)
  data.yDat = dFun;
 else
  data.yDat = lower(data.yDat);
  if ~strcmp(data.yDat,'tlabel') && ~strcmp(data.yDat,'datetick')
   error('CVARGAS:addaxes:invalidDateFunction',...
    ['Unrecognized ''' data.yDat ''' function. ' ...
     'Must be one of ''tlabel'' or ''datetick''.'])
  end
 end
end


% [EOF]   addaxes.m

Contact us at files@mathworks.com