Code covered by the BSD License  

Highlights from
Figure Management Utilities

image thumbnail
from Figure Management Utilities by Mirko Hrovat
These M-files are a collection of utilities for managing groups of figures on multiple monitors.

fighandle=tilefig(varargin)
function fighandle=tilefig(varargin)  
% fighandle = tilefig(figs,figname,monitor,layout)  TILE 1 or more FIGures.
% Tiles the screen for existing figures starting at the top left hand corner.
%   "fighandle" is an output array of handle numbers for the figures.
%   "figs" (first numeric input) is a vector of handles of the figures to be tiled. 
%       Default value is 0 which tiles all open figures.
%   "figname" (any argument position) is an optional string for each figure's name.
%       If not specified then figure names are retained, to erase names use ' '.
%   "monitor" (second numeric input) (Default=1) is an integer corresponding
%       to a monitor. Monitor numbering is defined by the row number of the
%       corresponding monitor in the root property 'MonitorPositions'. 
%   "layout" (third numeric input) is a vector (rows,columns) specifying the 
%       screen layout or a single number specifying the aspect ratio.
%       If not specified then the optimal layout will be determined.
%       If the specified layout only creates one row, then the figure
%       height is chosen to maintain the default aspect ratio.
%       The aspect ratio is the minimum horizontal/vertical figure size. 
%   Examples:
%           tilefig, tilefig([1,2,3],'Title',2), tilefig('Title'), 
%           figh=tilefig([2:12]); figh=tilefig([3,4],2);
%           tilefig(5,2,[2,3])
%
% NOTES:
% Figures are tiled in the order they are specified in "figs".
% The figures are numbered within this group of figures and not by their
%   figure handle.
% The figures are accessible by their handles. Thus "figure(fighandle(4))" 
%   will make the 4th figure from this group of figures the current figure.
% To delete the entire group of figures use "close(fighandle)".

%   Copyright 2006 Mirtech, Inc.
%   created 09/18/2006  by Mirko Hrovat on Matlab Ver. 7.2
%   Mirtech, Inc.       email: mhrovat@email.com
%   Inspired by "Tilefigs" by Charles Plum  
%   Uses getmondim.m
% More notes:
% Will work with docked figures, will ignore modal figures.
% Extended monitors may have a different resolution from the primary monitor.
% Placement and size of the taskbar on the primary monitor can be changed
%   in the code, see commented sections.
% The size and layout of the figures is determined by the aspect ratio and
%   the number of figure columns.
% For a large number of figures, the menubar and toolbar are removed to
%   increase figure space.
% Default properties for this group of figures may be coded into the code
%   below. The following properties are currently set.
%        'Units','pixels', ...
%        'NumberTitle','off',...
%        'MenuBar',menbar,...       (depends on number of figures)
%        'ToolBar',tbar             (depends on number of figures)

% --------- Key Constants -----------
% To allow for user or OS borders set the appropriate value in pixels.
topborder       =0;
bottomborder    =0;
rightborder     =0;
leftborder      =0;
taskbarborder   =30;
% Border properties for figures - Adjust if needed.
% determined by the difference between OuterPosition and Position values.
% GETFIGDIM can return these values for your system.  
figureborder    =5;     %#ok
titleheight     =26;
menbarheight    =21;
toolbarheight   =27;
minfigwidth     =125;
% Set the default aspect ratio (minimum horizontal/vertical size of the figure).
def_aspect      =1.1;   

menbarlimit     =3;     % no menubar if numrows > menbarlimit
toolbarlimit    =3;     % no toolbar if numrows > toolbarlimit
maxnumrows      =6;     % maximum number of figure rows to create
% ----------------------------------

monnum=[];
figs=[];  
ftitle=[];
layout=[];
getname=1;
if nargin~=0,
    count=0;
    for n=1:length(varargin),
        arg=varargin{n};
        if isnumeric(arg),      % note "empty" is also considered to be numeric!
            count=count+1;
            switch count
                case 1
                    figs=arg;
                case 2
                    monnum=arg;
                case 3
                    layout=arg;
            end  % switch count
        elseif ischar(arg),
            ftitle=arg;
            getname=0;
        end  % if ~isempty
    end  % for
end  % if nargin
if isempty(figs),       figs=0;     end
if isempty(ftitle),     ftitle='';  end
if isempty(monnum),     monnum=1;   end
if isempty(layout)||numel(layout)==2,     
    aspect=def_aspect;
elseif numel(layout)==1,
    aspect=layout;
    layout=[];
else
    error ('  Layout cannot have more than 2 elements!')
end

% alternative methods to find all of the figures.
% Second method should be more foolproof.
% allhands=get(0,'Children');
allhands=findobj('Type','figure');
% Note that figures without visible handles will not be tiled.
if figs==0,
    figs=sort(allhands);
else
    [tmp,indx]=intersect(figs,allhands);    %#ok  only tile figures that do exist
    figs=figs(sort(indx));                  % this keeps the order of the figures
end
numfigs=numel(figs);
% Check WindowStyle property on figures
m=0;
for n=1:numfigs,
    m=m+1;
    winstyle=get(figs(m),'WindowStyle');
    if strcmpi(winstyle,'modal'),           % Cannot maximize this figure.
        figs(m)=[];
        m=m-1;
    elseif strcmpi(winstyle,'docked'),      % Docked figures need to be undocked.
        set(figs(m),'WindowStyle','normal');
        drawnow
    end
end
numfigs=numel(figs);

% Get screen dimensions.
scnsize=getmondim(monnum);
if isempty(scnsize),
    error ('  Monitor %g does not exist',monnum)
end
% ----------------------- TASKBAR PLACEMENT --------------------
% adjust border for taskbar, edit appropriate line for position of taskbar
if monnum==1,   
    bottomborder=bottomborder+taskbarborder;
end
% ----------------------- TASKBAR PLACEMENT --------------------
scnwidth=scnsize(3)-leftborder-rightborder;
scnheight=scnsize(4)-topborder-bottomborder;

% Try to determine the best layout for the number of figures.
% Calculate the number of figure columns for different number of rows
% based upon the screen size to maintain square figures
numfigcols=zeros(1,maxnumrows);
for n=2:maxnumrows,
    barheight=((menbarlimit-n)>=0)*menbarheight+((toolbarlimit-n)>=0)*toolbarheight;
    numfigcols(n)=fix(scnwidth/((scnheight/n - barheight-titleheight)*aspect));
% Note that the figure size is created with a minimum aspect ratio. 
end
% For one row of figures use the same size figure as for two rows.
numfigcols(1)=numfigcols(2);
maxnumfigs=(1:maxnumrows).*numfigcols;

% Calculate offsets for multiple monitors.
offx=scnsize(1)+leftborder-1;
offy=scnsize(2)+bottomborder-1;

% Determine layout from numfigs
if isempty(layout),
    % Determine a layout (figrows,figcols) for numfigs figures.
    figrows=1;
    while numfigs>maxnumfigs(figrows);
        figrows=figrows+1;
        if figrows>maxnumrows,
            error ('  Too many figures are requested! Maximum is %3.0f',maxnumfigs(maxnumrows))
        end    
    end
    figcols=numfigcols(figrows);
else
    figrows=layout(1);
    figcols=layout(2);
    if figrows>maxnumrows,
        error ('  Too many figure rows! Maximum is %3.0f',maxnumrows)
    end 
end     % isempty(layout)
    
% For a large number of figures, the menu and tool bars are turned off to
% conserve space.
if figrows > toolbarlimit,
    tbar='none';
else
    tbar='figure';
end
if figrows > menbarlimit,
    menbar='none';
else
    menbar='figure';
end

figwidth=scnwidth/figcols;
if figwidth < minfigwidth
    figcols=fix(scnwidth/minfigwidth);
    figrows=ceil(numfigs/figcols);
    if figrows>maxnumrows,
        error ('  Too many figure rows! Maximum is %3.0f',maxnumrows)
    end 
    figwidth=scnwidth/figcols;
end

% For a single row of figures calculate height based upon aspect ratio.
if figrows==1,
    figheight=figwidth/aspect + menbarheight + toolbarheight + titleheight;
    figrows=scnheight/figheight;    % It's ok if figrows is not integer.
else
    figheight=scnheight/figrows;
end

% Now move the individual figures.
% Note that the OuterPosition property is preferable to the Position property 
% for setting the figure positions.
for n=numfigs:-1:1,
    r=fix((n-1)/figcols)+1;     % calculate row number
    c=mod(n-1,figcols)+1;       % calculate column number
    pos=[offx+(c-1)*figwidth+1,offy+(figrows-r)*figheight+1,figwidth,figheight];
    if getname,
        ftitle = get(figs(n),'Name');
        % remove #xx if it exists
        if ~isempty(ftitle) && ftitle(1)=='#',
            [tmp,ftitle]=strtok(ftitle);    %#ok
            ftitle=strtrim(ftitle);         
        end
    end
    if numfigs==1,
        figtitle=ftitle;
    else
        figtitle=['#',int2str(n),'  ',ftitle];
    end
     % ------------------- MODIFY FIGURE PROPERTIES -----------------
    % Move figure and modify properties as needed.
    set(figs(n),'Name',figtitle,...
        'Units','pixels', ...
        'OuterPosition',pos,...
        'NumberTitle','off',...
        'MenuBar',menbar,...
        'ToolBar',tbar);
    % ------------------- MODIFY FIGURE PROPERTIES -----------------
    figure(figs(n))             % bring figure to front.
end

if nargout==1,
    fighandle=figs;
end

Contact us at files@mathworks.com