Search code examples
octavefigure

Stop overlapping figures in Octave


Is there an easy way to have multiple figures distributed evenly across a monitor without manual adjustment?

I've attempted to use the autoArrangeFigures Matlab community function with little luck. First I'm hit with various script errors and once addressed, it failed to stop the overlapping figures in a Linux (pop-os) environment.

enter image description here


Solution

  • Below is a function I've called tilefig which tiles figures overlapping only on the toolbars, i.e. maximising plot visibility. Tested in MATLAB but I've done some quick documentation checks on the few less common functions like allchild(0) and get(0,'screensize') and I think it should be Octave compatible.

    I've commented the code, but basically the logic is

    • Get handles to all open figure objects
    • Start from either a given position or the position of the current figure
    • Update the positions of subsequent figures in a loop, incrementing the column or row numbers according to the screen size and maximum row/column limits.

    Running tilefig with no inputs will tile the whole screen starting with the current figure in the top-left.

    To make the tiling neat, it also resizes all figures to be the same width/height.

    Example result for tilefig([],4) with 7 figures

    figures

    function tilefig( maxrows, maxcols, p )
        % Tile figures to max rows/cols in a grid, can be [] to just use all
        % screen space. Optional input 'p' for top-left tile position, will use
        % current figure if omitted.
        AllFig = allchild(0);          % Get all figures
        pScr = get(0, 'screensize');   % Get screen size
        if nargin < 1 || isempty( maxrows )
            maxrows = inf;
        end
        if nargin < 2 || isempty( maxcols )
            maxcols = inf;
        end
        if nargin < 3                  
            p = get( gcf, 'Position' );   
        end
        pNew = p;       % Current position
        nr = 1; nc = 1; % Row/col numbers
        for ii = 1:numel(AllFig)
            if sum(pNew([1,3])) > pScr(3) || nc > maxcols
                % Exceeded screen width or max num columns
                nc = 1;
                nr = nr + 1;
                pNew(1) = p(1);
                pNew(2) = pNew(2) - pNew(4);
            end
            if pNew(2) < 0 || nr > maxrows
                % Loop back to the first row if exceeds screen height / max row
                nr = 1;
                pNew(2) = p(2);
            end        
            set( AllFig(ii), 'Position', pNew );
            nc = nc + 1;
            pNew = pNew + [pNew(3), 0, 0, 0];
        end    
        % Reverse the overlap
        for ii = numel(AllFig):-1:1
            figure( AllFig(ii) );
        end
    end