Заголовки строк и столбцов в подзаголовках matplotlib
какова наилучшая практика добавления строки и заголовка столбца в сетку подзаголовков, генерируемых в цикле в matplotlib
? Я могу придумать пару, но не особенно аккуратных:
- для столбцов со счетчиком вашего цикла вы можете использовать
set_title()
только для первой строки. Для строк это не работает. Вам придется рисоватьtext
вне участков. - вы добавляете дополнительную строку подзаголовков сверху и дополнительный столбец подзаголовков слева и рисуете текст в середине сюжета.
можете ли вы предложить лучшую альтернативу?
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()
если у вас есть Г-метки, или если вы предпочитаете немного больше гибкости, вы можете использовать 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()
вышеуказанный ответ работает. Просто не то, что во второй версии ответа, у вас есть:
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')