修改位置属性时,八度隐藏子图的一部分

问题描述

我正在使用 Octave 制作一组子图,但第一个标题重叠。

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,n));
  title (sprintf ("title (2,n));
endfor

为了跳过这个问题,我修改了子图的位置属性,取消了上面代码的注释,但随后我隐藏了第一行的一部分。

如何制作子图而不出现重叠图或隐藏部分图?

技术细节:

  • 八度音程 5.2.0
  • Debian 10.7
  • graphics_toolkit():qt、gnuplot、fltk

overlapping

hide

解决方法

线

subplotPos .*= [1 1.2 1 1];

可能没有做你想让它做的事情。就归一化单位而言(这是默认值),相对于图形的全尺寸,定位意味着该坐标区对象的 [ x-origin,y-origin,x-width,y-width ]

因此,您只是指示八度将所有结果轴对象向上移动 20%,但不改变它们的大小。这自然会导致您的顶轴对象落在图形可用空间的“外部”。

相反,您可能想要的是“缩小”您的轴,以便它们仍然适合图形可用的空间,同时为标题等留出一些空间(加上可选的在其分配的空间内重新居中子图)。所以大概是这样的:

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

附注。顺便说一下,如果你想要这样的精细定位,我实际上更喜欢创建我自己的轴对象,准确地定位在我想要的位置,而不是使用子图。我还将首先定义图形大小,以便您每次都能获得可重复的绘图。使用带定位的子图和带定位的简单轴之间的一大区别是,如果需要,轴可能会重叠,而子图不会(重叠的对象会立即删除它重叠的对象)。

此外,从设计的角度来看,如果您打算在文章或报告等中使用它,我实际上会在这里完全跳过标题,因为它们会破坏子图网格的流程,而只需使用“标签” ' 代替,例如“a”、“b”、“c”等,出现在每个图的左下角,然后在图标题中引用这些。您可以实现这一点,例如通过使用绘图的坐标创建文本对象。如果您想避免每次都必须找到“正确坐标”来放置文本,您可以编写一个函数,在可预测的位置创建一个新的轴对象,然后使用文本函数在其中心放置一个标签。


PS2。我可能应该首先提到这一点,但是,另一个明显的解决方案是简单地使您的图形更大(如果您不想每次都手动调整窗口大小,则可以通过编程方式进行),因为这会增加图之间的空间而不会更改字体大小,因此这可能会自行解决您的“xlabel 与标题重叠”问题。

更新:这是一个操作图形大小而不是绘图对象的示例。

% 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,12);
    title  (sprintf ("title (2,16);
  endfor