Matplotlib'in alt grafiklerinde satır ve sütun başlıkları


89

Bir döngüde oluşturulan alt noktalar ızgarasına bir satır ve sütun başlığı eklemek için en iyi uygulama nedir matplotlib? Bir çift düşünebilirim, ama pek de düzgün değil:

  1. Sütunlar için, döngünüze bir sayaç ile set_title()yalnızca ilk satır için kullanabilirsiniz. Satırlar için bu işe yaramaz. Arsaların textdışını çizmeniz gerekir .
  2. Üstte fazladan bir alt grafik satırı ve solda fazladan bir alt grafik sütunu eklersiniz ve bu alt grafiğin ortasına metin çizersiniz.

Daha iyi bir alternatif önerebilir misin?

görüntü açıklamasını buraya girin

Yanıtlar:


116

Bunu yapmanın birkaç yolu var. Kolay yol, arsanın y etiketlerini ve başlıklarını kullanmak ve ardından fig.tight_layout()etiketlere yer açmak için kullanmaktır . Alternatif olarak, ile doğru konuma ek metin yerleştirebilir annotateve ardından yarı manuel olarak yer açabilirsiniz .


Eksenlerinizde y etiketleri yoksa, eksenlerin ilk satırı ve sütununun başlığını ve y etiketini kullanmak kolaydır.

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()

görüntü açıklamasını buraya girin


Y etiketleriniz varsa veya biraz daha fazla esneklik istiyorsanız annotate, etiketleri yerleştirmek için kullanabilirsiniz . Bu daha karmaşıktır, ancak satır ve sütun etiketlerine ek olarak tek tek arsa başlıklarına, yazı başlıklarına vb. Sahip olmanıza izin verir.

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()

görüntü açıklamasını buraya girin


8
Yöntem is_first_col(), is_last_col(), is_first_row()ve is_last_row()de bu bağlamda uygun olabilir.
gerrit

1
Ayrıca not olarak, matplotlib'in döndürme seçeneği vardır, bu nedenle etiketinizi 90 derece döndürmek istiyorsanız, argümanı eklemeniz rotation = 90
yeterlidir

2

Yukarıdaki cevap işe yarıyor. Ancak cevabın ikinci versiyonunda şunlara sahip değilsiniz:

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')

onun yerine:

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')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.