简体   繁体   中英

Octave hide part of subplot when position property is modified

I'm using Octave to make a group of subplots, but the first titles are overlapping.

clf;
x = 0:1;
for n = 1:13
  sPlot = subplot (5,3,n, "align");

  #subplotPos = get(sPlot, 'position');
  #subplotPos .*= [1 1.2 1 1];
  #set(sPlot, 'position', subplotPos);

  plot (x, x);
  xlabel (sprintf ("xlabel (2,2,%d)", n));
  ylabel (sprintf ("ylabel (2,2,%d)", n));
  title (sprintf ("title (2,2,%d)", n));
endfor

To skip this issue I modified the position property of the subplot, uncommenting the above code, but then I get part of the first row hidden.

How can I make a subplot without getting overlapped plots or hide part of the plots?

Technical details:

  • Octave 5.2.0
  • Debian 10.7
  • graphics_toolkit(): qt, gnuplot, fltk

重叠 隐藏

The line

subplotPos .*= [1 1.2 1 1];

probably doesn't do what you wanted it to do. In terms of normalised units (which is the default), positioning implies [ x-origin, y-origin, x-width, y-width ] for that axes object, with respect to the figure's full size.

Therefore you just instructed octave to shift all your resulting axes objects up by 20%, but without changing their size. Which naturally results in your top axes objects falling 'outside' of the figure's available space.

Instead what you probably want is to 'shrink' your axes, so that they still fit in the space available for the figure, while making some room for the titles etc (plus optional re-centering of the subplot within its allocated space). So presumably something more along the lines of:

  subplotPos =   subplotPos    .* [1 1 1 0.5] ...   % shrink step
               + subplotPos(4) .* [0, 0.25, 0, 0]   % recenter step

PS. By the way, if you desire fine-positioning like this, I would actually prefer creating my own axes objects, positioned exactly where I want them, rather than use subplot. I would also define the figure size first, so that you can have a reproducible plot each time. One big difference between using subplot with positioning, and simple axes with positioning, is that axes may overlap if needed, whereas subplots do not (the overlapping object immediately deletes the one it overlaps).

Also, from a design point of view, if you're planning on using this in an article or report etc, I would actually skip titles here completely, since they break the flow of the subplot grid, and simply use 'labels' instead, eg "a", "b", "c", etc, appearing at the bottom left of each plot, and then refer to these in the figure caption instead. You can achieve this eg by creating a text object using the plot's coordinates. If you want to avoid having to find the 'right coordinates' to put the text each time, you can write a function that creates a new axes object in a predictable location, and then uses the text function to place a label in its centre.


PS2. I probably should have mentioned this first, but, the other obvious solution is to simply make your figure larger (which you can do programmatically if you don't want to manually resize the window each time), since this increases the space between plots without changing the font-size, so this may resolve your 'xlabel vs title overlap' problem by itself.

UPDATE : Here is an example manipulating the figure size, instead of the plot objects.

% Get monitor resolution from the root graphical object, 'groot'. (typically groot == 0)
  ScreenSize   = get( groot, 'screensize' );
  ScreenWidth  = ScreenSize(3);
  ScreenHeight = ScreenSize(4);


% Define desired figure size, and recenter on screen
  FigureWidth     = 1650;
  FigureHeight    = 1250;
  Figure_X_Origin = floor( (ScreenWidth  - FigureWidth)  / 2 );
  Figure_Y_Origin = floor( (ScreenHeight - FigureHeight) / 2 );

  FigPosition = [ Figure_X_Origin, Figure_Y_Origin, FigureWidth, FigureHeight ];


% Create a figure with the specified position / size.
  Fig = figure();
  set( Fig, 'position', FigPosition );   % or simply Fig = figure( 'position', FigPosition )


% Now same basic code as before; figure is large enough therefore 'resizing' corrections are not necessary.
  clf;
  x = 0:1;
  for n = 1:13
    sPlot = subplot (5,3,n, "align");
    plot (x, x);
    xlabel (sprintf ("xlabel (2,2,%d)", n), 'fontsize', 12);
    ylabel (sprintf ("ylabel (2,2,%d)", n), 'fontsize', 12);
    title  (sprintf ("title (2,2,%d)" , n), 'fontsize', 16);
  endfor

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM