Code covered by the BSD License  

Highlights from
subplotsCM

image thumbnail

subplotsCM

by

Andrew Bliss (view profile)

 

Creates subplots with less wasted space. Subplot sizes and margins are specified in centimeters.

[axout,hout]=subplotsCM(nrows,ncols,figwidth,figheight,varargin)
function [axout,hout]=subplotsCM(nrows,ncols,figwidth,figheight,varargin)
%SUBPLOTSCM creates subplots with less wasted space; margins measured in cm
%   [AX,H]=SUBPLOTSCM(NROWS,NCOLS,FIGWIDTH,FIGHEIGHT,W,E,NS,EW,N,S) where:
%   NROWS is the number of rows of subplots, NCOLS the number of columns.
%   FIGWIDTH and FIGHEIGHT are in centimeters. Defaults: 44, 25.5.
%   W, E, N, and S are the margin widths (in cm) for the west, east, north,
%      and south sides of the figure. Defaults: 1.4, 0.3, 0.2, 1
%   NS and EW are the margin widths between subplots. Defaults: 0.05, 0.05.
%   AX is a handle to the axes created.
%   H is the figure handle.
%
%   If FIGWIDTH or FIGHEIGHT are strings, SUBPLOTSCM will use the string
%   value as the subplot width or height and calculate the figure height or
%   width. E.g. if a subplot height of 3 cm is desired, FIGHEIGHT='3'
%
%   NOTE: Fontsize is set to 8. If you don't like that, comment it. 
%   NOTE: For log plots, you may need to comment the HOLD ON that I use to
%      keep the yaxislocation correct.
%   NOTE: if NS and/or EW are 0, use TICKLABELINSIDE to move the tick
%      labels inside the axis. It is on the file exchange.
%
%   Examples:
%       %really tight axes
%       ax=subplotsCM(2,3,25,15);
%       for n=1:6,plot(ax(n),1:10,rand(10,1)),end
%       set(ax([2 3 5 6]),'yticklabel',''),set(ax([1 2 3]),'xticklabel',''),linkaxes(ax)
%
%       %some space between axes, with a variety of margins for illustration
%       ax=subplotsCM(2,2,20,20,1.4,1,.95,.25,1,1.5);
%       for n=1:4,hold on,plot(ax(n),1:10,rand(10,1)),end
%       xlabel(ax(1),'north/south interior margin=.95'),ylabel(ax(1),'west margin=1.4'),title(ax(1),'north margin=1')
%       xlabel(ax(2),'east/west interior margin=.25'),ylabel(ax(2),'another ylabel')
%       xlabel(ax(3),'south margin=1.5'), ylabel(ax(4),'east margin=1')
%
%   See also: SUBPLOT, TICKLABELINSIDE.

%   Written by Andrew Bliss, April 2013

%set default width, height
if nargin==2 || isempty(figwidth) || isempty(figheight)
    figwidth=44; %44 fullscreen at 1680x1050; 8.6 publication;
    figheight=25.5; %25.5 fullscreen at 1680x1050; 12 publication;
end
%if fig parameters are characters, set the subplot size. Later we calculate
%   the figure height from the subplot height.
flagw=0;flagh=0;
if nargin>2 && ischar(figwidth)
    flagw=1;
    subplotw=str2double(figwidth);
end
if nargin>3 && ischar(figheight)
    flagh=1;
    subploth=str2double(figheight);
end
%set default margins
%   most comments refer to figures with 8 point font
margin.w=1.4; %1.8; %1.4 with ylabel and 4 digit yticklabel e.g. -100
margin.e=.3; %.2; %.3 with year as xticklabel
margin.ns=.05; %.05;
margin.ew=.05; %.05;
margin.n=.2; %.2; %.7 with title
margin.s=1; %1.2; %1 with xlabel
%reset margins if specified
marginorder={'w','e','ns','ew','n','s'};
for n=1:length(varargin)
    if ~isempty(varargin{n})
        margin.(marginorder{n})=varargin{n};
    end
end

%get figwidth and height from subplot width and height
if flagw
    figwidth=subplotw*ncols+margin.w+margin.e+(ncols-1)*margin.ew;
end
if flagh
    figheight=subploth*nrows+margin.s+margin.n+(nrows-1)*margin.ns;
end

%set subplot size
subplotheight=(figheight-margin.s-margin.n-(nrows-1)*margin.ns)/nrows;
subplotwidth=(figwidth-margin.w-margin.e-(ncols-1)*margin.ew)/ncols;

%open main figure
h=figure('units','centimeters','position',[0 0 figwidth figheight]);
pause(.05),set(h,'position',[0 0 figwidth figheight]) %reset position to make sure

%create the axes
counter=1;
for n=1:nrows
    for m=ncols:-1:1 %this is backwards so the counter increments the way you'd expect
        %Position vector: left x, bottom y, width, height
        axpos=[margin.w+(ncols-m)*(subplotwidth+margin.ew) margin.s+(nrows-n)*(subplotheight+margin.ns) ...
            subplotwidth subplotheight];
        ax(counter)=axes('units','centimeters','position',axpos);
        %aesthetics (all these are optional)
        hold on, box on
        set(ax(counter),'fontsize',8)
        if m==1 && ncols>1
            set(ax(counter),'yaxislocation','right')
        end
        counter=counter+1;
    end
end

%set outputs 
if nargout>0
    axout=ax;
end
if nargout>1
    hout=h;
end

Contact us