function fh = subfigure6p5(varargin)
%SUBFIGURE creates figures in tiled positions.
% H = SUBFIGURE(a,b,c) breaks the computer screen into an a-by-b matrix of
% small figures, selects the c-th figure for the current figure, and
% returns its handle. The figures are counted along the top row of the
% computer screen, then the second row, etc. This is the same way that
% SUBPLOT tiles axes in a figure. H is not returned if not requested.
% More than one figure can be created by calling SUBFIGURE with a cell of
% positions, or by specifying 'all' in the position argument. If 'all' is
% called, this will be treated as if a cell {1:a*b} had been passed. If
% more than one figure is created at a time, SUBFIGURE will create an axes
% object in each figure and H will have two columns. Each row of H will
% contain the figure handle and corresponding axes handle.
% SUBFIGURE has a 37 pixel offset from the bottom of the screen built-in.
% Since this is the first line of code, it is easily changed by the user
% for their particular system if needed or desired.
%
% SUBFIGURE(a,b,'all') or SUBFIGURE(a,b,{1:a*b}) plots a*b figures
% on screen in a a-by-b pattern.
% SUBFIGURE(a,b,C), where C is a vector, specifies a single figure position
% that covers all the subfigure positions in C.
% SUBFIGURE(N,N,{1:N:N^2}) plots N figures on the left side of the screen.
% SUBFIGURE(N,N,1:N:N^2) plots one figure that covers the figures from the
% previous example, in the left Nth of the screen.
% SUBFIGURE(N,N,{1:N}) plots N figures on the top of the screen.
% SUBFIGURE(N,N,1:N) plots one figure on the top Nth of the screen.
% SUBFIGURE(a,b,c,'replace') if a figure exists at position c, replaces it.
% SUBFIGURE(...,PROP1, VALUE1, PROP2, VALUE2, ...) sets the specified
% property-value pairs for the figure(s).
% SUBFIGURE(5,5,{1:5:25},'menubar','none') plots 5 figures with no menubars
% on the left hand side of the screen, this can be useful when plotting
% subfigures because the menubars can take up a lot of space (relatively).
%
% See also figure, subplot, close
%
% Author: Matt Fig
% Contact: popkenai@yahoo.com
% Date: 2/15/2009
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%% User editable offset from bottom of screen, in pixels.
offset = 37; % CHANGE THIS OFFSET FOR YOUR SYSTEM, IF NECESSARY OR DESIRED.
%%%%%%%%%%%%%%%%%%% User editable offset from bottom of screen, in pixels.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if nargin<3 % Error checking.
error('At least three input arguments are needed. See help.')
end
% pvpflag = false; % Flag: property/value pairs passed in.
rpflag = false; % Flag: user wanting to replace any figure in the way.
spflag = false; % Flag: user wants no menus.
cellflag = false; % Flag: user passed in a cell for third argument.
switch nargin
case 3
[a,b,c] = deal(varargin{:}); % The 'usual' case.
strt = 4;
case 4 % Could combine with otherwise, but this is a simpler case.
[a,b,c,str] = deal(varargin{:}); % User put replace, maybe. Must check.
strt = 5;
if ischar(str) && strncmpi('replace',str,3) % User passed 'rep'*
rpflag = true;
else
error('Unknown fourth option passed. See help.')
end
otherwise
% pvpflag = true; % User might have passed in property/value
% pairs.
[a,b,c] = deal(varargin{1:3}); % Deal out dimensions.
nmv = numel(varargin(4:end));
strt = 4;
if rem(nmv,2) % Odd indicates user may have passed in 'replace'
if strncmpi('replace',varargin{4},3)
rpflag = true;
strt = 5;
else
error('Unknown fourth option passed. See help.')
end
end
for ii = 1:numel(varargin(strt:end))
if strncmpi('men',varargin{ii+strt-1},3) % Look 4 menubars off.
if strncmpi('n',varargin{ii+strt},1) % 'menubar','none'
spflag = true; % This affects the y spacing.
dfpos = getsp(spflag);%Y Spacing between figs: NO MENUS
break;
end
end
end
end
if ischar(c)
if strcmpi(c,'all')
c = {1:a*b}; % User wants entire grid plotted.
else
error('The third argument must be numeric or ''all'', See help.')
end
end
if iscell(c)
c = [c{:}];
clen = length(c);
cellflag = true;
else
clen = 1;
end
if numel(a)>1 || numel(b)>1 || iscell(a) || iscell(b) % Error checking.
error('The first two arguments must be scalar.')
end
c = c(:)'; % Need a row vector.
if ~isnumeric([a,b,c]) || any([a,b,c]<1) || any(floor([a,b,c])~=[a,b,c])
error('First 3 args must be (or contain) integers > 0. See help.')
end
if any(c>a*b) % Error checking.
error('The third arg cannot exceed the product of the first two.')
end
if ~spflag
dfpos = getsp(spflag); % Y spacing between figs: with MENUS.
end
rsp = dfpos(4); % The absolute spacing between figures in row dir.
csp = dfpos(3); % The absolute spacing between figures in col dir.
un = get(0,'units'); % Will reset at the end.
set(0,'units','pix'); % Work in common units.
scr = get(0,'screensize'); % For proper formatting.
xpwidth = (scr(3) - b * csp - 2 )/b; % Width of figure.
ypheight = (scr(4) - a * rsp - offset + dfpos(2) )/a; % Height of figure.
if clen>1
fh = zeros(clen,2); % Pre-allocation.
else
fh = zeros(clen,1); % Pre-allocation.
end
for kk = 1:clen
if ~cellflag % A vector of locations.
p = zeros(length(c),4); % Pre-allocation.
% We need the positions of the figures that would be here to find
% the position of the figure that will cover the same area.
for mm = 1:length(c)
[ii,jj] = ind2sub([b,a],c(mm)); % Transpose: filling rows.
xpleft = ii*csp + xpwidth*(ii-1) - (dfpos(1)-1); % Left side.
ypbott = (a-jj)*rsp + ypheight*(a-jj) + offset; % Up by offset.
p(mm,:) = [xpleft ypbott xpwidth ypheight]; % Position of fig.
end
[m1 i1] = min(p(:,1)); % The minimum x-value of all figures.
[m2 i2] = min(p(:,2)); % The minimum y-value of all figures.
[i3,i3] = max(p(:,1)); %#ok The maximum x-idx of all figures.
[i4,i4] = max(p(:,2)); %#ok The maximum y-idx of all figures.
posvect = [m1 m2 p(i3,1)-p(i1,1)+p(1,3) p(i4,2)-p(i2,2)+p(1,4)];
else % A cell of locations.
[ii,jj] = ind2sub([b,a],c(kk)); % Transpose: we are filling rows.
xpleft = ii*csp + xpwidth*(ii-1)- (dfpos(1)-1); % Left side.
ypbott = (a-jj)*rsp + ypheight*(a-jj) + offset; % Up by offset.
posvect = [xpleft ypbott xpwidth ypheight]; % Position of figure.
end
if rpflag
try
fh(kk,1) = figreplace(posvect,varargin{strt:end}); % User wants to replace figure.
catch
fh(kk,1) = figreplace(posvect);
str = 'Bad Property or Value passed. Properties not assigned.';
warning('SUBFIGURE:PropertyValueSet',str)
end
else
try
fh(kk,1) = figure('units','pix','pos',posvect,varargin{strt:end}); % Do not replace fig.
catch
fh(kk,1) = figure('units','pix','pos',posvect);
str = 'Bad Property or Value passed. Properties not assigned.';
warning('SUBFIGURE:PropertyValueSet',str)
end
end
if clen>1
ax = axes; % More than one figure is called, make an axes.
fh(kk,2) = ax; % Assign it to the handle matrix.
end
end
if nargout==0
clear fh % User doesn't want the figure handles.
end
set(0,'units',un) % Reset this guy, as promised.
function dfpos = getsp(flag)
% Subfunction gets the necessary spacing. Includes menus or lack thereof.
% We only need to calculate this once for each type while SUBFUNCTION is
% in memory, so we will store the results in a persistent variable.
persistent dfp1 dfp0 % dfp1 stores position format for without menubars.
if flag
if isempty(dfp1)
invf = figure('units','pix','menubar','none'); % Invisible dummy.
set(invf,'visible','off'); % We don't need to see this guy.
op_pos = get(invf,{'outerp','pos'}); % Get the needed info.
delete(invf); % Delete our dummy figure.
dfpos = abs(op_pos{1}-op_pos{2}); % Calculate the dimensions.
dfp1 = dfpos;
else
dfpos = dfp1; % Use our persistent variable.
end
else
if isempty(dfp0)
invf = figure('units','pix'); % Dummy figure for formatting.
set(invf,'visible','off'); % We don't need to see this guy.
op_pos = get(invf,{'outerp','pos'}); % Get the needed info.
delete(invf); % Delete our dummy figure.
dfpos = abs(op_pos{1}-op_pos{2}); % Calculate the dimensions.
dfp0 = dfpos;
else
dfpos = dfp0; % Use our persistent variable.
end
end
function fh = figreplace(varargin)
% Subfunction deals with when user calls for figure to be replaced.
fh = get(0,'children'); % Get all of the current figures.
posvect = varargin{1};
M = numel(varargin(2:end));
try
[vrgn{1:M}] = deal(varargin{2:end});
catch
vrgn = [];
end
if isempty(fh)
try
fh = figure('units','pixels','pos',posvect,vrgn{:}); % Return our figure handle.
catch
fh = figure('units','pixels','pos',posvect);
end
return
end
num = numel(fh); % There are possible figures to replace.
un = get(fh,'units'); % Will reset at the end.
set(fh,'un','pix') ; % Work in common units.
if num>1
pos = cell2mat(get(fh,'pos')); % A matrix of position vectors.
else
pos = get(fh,'pos'); % Only one figure.
end
overlap = rectint(pos,repmat(posvect,num,1)); % Built-in to find overlap.
idx = find(overlap(:,1)); % Others have zero overlap.
if ~isempty(idx)
delete(fh(idx)); % Delete the figures that share position.
else
if iscell(un)
set(fh,{'units'},un); % Reset for user.
else
set(fh,'units',un); % Reset for user.
end
end
try
fh = figure('units','pixels','pos',posvect,vrgn{:}); % Return our figure handle.
catch
fh = figure('units','pixels','pos',posvect);
end