简体   繁体   English

子图:tight_layout 改变图形大小

[英]Subplots: tight_layout changes figure size

Changing the vertical distance between two subplot using tight_layout(h_pad=-1) changes the total figuresize.使用 tiny_layout(h_pad=-1) 更改两个子图之间的垂直距离会更改总图形大小。 How can I define the figuresize using tight_layout?如何使用 tiny_layout 定义图形大小?

Here is the code:这是代码:

#define figure
pl.figure(figsize=(10, 6.25))

ax1=subplot(211)
img=pl.imshow(np.random.random((10,50)), interpolation='none')
ax1.set_xticklabels(()) #hides the tickslabels of the first plot

subplot(212)
x=linspace(0,50)
pl.plot(x,x,'k-')
xlim( ax1.get_xlim() ) #same x-axis for both plots

And here is the results:结果如下:

If I write如果我写

pl.tight_layout(h_pad=-2)

in the last line, then I get this:在最后一行,然后我得到这个:

在此处输入图片说明

As you can see, the figure is bigger...正如你所看到的,这个数字更大......

You can use a GridSpec object to control precisely width and height ratios, as answered on this thread and documented here .您可以使用 GridSpec 对象来精确控制宽度和高度比率,如在此线程上回答并记录在此处

Experimenting with your code, I could produce something like what you want, by using a height_ratio that assigns twice the space to the upper subplot, and increasing the h_pad parameter to the tight_layout call.试验你的代码,我可以产生你想要的东西,通过使用height_ratio将两倍的空间分配给上部子图,并将h_pad参数增加到tight_layout调用。 This does not sound completely right, but maybe you can adjust this further ...这听起来并不完全正确,但也许您可以进一步调整...

import numpy as np
from matplotlib.pyplot import *
import matplotlib.pyplot as pl
import matplotlib.gridspec as gridspec

#define figure
fig = pl.figure(figsize=(10, 6.25))

gs = gridspec.GridSpec(2, 1, height_ratios=[2,1])

ax1=subplot(gs[0])
img=pl.imshow(np.random.random((10,50)), interpolation='none')
ax1.set_xticklabels(()) #hides the tickslabels of the first plot

ax2=subplot(gs[1])
x=np.linspace(0,50)
ax2.plot(x,x,'k-')
xlim( ax1.get_xlim() ) #same x-axis for both plots
fig.tight_layout(h_pad=-5)
show()

There were other issues, like correcting the imports, adding numpy, and plotting to ax2 instead of directly with pl .还有其他问题,例如更正导入、添加 numpy 以及绘制到ax2而不是直接使用pl The output I see is this:我看到的输出是这样的:

修正图

This case is peculiar because of the fact that the default aspect ratios of images and plots are not the same.这种情况很特殊,因为图像和绘图的默认纵横比不同。 So it is worth noting for people looking to remove the spaces in a grid of subplots consisting of images only or of plots only that you may find an appropriate solution among the answers to this question (and those linked to it): How to remove the space between subplots in matplotlib.pyplot?因此,对于希望删除仅由图像或仅由图组成的子图网格中的空格的人来说,值得注意的是,您可能会在此问题的答案(以及与之相关的答案中找到合适的解决方案): 如何删除matplotlib.pyplot 中子图之间的空间? . .

The aspect ratios of the subplots in this particular example are as follows:此特定示例中子图的纵横比如下:

# Default aspect ratio of images:
ax1.get_aspect()
# 1.0

# Which is as it is expected based on the default settings in rcParams file:
matplotlib.rcParams['image.aspect']
# 'equal'
# Default aspect ratio of plots:
ax2.get_aspect()
# 'auto'

The size of ax1 and the space beneath it are adjusted automatically based on the number of pixels along the x-axis (ie width) so as to preserve the 'equal' aspect ratio while fitting both subplots within the figure. ax1的大小及其下方的空间根据沿 x 轴(即宽度)的像素数自动调整,以便在拟合图中的两个子图时保持“相等”的纵横比。 As you mentioned, using fig.tight_layout(h_pad=xxx) or the similar fig.set_constrained_layout_pads(hspace=xxx) is not a good option as this makes the figure larger.正如您所提到的,使用fig.tight_layout(h_pad=xxx)或类似的fig.set_constrained_layout_pads(hspace=xxx)不是一个好的选择,因为这会使图形更大。

To remove the gap while preserving the original figure size, you can use fig.subplots_adjust(hspace=xxx) or the equivalent plt.subplots(gridspec_kw=dict(hspace=xxx)) , as shown in the following example:要在保留原始图形大小的同时消除间隙,您可以使用fig.subplots_adjust(hspace=xxx)或等效的plt.subplots(gridspec_kw=dict(hspace=xxx)) ,如下例所示:

import numpy as np                 # v 1.19.2
import matplotlib.pyplot as plt    # v 3.3.2
np.random.seed(1)

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6.25),
                               gridspec_kw=dict(hspace=-0.206))

# For those not using plt.subplots, you can use this instead:
# fig.subplots_adjust(hspace=-0.206)

size = 50
ax1.imshow(np.random.random((10, size)))
ax1.xaxis.set_visible(False)

# Create plot of a line that is aligned with the image above
x = np.arange(0, size)
ax2.plot(x, x, 'k-')
ax2.set_xlim(ax1.get_xlim())

plt.show()

no_hspace

I am not aware of any way to define the appropriate hspace automatically so that the gap can be removed for any image width.我不知道有什么方法可以自动定义适当的hspace以便可以删除任何图像宽度的间隙。 As stated in the docstring for fig.subplots_adjust() , it corresponds to the height of the padding between subplots, as a fraction of the average axes height .fig.subplots_adjust()的文档字符串所述,它对应于子图之间填充高度,作为平均轴高度的一部分 So I attempted to compute hspace by dividing the gap between the subplots by the average height of both subplots like this:因此,我尝试通过将子图之间的间隙除以两个子图的平均高度来计算hspace ,如下所示:

# Extract axes positions in figure coordinates
ax1_x0, ax1_y0, ax1_x1, ax1_y1 = np.ravel(ax1.get_position())
ax2_x0, ax2_y0, ax2_x1, ax2_y1 = np.ravel(ax2.get_position())

# Compute negative hspace to close the vertical gap between subplots
ax1_h = ax1_y1-ax1_y0
ax2_h = ax2_y1-ax2_y0
avg_h = (ax1_h+ax2_h)/2
gap = ax1_y0-ax2_y1
hspace=-(gap/avg_h) # this divided by 2 also does not work

fig.subplots_adjust(hspace=hspace)

Unfortunately, this does not work.不幸的是,这不起作用。 Maybe someone else has a solution for this.也许其他人对此有解决方案。

It is also worth mentioning that I tried removing the gap between subplots by editing the y positions like in this example:还值得一提的是,我尝试通过编辑 y 位置来消除子图之间的间隙,如本例所示:

# Extract axes positions in figure coordinates
ax1_x0, ax1_y0, ax1_x1, ax1_y1 = np.ravel(ax1.get_position())
ax2_x0, ax2_y0, ax2_x1, ax2_y1 = np.ravel(ax2.get_position())

# Set new y positions: shift ax1 down over gap
gap = ax1_y0-ax2_y1
ax1.set_position([ax1_x0, ax1_y0-gap, ax1_x1, ax1_y1-gap])
ax2.set_position([ax2_x0, ax2_y0, ax2_x1, ax2_y1])

Unfortunately, this (and variations of this) produces seemingly unpredictable results, including a figure resizing similar to when using fig.tight_layout() .不幸的是,这(及其变体)产生了看似不可预测的结果,包括与使用fig.tight_layout()时类似的图形大小调整。 Maybe someone else has an explanation for what is happening here behind the scenes.也许其他人对幕后发生的事情有一个解释。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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