Code covered by the BSD License  

Highlights from
addaxis_unit

image thumbnail
from addaxis_unit by Friedhelm Steinhilber
This function adds a second y-axis to a x-y plot using a relationship between the two y-axes.

addaxis_unit(h,f,ticks2unit,ylabel2unit,TICKFORMAT)
function hAxes = addaxis_unit(h,f,ticks2unit,ylabel2unit,TICKFORMAT)
%Function adds a second y-axis (right) to the figure in such a way
%that only one curve is shown but with two different units.
%Unit 1 on the left y-axis,
%Unit 2 on the right y-axis.
%Unit1 and Unit2 are related to each-other by the inline function as given in func_y1.
%
%function hAxes = addaxis_unit(h,f,ticks2unit,ylabel2unit,TICKFORMAT)
%expects either A or B
% A:
%  h = 'reset'  Before the first subplot in one figure
%               Needed for the automatic ticklabeling of the second y-axis
%               See example: addunit_axis_example_hAxes_y1ticks
% B:
%  h: Handle of Figure, or Axes which should get the second y-axis
%     if h=Figure, Figure must not include subplots.
%     if h=Axes, subplots are possible
%     See and run example-files
%  f: Matlab function, which relates the two units: 
%      y1 = f(y2) or y2 = f(y1), depending on "ticks2unit"
%     The function can be:
%      1. A handle to a common Matlab function
%      2. A Matlab inline object f = inline('...y2','y2')
%      3. An anonymous Matlab function: f = @(y2)...y2...
%  ticks2unit: Gives ticks and labels of second y-axis
%     can be:
%      1. A vector with numerical values.
%      2. The string 'y1', which uses the same ticks as first y-axis. 
%         In this case the labels are calculated using "f".
%         "f" must be then: y2 = f(y1)  
%  ylabel2unit: Label for second y-axis [OPTIONAL]
%  TICKFORMAT: Format of labels for second y-axis [OPTIONAL]
%      Default: '%11.4g', for possible formats see fprintf 
%
%gives
%  hAxes: Handles of the two axes
%

%Version 2/6/2010
%Author: Friedhelm Steinhilber

global HAXES
global F
global BOOLY2EQY1

if nargin==1 & strcmp(h,'reset')==1
    clear global HAXES
    clear global F
    clear global BOOLY2EQY1
    global HAXES
    global F
    global BOOLY2EQY1
    disp('addaxis_unit is reseted.')
    return
end

if nargin<3
    warning('wrong call of function')
    help addaxis_unit
    return
end

if nargin==3
    ylabel2unit=[];
    %default format for y2-ticks
    TICKFORMAT = '%11.4g';
elseif nargin==4
    %default format for y2-ticks
    TICKFORMAT = '%11.4g';
end

%test if h=handle of figure or of axes
if isnumeric(get(h,'ylim'))
    %if handle is axes, occurrence of subplots is assumed
    hAxes(1) = h;
else
    %activate selected figure
    figure(h)
    hAxes(1) = gca;
    
    %if handle is figure, than no subplots
    clear global HAXES
    clear global F
    clear global BOOLY2EQY1
    global HAXES
    global F
    global BOOLY2EQY1
end

%get axes properties of 1st y-axis
pos = get(hAxes(1),'Position');
ydir = get(hAxes(1),'ydir');
yscale = get(hAxes(1),'yscale');
xscale = get(hAxes(1),'xscale');
ycolor = get(hAxes(1),'ycolor');
ylimit = get(hAxes(1),'ylim');
xlimit = get(hAxes(1),'xlim');
fontsize = get(get(hAxes(1),'yLabel'),'fontsize');

set(hAxes(1),'YAxisLocation','left',...
    'box','off')

%build a new axes object, with y-axis on the right
hAxes(2) = axes('Position',pos,...
    'XAxisLocation','top',...
    'YAxisLocation','right',...
    'YDir',ydir,...
    'YScale',yscale,...
    'XScale',xscale,...
    'Color','none',...
    'XTickLabel',[],...
    'XTick',[],...
    'YTickLabel',[],...
    'YTick',[],...
    'XColor','k',...
    'YColor',ycolor, ...
    'box','off');

%test if h=handle of figure or of axes
if isnumeric(get(h,'ylim'))
    HAXES = [HAXES hAxes];
    if iscell(F)
        F = {F{:} f};
    else
        F = {f};
    end
else
    HAXES = hAxes;
    F = f;
end


%build y2ticks
if strcmp(ticks2unit,'y1')
    y1ticks = get(hAxes(1),'ytick');
    ticks2unit = f(y1ticks)';
    y2ticks = y1ticks;
    BOOLY2EQY1 = [BOOLY2EQY1 1];
    set(gcf,'ResizeFcn',{@addaxis_unit_resizefcn,HAXES,F,BOOLY2EQY1,TICKFORMAT});
elseif isnumeric(ticks2unit)
    y2ticks = f(ticks2unit);
    %use only those ticks which are in the range of y1-axis
    idx = find(ylimit(1)<=y2ticks & y2ticks<=ylimit(2));
    y2ticks = y2ticks(idx);
    ticks2unit = ticks2unit(idx);
    BOOLY2EQY1 = [BOOLY2EQY1 0];
    set(gcf,'ResizeFcn',{@addaxis_unit_resizefcn,HAXES,F,BOOLY2EQY1,TICKFORMAT});
else
    warning('The variable "ticks2unit" has wrong format!')
end

%plot ticks on second y-axis             
set(hAxes(2),'ytick',y2ticks) 
set(hAxes(2),'yticklabel',num2str(ticks2unit,TICKFORMAT))
set(hAxes(2),'ylim',ylimit)
set(hAxes(2),'xlim',xlimit)
set(get(hAxes(2),'yLabel'),'string',ylabel2unit,'rotation',-90);
y2labelposition=get(get(hAxes(2),'yLabel'),'position');
set(get(hAxes(2),'yLabel'),'position',y2labelposition,...
    'fontsize',fontsize,'verticalalignment','bottom');

%link the two axes
linkaxes(hAxes)

if nargout==0
    clear hAxes
end

end

function addaxis_unit_resizefcn(hFigure,arg2,HAXES,F,BOOLY2EQY1,TICKFORMAT)
for i = 1:2:length(HAXES)
    if BOOLY2EQY1((i+1)/2)==1
        if iscell(F)
            f = cell2mat(F((i+1)/2));
        else
            f = F;
        end
        y1ticks = get(HAXES(i),'ytick');
        ticks2unit = f(y1ticks)';
        y2ticks = y1ticks;
        set(HAXES(i+1),'ytick',y2ticks)
        set(HAXES(i+1),'yticklabel',num2str(ticks2unit,TICKFORMAT))
    end
    set(HAXES(i+1),'position',get(HAXES(i),'position'))
end
end

Contact us at files@mathworks.com