matplotlib 子图中的行标题和列标题

新手上路,请多包涵

将行和列标题添加到 matplotlib 中循环生成的子图网格的最佳做法是什么?我能想到一对,但不是特别整洁:

  1. 对于列,您可以使用循环计数器 set_title() 仅用于第一行。对于行,这不起作用。您必须在地块之外绘制 text
  2. 您在顶部添加一行额外的子图,在左侧添加一列额外的子图,并在该子图的中间绘制文本。

你能建议一个更好的选择吗?

在此处输入图像描述

原文由 gozzilli 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

有几种方法可以做到这一点。简单的方法是利用绘图的 y 标签和标题,然后使用 fig.tight_layout() 为标签腾出空间。或者,您可以使用 annotate 将附加文本放置在正确的位置,然后半手动地为其腾出空间。


如果您的轴上没有 y 标签,则很容易利用轴的第一行和第一列的标题和 y 标签。

 import matplotlib.pyplot as plt

cols = ['Column {}'.format(col) for col in range(1, 4)]
rows = ['Row {}'.format(row) for row in ['A', 'B', 'C', 'D']]

fig, axes = plt.subplots(nrows=4, ncols=3, figsize=(12, 8))

for ax, col in zip(axes[0], cols):
    ax.set_title(col)

for ax, row in zip(axes[:,0], rows):
    ax.set_ylabel(row, rotation=0, size='large')

fig.tight_layout()
plt.show()

在此处输入图像描述


如果您确实有 y 标签,或者如果您希望更灵活一些,则可以使用 annotate 来放置标签。这更复杂,但除了行和列标签之外,您还可以拥有单独的绘图标题、ylabels 等。

 import matplotlib.pyplot as plt
from matplotlib.transforms import offset_copy

cols = ['Column {}'.format(col) for col in range(1, 4)]
rows = ['Row {}'.format(row) for row in ['A', 'B', 'C', 'D']]

fig, axes = plt.subplots(nrows=4, ncols=3, figsize=(12, 8))
plt.setp(axes.flat, xlabel='X-label', ylabel='Y-label')

pad = 5 # in points

for ax, col in zip(axes[0], cols):
    ax.annotate(col, xy=(0.5, 1), xytext=(0, pad),
                xycoords='axes fraction', textcoords='offset points',
                size='large', ha='center', va='baseline')

for ax, row in zip(axes[:,0], rows):
    ax.annotate(row, xy=(0, 0.5), xytext=(-ax.yaxis.labelpad - pad, 0),
                xycoords=ax.yaxis.label, textcoords='offset points',
                size='large', ha='right', va='center')

fig.tight_layout()
# tight_layout doesn't take these labels into account. We'll need
# to make some room. These numbers are are manually tweaked.
# You could automatically calculate them, but it's a pain.
fig.subplots_adjust(left=0.15, top=0.95)

plt.show()

在此处输入图像描述

原文由 Joe Kington 发布,翻译遵循 CC BY-SA 4.0 许可协议

以上答案有效。只是在答案的第二个版本中,你有:

 for ax, row in zip(axes[:,0], rows):
    ax.annotate(col, xy=(0, 0.5), xytext=(-ax.yaxis.labelpad-pad,0),
                xycoords=ax.yaxis.label, textcoords='offset points',
                size='large', ha='right', va='center')

代替:

 for ax, row in zip(axes[:,0], rows):
    ax.annotate(row,xy=(0, 0.5), xytext=(-ax.yaxis.labelpad-pad,0),
                xycoords=ax.yaxis.label, textcoords='offset points',
                size='large', ha='right', va='center')

原文由 Alan Shteyman 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏