Stop overlapping figures in Octave

Viewed 72

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

1 Answers

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
Related