当使用gridspecs时,我发现很难对齐不同的嵌套gridspecs,我经常将gridspecs用于大多数或所有子图都有固定纵横比的图(例如,为了显示图像)。
下面的图就是一个最小的示例,其中在嵌套子图中,两个正方形图像显示在4个较小图像旁边:
import matplotlib.pyplot as plt
import numpy as np
n_cols = 3
fig = plt.figure(1, figsize=(6, 6 / n_cols * 1.5))
gs = fig.add_gridspec(1, n_cols)
test_img = np.ones((64, 64, 3)) * np.linspace(0.3, 1, 64)[:, None] # simple, square test image
for col in range(n_cols - 1):
ax = fig.add_subplot(gs[col])
ax.imshow(test_img)
gs_sub = gs[-1].subgridspec(2, 2, wspace=0.02, hspace=0.02)
for i in range(4):
ax = fig.add_subplot(gs_sub[i])
ax.imshow(test_img)
# use tight layout to remove excess white space
gs.tight_layout(fig, rect=[0, 0, 1, 1], pad=0.001)
gs.update(wspace=0.025, hspace=0.0)
这将生成以下图:
正如你所看到的,较小的图像在垂直方向上要比较大的图像占用更多的空间。我猜嵌套gridspec会尝试使用所有可用的空间,而不会被限制为匹配左边的两个较大的图像。另一方面,它可以很好地对齐具有灵活纵横比的图(例如线图),因为子图的纵横比会自动拉伸:
(don'不介意重叠的轴刻度,如果需要,很容易添加更多的空间)。
我也经常可以通过缩放绘图的高度甚至是调整高度/宽度比来使事情顺利进行。在上面的绘图中,可以通过删除应用于绘图高度的任意比例因子"1.5"来改善结果。然而,这不是一个好的解决方案,因为它经常需要大量的手动实验,并且很少是完美的(特别是对于更复杂的布局)。
是否有更好的方法来实现这一点?是否有一种方法来通知嵌套的gridspec所需的对齐方式?理想情况下,我希望控制嵌套的gridspec来匹配其他子图的高度,而不是耗尽所有可用的空间。
谢谢你的帮忙!
1条答案
按热度按时间i86rm4rw1#
在
matplotlib
图中显示图像的问题是图形通常受到过度约束。在您的示例中,您为图形设置了特定的纵横比,然后在子图之间指定了任意间距。与图相反,图像具有固定的纵横比,这会导致图形参数不一致,因此您尝试设置的某个属性最终会被违反。解决方法是确保设置的参数一致。由于图像的纵横比是固定的,您可以选择子图之间的间距或图形的全局纵横比,并相应地进行约束。
在下文中,我将假设图形本身的纵横比并不重要,因此我们将设置子图之间的间距,并推导出
figsize
应满足的约束。根据documentation,
wspace
和hspace
参数表示为平均轴宽/轴高的分数。因此,对于绘制大小为w
xh
的n_rows
x xn_cols
图像网格的图形,总宽度为W = n_cols * w + (n_cols-1) * w_space * w
同样,总高度为:
H = n_rows * h + (n_rows-1) * h_space * h
然后我们可以使用比率
W / H
作为主图形的纵横比。为了简单起见,我假设所有的图像都有相同的大小,我们可以推导出一个类似的任意宽/高比的公式,但思路是一样的。
为了让它在subgridspecs上工作,你只需要先对subgridspecs做这个,它会给予你它们在主图形中的大小,你可以用它来计算主图形的长宽比。
下面是对示例图稍作修改后的一个例子,我实现了一个
gridspec_aspect
函数,该函数计算给定任意宽/高比和w/hspace的(子)图形的实际纵横比。生成下图: