Efsaneyi arsadan nasıl çıkarabilirim?


987

Tek bir şekilde yapılacak bir dizi 20 parselim (alt parseller değil) var. Efsanenin kutunun dışında olmasını istiyorum. Aynı zamanda, figürün boyutu azaldıkça eksenleri değiştirmek istemiyorum. Lütfen aşağıdaki sorular için bana yardım edin:

  1. Efsane kutusunu çizim alanının dışında tutmak istiyorum. (Efsanenin arsa alanının sağ tarafında olmasını istiyorum).
  2. Gösterge kutusunun içindeki metnin yazı tipi boyutunu küçülttüğümde, böylece gösterge kutusunun boyutu küçük olacak.

14
Daha yeni matplotlib sürümleri için, bu cevap , çizimlere müdahale etmeden efsanenin nereye yerleştirileceğini otomatik olarak belirlemek için matplotlib'in nasıl ayarlanacağını gösterir .
dotancohen

2
Aynı soru vardı ve benim için "kutunun dışında"
işe yarayan

1
Bu cevabın daha derinliği var https://stackoverflow.com/a/43439132/52074. ve bunu iki satır kod ile yapar! +1200 upvoted cevap da iyidir ama ben daha az genel bulundu.
Trevor Boyd Smith

2
@dotancohen "parsellere müdahale etmeden efsaneyi nereye koyacağınızı otomatik olarak belirler" Bazı durumlarda, arsa çok fazla eğri olduğunda maalesef imkansızdır. Bu durumlarda kullanıcı, göstergeyi manuel olarak yerleştirmek ve gerçekten de çizim alanının dışına koymak isteyebilir. Şu anda böyle bir komplo ile ilgili zorluklar yaşıyorum.
Ali

btw, loc: best seçeneklerinin listesi; sağ üst; sol üst; sol alt; sağ alt; sağ; merkez sol; merkez sağ; alt merkez; üst merkez; merkez;
Z-Y00

Yanıtlar:


57

Yazı tipi özellikleri oluşturarak gösterge metnini küçültebilirsiniz:

from matplotlib.font_manager import FontProperties

fontP = FontProperties()
fontP.set_size('small')
legend([plot1], "title", prop=fontP) 
# or add prop=fontP to whatever legend() call you already have

50
plot1bu cevapta ne var ?
Paul H

41
legendbu cevapta ne var ?
Richard

28
Bu, sorunun ikincil kısmını yanıtlar, ancak birincil (başlıklı olan) yanıtlamaz.
Mateen Ulhaq

8
Ayrıca, bunu yapmanın doğru yoluplt.legend(fontsize='small')
Mateen Ulhaq

41
Bu Yanıt korkunç ve çok az bağlam sunuyor!
Tekill

1794

İstediğinizi yapmanın birkaç yolu vardır. @İnalis ve @Navi'nin zaten söylediklerine eklemek için, göstergeyi bbox_to_anchorkısmen eksenlerin dışına yerleştirmek ve / veya yazı tipi boyutunu küçültmek için anahtar kelime bağımsız değişkenini kullanabilirsiniz .

Yazı tipi boyutunu küçültmeyi düşünmeden önce (bu, okumayı çok zorlaştırabilir), efsaneyi farklı yerlere yerleştirerek oynamayı deneyin:

Şimdi genel bir örnekle başlayalım:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend()

plt.show()

alternatif metin

Aynı şeyi yaparsak, ancak bbox_to_anchoranahtar kelime argümanını kullanırsak , göstergeyi eksen sınırlarının biraz dışına kaydırabiliriz:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend(bbox_to_anchor=(1.1, 1.05))

plt.show()

alternatif metin

Benzer şekilde, efsaneyi daha yatay hale getirebilir ve / veya şeklin üstüne koyabilirsiniz (ayrıca yuvarlak köşeleri ve basit bir alt gölgeyi açıyorum):

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$'%i)

ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05),
          ncol=3, fancybox=True, shadow=True)
plt.show()

alternatif metin

Alternatif olarak, geçerli grafiğin genişliğini daraltabilir ve göstergeyi tamamen şeklin ekseninin dışına koyabilirsiniz (not: tight_layout () kullanıyorsanız , ax.set_position () öğesini dışarıda bırakın:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$'%i)

# Shrink current axis by 20%
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])

# Put a legend to the right of the current axis
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))

plt.show()

alternatif metin

Ve benzer bir şekilde, çizimi dikey olarak daraltabilir ve yatay bir efsaneyi altına koyabilirsiniz:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$'%i)

# Shrink current axis's height by 10% on the bottom
box = ax.get_position()
ax.set_position([box.x0, box.y0 + box.height * 0.1,
                 box.width, box.height * 0.9])

# Put a legend below current axis
ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),
          fancybox=True, shadow=True, ncol=5)

plt.show()

alternatif metin

Matplotlib efsane rehberine bir göz atın . Ayrıca bir göz atabilirsiniz plt.figlegend().


10
Herkes bu konuda sorun yaşıyorsanız, tight_layout () sorunlara neden olacağını unutmayın!
Matthew G.Şub

4
mükemmel cevap! dokümana doğru bağlantı matplotlib.org/users/legend_guide.html#legend-location
meduz

4
bütünlük olarak, genel olarak (doc'dan özetlenir) " bbox_to_anchor4 float (x, y, genişlik, bbox'ın yüksekliği) veya normalleştirilmiş eksenlerde 2 float (x, y) bir demet olduğunu söyleyebilirsiniz. koordinatları. "
meduz

5
Bu muhtemelen en çok ziyaret ettiğim SO cevabım olduğunu itiraf etmeliyim. Tekrar tekrar gelmeye yardım edemem çünkü makul bir insanın bu mantığı buraya bakmadan hatırlayabilmesinin bir yolu yoktur.
KT.

9
Şekil bir dosyaya kaydetmek istiyorsanız, büyük olasılıkla döndürülen nesneyi, yani legend = ax.legend()ve daha sonra saklamanız gerekirfig.savefig(bbox_extra_artists=(legend,))
coldfix

791

Göstergeyi yerleştirme ( bbox_to_anchor)

İçin bir locargüman kullanılarak eksenlerin sınırlayıcı kutusunun içine bir gösterge yerleştirilir plt.legend.
Örneğin loc="upper right"Sınırlama kutusunun sağ üst köşesinde, içinde efsanesini yerleştiren varsayılan sınırlarıyla gelen (0,0)etmek (1,1)eksenleri koordinatları (veya kutu gösterimi sınırlama içinde (x0,y0, width, height)=(0,0,1,1)).

Göstergeyi eksen sınırlama kutusunun dışına yerleştirmek için, göstergenin (x0,y0)sol alt köşesinin bir grup eksen koordinatını belirtebilirsiniz .

plt.legend(loc=(1.04,0))

Bununla birlikte, daha çok yönlü bir yaklaşım, bbox_to_anchorargümanı kullanarak, açıklamanın yerleştirilmesi gereken sınırlayıcı kutuyu manuel olarak belirtmek olacaktır . Kişi kendini (x0,y0)bbox'ın sadece bir kısmını tedarik edecek şekilde kısıtlayabilir. Bu, açıklamanın locargüman tarafından verilen yönde genişleyeceği sıfır açıklıklı bir kutu oluşturur . Örneğin

plt.legend (bbox_to_anchor = (1.04,1), loc = "sol üst")

göstergeyi, göstergenin sol üst köşesi (1.04,1)eksen koordinatlarında olacak şekilde eksenlerin dışına yerleştirir .

Ayrıca modeve gibi farklı argümanlar arasındaki etkileşimin gösterildiği başka örnekler aşağıda verilmiştir ncols.

resim açıklamasını buraya girin

l1 = plt.legend(bbox_to_anchor=(1.04,1), borderaxespad=0)
l2 = plt.legend(bbox_to_anchor=(1.04,0), loc="lower left", borderaxespad=0)
l3 = plt.legend(bbox_to_anchor=(1.04,0.5), loc="center left", borderaxespad=0)
l4 = plt.legend(bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
                mode="expand", borderaxespad=0, ncol=3)
l5 = plt.legend(bbox_to_anchor=(1,0), loc="lower right", 
                bbox_transform=fig.transFigure, ncol=3)
l6 = plt.legend(bbox_to_anchor=(0.4,0.8), loc="upper right")

4-lü argümanı nasıl yorumlanacağı ilgili detaylar için bbox_to_anchor, olduğu gibi l4, bulunabilir bu soruya . Göstergeyi mode="expand"4-demet tarafından verilen sınırlama kutusunun içinde yatay olarak genişletir. Dikey olarak genişletilmiş bir efsane için bu soruya bakın .

Bazen sınırlama kutusunu eksen koordinatları yerine şekil koordinatlarında belirtmek yararlı olabilir. Bu, göstergeyi şeklin sol alt köşesine koymak için argümanın kullanıldığı l5yukarıdaki örnekte gösterilmiştir bbox_transform.

Rötuş

Efsaneyi eksenlerin dışına yerleştirmek genellikle figür tuvalinin tamamen veya kısmen dışında olduğu istenmeyen duruma yol açar.

Bu sorunun çözümleri:

  • Alt grafik parametrelerini
    ayarlama Eksenleri şekil içinde daha az yer kaplayacak (ve böylece göstergeye daha fazla alan bırakacak şekilde) alt grafik parametrelerini ayarlayabilirsiniz plt.subplots_adjust. Örneğin

    plt.subplots_adjust(right=0.7)

    figürün sağ tarafında, efsaneyi yerleştirebileceği% 30 boşluk bırakır.

  • Sıkı düzen
    Kullanma plt.tight_layoutŞekildeki öğeler şekil kenarlarına sıkıca oturacak şekilde alt grafik parametrelerini otomatik olarak ayarlamanızı sağlar. Ne yazık ki, bu otomatizmde efsane dikkate alınmaz, ancak tüm alt alanların (etiketler dahil) sığacağı bir dikdörtgen kutu sağlayabiliriz.

    plt.tight_layout(rect=[0,0,0.75,1])
  • İle figürü kaydetmebbox_inches = "tight"
    argüman bbox_inches = "tight"için plt.savefigrakam kaydetmek için kullanılabilir (efsane dahil) Tuval üzerine tüm sanatçı kaydedilmiş alana uygun olacak şekilde uyarlanmıştır. Gerekirse, şekil boyutu otomatik olarak ayarlanır.

    plt.savefig("output.png", bbox_inches="tight")
  • alt parsel parametrelerini
    otomatik olarak ayarlama Alt parsel konumunu, efsane şekil boyutunu değiştirmeden tuvalin içine sığacak şekilde otomatik olarak ayarlamanın bir yolu bu cevapta bulunabilir: Tam boyutta ve dolgu içermeyen şekil oluşturma (ve eksenlerin dışında efsane)

Yukarıda tartışılan vakalar arasında karşılaştırma:

resim açıklamasını buraya girin

Alternatifler

Bir şekil efsanesi
Şekillere eksen yerine bir gösterge kullanılabilir matplotlib.figure.Figure.legend. Bu, özel argümanların gerekli olmadığı matplotlib sürümü> = 2.1 için özellikle yararlı hale geldi

fig.legend(loc=7) 

figürün farklı eksenlerindeki tüm sanatçılar için bir efsane yaratmak. Efsane, locbir eksenin içine nasıl yerleştirildiğine benzer bir argüman kullanılarak yerleştirilir, ancak tüm şekle referans olarak - bu nedenle otomatik olarak eksenlerin dışında olacaktır. Geriye kalan, alt grafikleri, efsane ve eksenler arasında çakışma olmayacak şekilde ayarlamaktır. Burada yukarıdan "Alt grafik parametrelerini ayarlayın" noktası yardımcı olacaktır. Bir örnek:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,2*np.pi)
colors=["#7aa0c4","#ca82e1" ,"#8bcd50","#e18882"]
fig, axes = plt.subplots(ncols=2)
for i in range(4):
    axes[i//2].plot(x,np.sin(x+i), color=colors[i],label="y=sin(x+{})".format(i))

fig.legend(loc=7)
fig.tight_layout()
fig.subplots_adjust(right=0.75)   
plt.show()

resim açıklamasını buraya girin

Özel alt alan eksenlerinin içindeki açıklamaları
Kullanmanın bir alternatifi bbox_to_anchor, açıklamayı özel alt alan eksenlerine ( lax) yerleştirmek olacaktır. Gösterge alt grafiği çizimden daha küçük olması gerektiğinden gridspec_kw={"width_ratios":[4,1]}, eksen oluşturmada kullanabiliriz . Eksenleri gizleyebiliriz, lax.axis("off")ancak yine de bir efsane koyabiliriz. Efsane tutamaçlarının ve etiketlerinin gerçek çizimden elde edilmesi gerekir h,l = ax.get_legend_handles_labels()ve daha sonra laxalt grafikteki efsaneye tedarik edilebilir lax.legend(h,l). Tam bir örnek aşağıdadır.

import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = 6,2

fig, (ax,lax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios":[4,1]})
ax.plot(x,y, label="y=sin(x)")
....

h,l = ax.get_legend_handles_labels()
lax.legend(h,l, borderaxespad=0)
lax.axis("off")

plt.tight_layout()
plt.show()

Bu, yukarıdaki arsaya görsel olarak oldukça benzeyen bir arsa üretir:

resim açıklamasını buraya girin

Efsaneyi yerleştirmek için ilk eksenleri de kullanabiliriz, ancak bbox_transformefsane eksenlerini kullanabiliriz,

ax.legend(bbox_to_anchor=(0,0,1,1), bbox_transform=lax.transAxes)
lax.axis("off")

Bu yaklaşımda, efsane tutamaçlarını dışarıdan almamız gerekmez, ancak bbox_to_anchorargümanı belirtmemiz gerekir .

Daha fazla okuma ve notlar:

  • Efsanelerle yapmak istediğiniz diğer şeylerin bazı örneklerini içeren matplotlib efsane kılavuzunu düşünün .
  • Pasta grafikler için efsaneler yerleştirmek için bazı örnek kodlar doğrudan bu sorunun cevabında bulunabilir: Python - Legend, pasta grafikle çakışıyor
  • locArgüman ancak, çok sezgisel birbirine eşlenmiş değildir, aramalar kısaltmak sayılar yerine dizeleri, alabilir. İşte referans için eşleme:

resim açıklamasını buraya girin


Efsaneyi özel bir alt alan ekseni sinerjilerine çok güzel koymak fig.tight_layout. plt.subplotsEksenleri oluşturmak için kullanıyorsanız , sadece gridspec_kw={'height_ratios': [100, 1]}(veya width_ratios) gibi bir şey verin, böylece efsanenin eksenleri küçüktür ... Sonra fig.tight_layout()onu sığacak şekilde genişletecektir. En azından matplotlib 3.0.3 için.
travc

161

Sadece aramadan legend()sonra aramayı şu şekilde plot()arayın:

# matplotlib
plt.plot(...)
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))

# Pandas
df.myCol.plot().legend(loc='center left', bbox_to_anchor=(1, 0.5))

Sonuçlar şöyle görünecektir:

resim açıklamasını buraya girin


4
matplotlib.pyplot.legend'e de aynı parametreleri
iletirken çalışır

8
Bu, efsane içindeki kelimeleri başkası için kesiyor mu?
user1717828

85

Arsa alanı, kullanım dışında efsanesini yerleştirmek için locve bbox_to_anchoranahtar kelime legend(). Örneğin, aşağıdaki kod göstergeyi çizim alanının sağına yerleştirir:

legend(loc="upper left", bbox_to_anchor=(1,1))

Daha fazla bilgi için gösterge kılavuzuna bakın


10
Tamam - Uygulamayı seviyorum, ancak figürü kaydetmeye gittiğimde (her seferinde yapmak istemediğim pencerede manuel olarak yeniden boyutlandırmadan), efsane doğranıyor. Bunu nasıl düzeltebileceğim hakkında bir fikrin var mı?
astromax

@astromax Emin değilim ama belki aramayı deneyin plt.tight_layout()?
Christian Alis

81

Kısa cevap: bbox_to_anchor+ bbox_extra_artists+ kullanabilirsiniz bbox_inches='tight'.


Daha uzun cevap: bbox_to_anchorBazı kişiler yanıtlarda işaret ettiği gibi, gösterge kutusunun konumunu manuel olarak belirlemek için kullanabilirsiniz .

Ancak, genel sorun, açıklama kutusunun kırpılmış olmasıdır, örneğin:

import matplotlib.pyplot as plt

# data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# Plot
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(all_x, all_y)

# Add legend, title and axis labels
lgd = ax.legend( [ 'Lag ' + str(lag) for lag in all_x], loc='center right', bbox_to_anchor=(1.3, 0.5))
ax.set_title('Title')
ax.set_xlabel('x label')
ax.set_ylabel('y label')

fig.savefig('image_output.png', dpi=300, format='png')

resim açıklamasını buraya girin

Eğer parametreler kullanabilirsiniz rakamı kaydederken gelen efsane kutusunu önlemek için, kırpılmış alma bbox_extra_artistsve bbox_inchessormak savefigkaydedilen görüntüde kırpılmış öğeleri içerecek şekilde:

fig.savefig('image_output.png', bbox_extra_artists=(lgd,), bbox_inches='tight')

Örnek (Sadece 2 parametre eklemek için son satırı değiştirdim fig.savefig()):

import matplotlib.pyplot as plt

# data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# Plot
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(all_x, all_y)

# Add legend, title and axis labels
lgd = ax.legend( [ 'Lag ' + str(lag) for lag in all_x], loc='center right', bbox_to_anchor=(1.3, 0.5))
ax.set_title('Title')
ax.set_xlabel('x label')
ax.set_ylabel('y label')    

fig.savefig('image_output.png', dpi=300, format='png', bbox_extra_artists=(lgd,), bbox_inches='tight')

resim açıklamasını buraya girin

Matlablotlib'in, Matlab'ın yaptığı gibi efsane kutusu için dışarıdaki konuma doğal olarak izin vermesini diliyorum :

figure
x = 0:.2:12;
plot(x,besselj(1,x),x,besselj(2,x),x,besselj(3,x));
hleg = legend('First','Second','Third',...
              'Location','NorthEastOutside')
% Make the text of the legend italic and color it brown
set(hleg,'FontAngle','italic','TextColor',[.3,.2,.1])

resim açıklamasını buraya girin


6
Çok teşekkür ederim! "Bbox_to_anchor", "bbox_extra_artist" ve "" bbox_inches = 'sıkı" parametrelerinin Ben doğru çalışması için gerekli tam olarak ne olduğunu Müthiş.!
Demitrian

6
Teşekkür ederim, ama aslında bbox_inches='tight'bbox_extra_artist olmadan bile benim için mükemmel çalışıyor
avtomaton

1
@avtomaton Teşekkürler, bilmek iyi, hangi matplotlib sürümünü kullanıyorsunuz?
Franck Dernoncourt

1
@FranckDernoncourt python3, matplotlib sürüm 1.5.3
avtomaton

68

Burada tüm mükemmel cevaplar, yeni sürümleri ek olarak matplotlibve pylabedebilirsiniz araziler müdahale etmeden efsaneyi nereye koyacağını otomatik olarak belirleyebilir , eğer mümkünse.

pylab.legend(loc='best')

Bu, mümkünse efsaneyi otomatik olarak verilerden uzağa yerleştirir! Loc = 'best' kullanımını karşılaştırın

Ancak, verileri üst üste bindirmeden göstergeyi koyacak bir yer yoksa, diğer yanıtlardan birini denemek isteyeceksiniz; kullanarak loc="best"efsane asla planın dışına çıkmaz .


2
Bunu işaret ettiğiniz için teşekkür ederiz! Bunu birkaç yıl önce aradım ve bulamadım, ve bu benim hayatımı gerçekten kolaylaştıran bir şey.
Edgar H

4
Bu seçenek yardımcı olur, ancak bu yüzden ben aşağı indirdi soruya cevap vermez. görebildiğim kadarıyla, en iyi efsane arsa dışında koyar
Tommy

3
@Tommy: OP'nin yorumlarında (şimdi gitmiş gibi görünüyor) OP'nin efsanenin grafik verilerini kapsamasını istemediğini açıkça belirtti ve planın dışında bunu yapmanın tek yolu olduğunu düşündü. Bunu mefati, Mateo Sanchez, Bastiaan ve radtek'in cevaplarında görebilirsiniz. OP X istedi, ama Y'yi istedi .
dotancohen

1
Aslında değil. Efsanenin arsanın dışında olmasını özellikle istedi. Sorunun adında;) "Efsaneyi arsadan nasıl çıkarabiliriz".
durbachit

4
Bu, göstergenin verileri gizlemediğini garanti etmez. Sadece çok yoğun bir komplo yap - efsaneyi koyacak bir yer yok. Örneğin, bunu deneyin ... numpy import arange, sin, pi import matplotlib.pyplot dosyasından plt t = arange (0.0, 100.0, 0.01) fig = plt.figure (1) ax1 = fig.add_subplot (211) ax1 olarak deneyin. dağılım (t, günah (2 * pi * t), etiket = 'test') ax1.grid (True) # ax1.set_ylim ((- 2, 2)) ax1.set_ylabel ('1 Hz') ax1.set_title ( Ax1.get_xticklabels () içindeki etiket için 'sinüs dalgası veya iki'): label.set_color ('r') plt.legend (loc = 'en iyi') plt.show ()
adam.r

56

Kısa Cevap : Efsaneye sürüklenmeyi çağırın ve etkileşimli olarak istediğiniz yere taşıyın:

ax.legend().draggable()

Uzun Cevap : Göstergeyi programlı yerine etkileşimli / manuel olarak yerleştirmeyi tercih ediyorsanız, göstergenin sürüklenebilir modunu istediğiniz yere sürükleyebilmeniz için değiştirebilirsiniz. Aşağıdaki örneği kontrol edin:

import matplotlib.pylab as plt
import numpy as np
#define the figure and get an axes instance
fig = plt.figure()
ax = fig.add_subplot(111)
#plot the data
x = np.arange(-5, 6)
ax.plot(x, x*x, label='y = x^2')
ax.plot(x, x*x*x, label='y = x^3')
ax.legend().draggable()
plt.show()

Bunu tam olarak anladığımdan emin değilim. Efsaneyi bununla istediğim yere nasıl "sürükleyebilirim"? Python 3.6 ve Jupyter Notebook kullanıyorum
sb2020

14

Tam olarak ne istediğini değil, ama aynı soruna bir alternatif buldum. Efsaneyi yarı şeffaf hale getirin, şöyle: yarı şeffaf gösterge ve yarı saydam metin kutusu içeren matplotlib çizimi

Bunu aşağıdakilerle yapın:

fig = pylab.figure()
ax = fig.add_subplot(111)
ax.plot(x,y,label=label,color=color)
# Make the legend transparent:
ax.legend(loc=2,fontsize=10,fancybox=True).get_frame().set_alpha(0.5)
# Make a transparent text box
ax.text(0.02,0.02,yourstring, verticalalignment='bottom',
                     horizontalalignment='left',
                     fontsize=10,
                     bbox={'facecolor':'white', 'alpha':0.6, 'pad':10},
                     transform=self.ax.transAxes)

8

Belirtildiği gibi, efsaneyi arsaya yerleştirebilir veya kenardan hafifçe çıkarabilirsiniz. IPython Not Defteri ile yapılan Plotly Python API'sini kullanan bir örnek . Ben takımdayım.

Başlamak için gerekli paketleri yüklemek isteyeceksiniz:

import plotly
import math
import random
import numpy as np

Ardından, Plotly'yi yükleyin:

un='IPython.Demo'
k='1fw3zw2o13'
py = plotly.plotly(username=un, key=k)


def sin(x,n):
sine = 0
for i in range(n):
    sign = (-1)**i
    sine = sine + ((x**(2.0*i+1))/math.factorial(2*i+1))*sign
return sine

x = np.arange(-12,12,0.1)

anno = {
'text': '$\\sum_{k=0}^{\\infty} \\frac {(-1)^k x^{1+2k}}{(1 + 2k)!}$',
'x': 0.3, 'y': 0.6,'xref': "paper", 'yref': "paper",'showarrow': False,
'font':{'size':24}
}

l = {
'annotations': [anno], 
'title': 'Taylor series of sine',
'xaxis':{'ticks':'','linecolor':'white','showgrid':False,'zeroline':False},
'yaxis':{'ticks':'','linecolor':'white','showgrid':False,'zeroline':False},
'legend':{'font':{'size':16},'bordercolor':'white','bgcolor':'#fcfcfc'}
}

py.iplot([{'x':x, 'y':sin(x,1), 'line':{'color':'#e377c2'}, 'name':'$x\\\\$'},\
      {'x':x, 'y':sin(x,2), 'line':{'color':'#7f7f7f'},'name':'$ x-\\frac{x^3}{6}$'},\
      {'x':x, 'y':sin(x,3), 'line':{'color':'#bcbd22'},'name':'$ x-\\frac{x^3}{6}+\\frac{x^5}{120}$'},\
      {'x':x, 'y':sin(x,4), 'line':{'color':'#17becf'},'name':'$ x-\\frac{x^5}{120}$'}], layout=l)

Bu, grafiğinizi oluşturur ve efsaneyi arsanın içinde tutma şansı verir. Ayarlanmamışsa göstergenin varsayılanı, burada gösterildiği gibi onu çizimin içine yerleştirmektir.

resim açıklamasını buraya girin

Alternatif bir yerleşim için, grafiğin kenarını ve göstergenin kenarlığını yakından hizalayabilir ve daha sıkı bir uyum için kenarlık çizgilerini kaldırabilirsiniz.

resim açıklamasını buraya girin

Göstergeyi ve grafiği kodla veya GUI ile taşıyabilir ve yeniden düzenleyebilirsiniz. Göstergeyi kaydırmak için <= 1 x ve y değerlerini atayarak göstergeyi grafiğin içine konumlandırmak için aşağıdaki seçenekleriniz vardır. Örn:

  • {"x" : 0,"y" : 0} -- Sol alt
  • {"x" : 1, "y" : 0} -- Sağ alt
  • {"x" : 1, "y" : 1} -- Sağ üst
  • {"x" : 0, "y" : 1} -- Sol üst
  • {"x" :.5, "y" : 0} -- Alt merkez
  • {"x": .5, "y" : 1} -- Üst merkez

Bu durumda, belgelerdelegendstyle = {"x" : 1, "y" : 1} de açıklanan sağ üst kısmı seçiyoruz :

resim açıklamasını buraya girin


3

Bu çizgiler boyunca bir şey benim için çalıştı. Joe'dan alınan bir kodla başlayarak, bu yöntem pencere genişliğini, şeklin sağına bir göstergeye otomatik olarak uyacak şekilde değiştirir.

import matplotlib.pyplot as plt
import numpy as np

plt.ion()

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$'%i)

# Put a legend to the right of the current axis
leg = ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))

plt.draw()

# Get the ax dimensions.
box = ax.get_position()
xlocs = (box.x0,box.x1)
ylocs = (box.y0,box.y1)

# Get the figure size in inches and the dpi.
w, h = fig.get_size_inches()
dpi = fig.get_dpi()

# Get the legend size, calculate new window width and change the figure size.
legWidth = leg.get_window_extent().width
winWidthNew = w*dpi+legWidth
fig.set_size_inches(winWidthNew/dpi,h)

# Adjust the window size to fit the figure.
mgr = plt.get_current_fig_manager()
mgr.window.wm_geometry("%ix%i"%(winWidthNew,mgr.window.winfo_height()))

# Rescale the ax to keep its original size.
factor = w*dpi/winWidthNew
x0 = xlocs[0]*factor
x1 = xlocs[1]*factor
width = box.width*factor
ax.set_position([x0,ylocs[0],x1-x0,ylocs[1]-ylocs[0]])

plt.draw()

Bunu oldukça faydalı buldum ve benim için çalıştı. Eğer wx arka ucundaysanız (örn. Pencereleri kullanarak), mgr.window.wm_geometry ("% ix% i"% (winWidthNew, mgr.window.winfo_height ())) yerine mgr.window.SetClientSizeWH (winWidthNew) yazın. , winHeightNew) veya benzeri
Ezekiel Kruglick

Eğer (matplotlib benim Linux üzerinde yükleme varsayılan olan) Qt4Agg arka uç kullanıyorsanız, o zaman çizgisini değiştirmek mgr.window.wm_geometry(...)ile mgr.window.setFixedWidth(winWidthNew).
Filip

Ve daha önce keşfettiğim gibi, doğrudan bir dosyaya (SVG ve AGG arka uçları gibi) kaydetmek için tasarlanmış herhangi bir pencere göstermeyen bir arka uç kullanıyorsanız, pencereyi tamamen yeniden boyutlandırın. fig.set_size_inches(...)İhtiyacınız olan yeniden boyutlandırma ile ilgilenir.
Filip

3

Matplotlib'in yeni sürümleri efsaneyi arsa dışına yerleştirmeyi çok daha kolay hale getirdiğinden, bu soruyu yenilemeye değer. Bu örneği Matplotlib versiyonuyla ürettim 3.1.1.

Kullanıcılar loc, göstergeyi sınırlayıcı kutunun herhangi bir yerine konumlandırmak için parametreye 2 demetlik bir koordinat iletebilir . Tek sorun plt.tight_layout(), arsa boyutlarını yeniden hesaplamak için matplotlib almak için çalıştırmanız gerekir, böylece efsane görünür:

import matplotlib.pyplot as plt

plt.plot([0, 1], [0, 1], label="Label 1")
plt.plot([0, 1], [0, 2], label='Label 2')

plt.legend(loc=(1.05, 0.5))
plt.tight_layout()

Bu, aşağıdaki grafiğe yol açar:

efsane dışında arsa

Referanslar:


2

Ayrıca deneyebilirsiniz figlegend. Herhangi bir Axes nesnesinden bağımsız bir efsane oluşturmak mümkündür. Ancak, nesnelerin biçimlendirmesinin doğru şekilde aktarıldığından emin olmak için bazı "kukla" Yollar oluşturmanız gerekebilir.


1

İşte bulundu matplotlib öğretici bir örnektir burada . Bu daha basit örneklerden biri ama efsaneye şeffaflık ekledim ve etkileşimli kabuğa yapıştırarak bir sonuç elde edebilmeniz için plt.show () ekledim:

import matplotlib.pyplot as plt
p1, = plt.plot([1, 2, 3])
p2, = plt.plot([3, 2, 1])
p3, = plt.plot([2, 3, 1])
plt.legend([p2, p1, p3], ["line 1", "line 2", "line 3"]).get_frame().set_alpha(0.5)
plt.show()

1

Büyük efsanem olduğunda benim için çalışan çözüm, ekstra boş görüntü düzeni kullanmaktı. Aşağıdaki örnekte 4 satır yaptım ve alt kısımda efsane için ofset (bbox_to_anchor) ile görüntü çiziyorum.

f = plt.figure()
ax = f.add_subplot(414)
lgd = ax.legend(loc='upper left', bbox_to_anchor=(0, 4), mode="expand", borderaxespad=0.3)
ax.autoscale_view()
plt.savefig(fig_name, format='svg', dpi=1200, bbox_extra_artists=(lgd,), bbox_inches='tight')

1

Eklemeye benzer bbox_extra_artistsve bbox_inchesekstra sanatçılarınızın savefigçağrınızın kapsamında olması gerekmeyen başka bir çözüm . Bunu, fonksiyonumun içindeki çizimimin çoğunu oluşturduğum için ortaya çıktım.

Yazmak istediğinizde tüm eklemelerinizi sınırlayıcı kutuya eklemek yerine, Figuresanatçıların önüne önceden ekleyebilirsiniz . Franck Dernoncourt'un yukarıdaki cevabına benzer bir şey kullanarak :

import matplotlib.pyplot as plt

# data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# plotting function
def gen_plot(x, y):
    fig = plt.figure(1)
    ax = fig.add_subplot(111)
    ax.plot(all_x, all_y)
    lgd = ax.legend( [ "Lag " + str(lag) for lag in all_x], loc="center right", bbox_to_anchor=(1.3, 0.5))
    fig.artists.append(lgd) # Here's the change
    ax.set_title("Title")
    ax.set_xlabel("x label")
    ax.set_ylabel("y label")
    return fig

# plotting
fig = gen_plot(all_x, all_y)

# No need for `bbox_extra_artists`
fig.savefig("image_output.png", dpi=300, format="png", bbox_inches="tight")

Oluşturulan çizim.


-1

Sorununuzu zaten çözüp çözmediğinizi bilmiyorum ... muhtemelen evet, ama ... Ben sadece matlab gibi, konum için 'dışında' dizesini kullandım. Matplotlib'den pylab ithal ettim. kodu aşağıdaki gibi görün:

from matplotlib as plt
from matplotlib.font_manager import FontProperties
...
...
t = A[:,0]
sensors = A[:,index_lst]

for i in range(sensors.shape[1]):
    plt.plot(t,sensors[:,i])

plt.xlabel('s')
plt.ylabel('°C')
lgd = plt.legend(b,loc='center left', bbox_to_anchor=(1, 0.5),fancybox = True, shadow = True)

Grafiği görmek için tıklayın

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.