在倾斜网格中排列matplotlib子图

5
使用matplotlib,我想在一个网格上显示多个子图,每行的列数不同,每个子图大致相同大小,并且子图排列使它们更或多或少地居中,就像这样:

Grid of axes in pattern (2, 3, 2)

使用gridspec创建具有2、3、2模式的网格相当简单,但问题在于gridspec会将它们对齐到网格上,因此具有2个图的行中的图形更宽:

Grid aligned with gridspec

这是生成它的代码:
from matplotlib import gridspec
from matplotlib import pyplot as plt

fig = plt.figure()

arrangement = (2, 3, 2)
nrows = len(arrangement)

gs = gridspec.GridSpec(nrows, 1)
ax_specs = []
for r, ncols in enumerate(arrangement):
    gs_row = gridspec.GridSpecFromSubplotSpec(1, ncols, subplot_spec=gs[r])
    for col in range(ncols):
        ax = plt.Subplot(fig, gs_row[col])
        fig.add_subplot(ax)

for i, ax in enumerate(fig.axes):
    ax.text(0.5, 0.5, "Axis: {}".format(i), fontweight='bold',
            va="center", ha="center")
    ax.tick_params(axis='both', bottom='off', top='off', left='off',
                   right='off', labelbottom='off', labelleft='off')

plt.tight_layout()

我知道可以设置一堆子图并通过计算几何形状来调整它们的排列,但我认为这可能会变得有点复杂,所以我希望可能有更简单的方法可用。
需要注意的是,即使我在示例中使用了(2, 3, 2)的排列,我也想为任意集合执行此操作,而不仅仅是这一个。
1个回答

8

这个想法通常是找到子图之间的最小公共分母,即所需网格可以组成的最大子图,并将所有子图跨越多个这些子图位置,从而实现所需的布局。

enter image description here

在这里,您有3行6列,每个子图跨越1行2列,只是第一行中的子图跨越subplot位置1/2和3/4,而第二行中的子图跨越位置0/1、2/3和4/5。

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

gs = gridspec.GridSpec(3, 6)
ax1a = plt.subplot(gs[0, 1:3])
ax1b = plt.subplot(gs[0, 3:5])
ax2a = plt.subplot(gs[1, :2])
ax2b = plt.subplot(gs[1, 2:4])
ax2c = plt.subplot(gs[1, 4:])
ax3a = plt.subplot(gs[2, 1:3])
ax3b = plt.subplot(gs[2, 3:5])


for i, ax in enumerate(plt.gcf().axes):
    ax.text(0.5, 0.5, "Axis: {}".format(i), fontweight='bold',
            va="center", ha="center")
    ax.tick_params(axis='both', bottom='off', top='off', left='off',
                   right='off', labelbottom='off', labelleft='off')

plt.tight_layout()

plt.show()

enter image description here


嗯,是的,我考虑过这个。让我看看通用化会有多容易。 - Paul
实际上,如果它们始终是长度为n或n-1,则只需要进行n * 2网格即可,因此非常简单。 - Paul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接