将行和列标题添加到matplotlib
中循环中生成的子图网格的最佳做法是什么?我能想到一对,但不是特别整洁:
set_title()
作为第一行。对于行,这不起作用。您必须在地块之外绘制text
。你能建议一个更好的选择吗?
答案 0 :(得分:67)
有几种方法可以做到这一点。简单的方法是利用情节的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
放置标签。这更复杂,但除了行标签和列标签之外,您还可以使用单独的地图标题,标签等。
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()
答案 1 :(得分:1)
上述答案有效。只是不是在答案的第二个版本中,你有:
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')