Soru Matplotlib subplots için ortak xlabel / ylabel


Aşağıdaki arsa sahibim:

fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

ve şimdi bu arsa genel x ekseni etiketleri ve y ekseni etiketleri vermek istiyorum. "Ortak" ile demek istediğim, alt alanların tümünün altında büyük bir x ekseni etiketi ve sağdaki büyük bir y ekseni etiketi olması gerekir. Bunun için dokümantasyonda hiçbir şey bulamıyorum plt.subplotsve benim googla'larım, büyük bir şey yapmam gerektiğini önerdi plt.subplot(111) ile başlamak için - ama nasıl kullanarak benim 5 * 2 alt yazılarını koymak plt.subplots?


76
2018-04-22 15:25


Menşei


Sorunun güncellenmesiyle ve aşağıdaki cevaplarda kalan yorumlar bunun bir kopyasıdır. stackoverflow.com/questions/6963035/... - Hooked
Değil, benim soru plt.subplots () için olduğu ve add_subplot kullanır bağlantı sorduğundan beri - Ben önlemek istiyorum hangi add_subplot için geçiş yapmazsanız, bu yöntemi kullanamazsınız. ben could Bağlantınızda alternatif bir çözüm olarak verilen plt.text çözümünü kullanın, ancak bu en zarif çözüm değildir. - jolindbe
Anlayabildiğim kadarıyla, plt.subplots, mevcut bir eksen ortamında bir alt küme oluşturamaz, ancak her zaman yeni bir rakam oluşturur. Sağ? - jolindbe
En şık bir çözüm burada bulunabilir: stackoverflow.com/questions/6963035/... - Mr.H
Bağlantınız, 4 yıldan fazla bir süre önce Hooked kullanıcısı tarafından sağlandı (yalnızca birkaç yorum sizin üzerindeydi). Daha önce söylediğim gibi, bu çözüm add_subplot ve plt.subplots () ile ilgili değil. - jolindbe


Cevaplar:


Bu gerçekten istediğin gibi görünüyor. Aynı yaklaşımı uygular bu cevap özel durumunuza

import matplotlib.pyplot as plt

fig, ax = plt.subplots(nrows=3, ncols=3, sharex=True, sharey=True, figsize=(6, 6))

fig.text(0.5, 0.04, 'common X', ha='center')
fig.text(0.04, 0.5, 'common Y', va='center', rotation='vertical')

Multiple plots with common axes label


122
2017-11-12 16:56



parlak, sadece parlak! - ThePredator
x-etiketinin x-koordinatı için 0.5'in, etiketi merkez alt-çiziminin merkezine koymadığını unutmayın. Yticklabels'i hesaba katmak için biraz daha büyük gitmeniz gerekiyor. - dbliss
Bir bak bakalım bu cevap kullanmayan bir yöntem için plt.text. Altpiplerinizi yaratırsınız, ancak bir bit grafiği ekleyin, görünmez yapın ve x ve y etiketini etiketleyin. - kungfujam
Teşekkürler, genel olarak çalıştı. Kullanırken kırmaya herhangi bir çözüm tight_layout? - serv-inc
@ serv-inc ile tight_layout yerine 0.04 ile 0 çalışıyor gibi görünüyor. - divenex


olmadan sharex=True, sharey=True alırsın:

enter image description here

Onunla daha güzel almalısınız:

fig, axes2d = plt.subplots(nrows=3, ncols=3,
                           sharex=True, sharey=True,
                           figsize=(6,6))

for i, row in enumerate(axes2d):
    for j, cell in enumerate(row):
        cell.imshow(np.random.rand(32,32))

plt.tight_layout()

enter image description here

Ancak, ek etiketler eklemek isterseniz, bunları yalnızca kenar grafiğe eklemelisiniz:

fig, axes2d = plt.subplots(nrows=3, ncols=3,
                           sharex=True, sharey=True,
                           figsize=(6,6))

for i, row in enumerate(axes2d):
    for j, cell in enumerate(row):
        cell.imshow(np.random.rand(32,32))
        if i == len(axes2d) - 1:
            cell.set_xlabel("noise column: {0:d}".format(j + 1))
        if j == 0:
            cell.set_ylabel("noise row: {0:d}".format(i + 1))

plt.tight_layout()

enter image description here

Her arsa için etiket eklenmesi onu bozardı (tekrarlanan etiketlerin otomatik olarak algılanması için bir yol olabilir, ancak bir tanesinin farkında değilim).


27
2018-05-13 18:21



Örneğin, parsel sayısının bilinmemesi (örneğin, herhangi bir alt sayı için çalışan bir genelleştirme çizim fonksiyonuna sahip olmanız) durumunda bu durum daha da zorlaşır. - naught101


Komutundan beri:

fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

Kullandığınız figürden oluşan bir tuple ve eksen örneklerinin bir listesini döndürür, zaten bir şey yapmak için yeterlidir (değişmiş olduğum zihin) fig,axiçin fig,axes):

fig,axes = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

for ax in axes:
    ax.set_xlabel('Common x-label')
    ax.set_ylabel('Common y-label')

Belirli bir alt plotta bazı ayrıntıları değiştirmek isterseniz, axes[i] nerede i alt yazılar üzerinde yineleyin.

Bir dahil etmek de çok yararlı olabilir

fig.tight_layout()

Dosyanın sonunda, önce plt.show()üst üste binen etiketlerden kaçınmak için.


14
2018-04-22 17:49



Üzgünüm yukarıda biraz belirsizdim. "Ortak" ile, tüm parsellerin altında tek bir x etiketi ve parsellerin solundaki tek bir y etiketini kastediyorum, bu sorunu yansıtacak şekilde güncelledim. - jolindbe
@JohanLindberg: Yorumlarınızı burada ve yukarıda: Gerçekten de plt.subplots() yeni bir rakam örneği oluşturacak. Bu komutla devam etmek istiyorsanız, kolayca ekleyebilirsiniz. big_ax = fig.add_subplot(111)Çünkü zaten bir figürün var ve başka bir eksen ekleyebilirsin. Bundan sonra, manipüle edebilirsiniz big_ax Bağlantılı olarak bağlantıda gösterildiği şekilde. - Marius
Önerileriniz için teşekkürler, ama eğer bunu yaparsam, big_ax'ı plt.subplots () 'dan sonra eklemeliyim ve bu alt alanı diğer her şeyin üstüne getiriyorum - bunu şeffaf hale getirebilir veya bir şekilde arkaya gönderebilir miyim? Tüm renkleri Hooked bağlantısında olduğu gibi ayarlamasam bile, tüm alt yazılarımı kapsayan beyaz bir kutu. - jolindbe
@JohanLindberg, haklısın, ben kontrol etmedim. Ancak, büyük eksenin arka plan rengini kolayca ayarlayabilirsiniz. none yaparak: big_ax.set_axis_bgcolor('none') Etiket rengini de yapmalısınız. none (Hooked ile bağlantılı örneğe karşılık olarak): big_ax.tick_params(labelcolor='none', top='off', bottom='off', left='off', right='off') - Marius
Bir hata alıyorum: AttributeError: 'numpy.ndarray' object has no attribute 'set_xlabel' ifadede ax.set_xlabel('Common x-label'). Anlayabilir misin? - hengxin


Grafikler çizerken benzer bir soruna rastladım. Grafikler iki bölümden (üst ve alt) oluşuyordu. Y-etiketinin her iki parça üzerinde ortalanması gerekiyordu.

Dış figürdeki (fig.text () gibi) konumun bilinmesine dayanan bir çözüm kullanmak istemedim, bu yüzden set_ylabel () işlevinin y konumunu değiştirdim. Genellikle 0.5, eklendiği arsa ortasıdır. Kodumdaki parçalar (hspace) arasındaki dolgu sıfır olduğundan, iki parçanın ortasını üst kısma göre hesaplayabilirdim.

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

# Create outer and inner grid
outerGrid = gridspec.GridSpec(2, 3, width_ratios=[1,1,1], height_ratios=[1,1])
somePlot = gridspec.GridSpecFromSubplotSpec(2, 1,
               subplot_spec=outerGrid[3], height_ratios=[1,3], hspace = 0)

# Add two partial plots
partA = plt.subplot(somePlot[0])
partB = plt.subplot(somePlot[1])

# No x-ticks for the upper plot
plt.setp(partA.get_xticklabels(), visible=False)

# The center is (height(top)-height(bottom))/(2*height(top))
# Simplified to 0.5 - height(bottom)/(2*height(top))
mid = 0.5-somePlot.get_height_ratios()[1]/(2.*somePlot.get_height_ratios()[0])
# Place the y-label
partA.set_ylabel('shared label', y = mid)

plt.show()

resim

Downsides:

  • Çizgiye yatay mesafe üst kısma dayanır, alt keneler de etikete uzanabilir.

  • Formül, parçalar arasında boşluk bırakmaz.

  • Üst parçanın yüksekliği 0 olduğunda bir istisna atar.

Muhtemelen rakamlar arasında dolgu yapmak için genel bir çözüm var.


2
2017-07-27 16:35



Hey, cevabınızın damarında bunu yapmanın bir yolunu buldum, ancak bu sorunların bazılarını çözebilir; görmek stackoverflow.com/a/44020303/4970632 (altında) - Luke Davis


Daha sağlam bir yöntem keşfettim:

Eğer biliyorsan bottom ve top içine giren kwargs GridSpec başlatma veya eksenlerin kenarlarını başka bir şekilde bilirsiniz. Figure koordinatlarylabel konumunu da belirtebilirsiniz. Figure Bazı fantezi "dönüşüm" büyü ile koordinatları. Örneğin:

import matplotlib.transforms as mtransforms
bottom, top = .1, .9
f, a = plt.subplots(nrows=2, ncols=1, bottom=bottom, top=top)
avepos = (bottom+top)/2
a[0].yaxis.label.set_transform(mtransforms.blended_transform_factory(
       mtransforms.IdentityTransform(), f.transFigure # specify x, y transform
       )) # changed from default blend (IdentityTransform(), a[0].transAxes)
a[0].yaxis.label.set_position((0, avepos))
a[0].set_ylabel('Hello, world!')

... ve etiketini görmelisin hala sol-sağı uygun şekilde ayarlar normalde olduğu gibi, kene etiketleriyle çakışmaya devam etmek için - ama şimdi her zaman olacak şekilde ayarlanacak tam olarak İstenen alt noktalar.

Dahası, hatta kullanmıyorsanız set_position, ylabel varsayılan olarak görünecek tam olarak rakamın yarısı kadar. Sanırım bunun nedeni, etiket nihayet çizildiğinde, matplotlib için 0,5 kullanır yAltta yatan koordinat dönüşümünün değişip değişmediğini kontrol etmeden koordinasyon.


1
2018-05-17 09:07





Alt etiketin alt sol köşesinde görünmez etiketler oluşturarak, ortak etiketler için yer ayırırsanız daha iyi görünecektir. RcParams'dan font boyutuna geçmek de iyidir. Bu şekilde, ortak etiketler rc kurulumunuzla boyutu değiştirecek ve eksenler ortak etiketler için alan bırakacak şekilde ayarlanacaktır.

fig_size = [8, 6]
fig, ax = plt.subplots(5, 2, sharex=True, sharey=True, figsize=fig_size)
# Reserve space for axis labels
ax[-1, 0].set_xlabel('.', color=(0, 0, 0, 0))
ax[-1, 0].set_ylabel('.', color=(0, 0, 0, 0))
# Make common axis labels
fig.text(0.5, 0.04, 'common X', va='center', ha='center', fontsize=rcParams['axes.labelsize'])
fig.text(0.04, 0.5, 'common Y', va='center', ha='center', rotation='vertical', fontsize=rcParams['axes.labelsize'])

enter image description here enter image description here


0
2018-05-30 17:57