2014-04-23 10 views
6

Tworzę działki przy użyciu Matplotlib, które zapisuję jako SVG, eksportuję do .pdf + .pdf_tex za pomocą Inkscape i dołączam plik .pdf_tex do dokumentu LaTeX.Przenoszenie i zmiana rozmiaru legend-box w matplotlib

To oznacza, że ​​mogę wejść lateksu polecenia w tytuły, legendy itp, dając obraz jak ten plot

co czyni tak, gdy używam go w moim dokumencie LaTeX. Zauważ, że czcionka dla liczb na osi zmienić, a lateks kodu w legendzie jest kompilowany:

plot rendered using LaTeX

kod na działce (jak eksport do SVG nie pokazano tutaj, ale można wykazać na życzenie):

import numpy as np 
x = np.linspace(0,1,100) 
y = x**2 

import matplotlib.pyplot as plt 
plt.plot(x, y, label = '{\\footnotesize \$y = x^2\$}') 
plt.legend(loc = 'best') 
plt.show() 

Problem polega na tym, jak widać, że wyrównanie i rozmiar pudełka wokół legendy jest nieprawidłowy. Dzieje się tak, ponieważ rozmiar tekstu etykiety zmienia się, gdy obraz jest przesyłany przez Inkscape + pdflatex (ponieważ \footnotesize itd. Znika i zmienia się rozmiar czcionki).

I zorientowali się, że mogę wybrać położenie etykiety przez którąkolwiek

plt.label(loc = 'upper right') 

lub jeśli chcesz mieć większą kontrolę mogę używać

plt.label(bbox_to_anchor = [0.5, 0.2]) 

ale nie znalazłem żadnego sposobu zmniejszania pola na etykiecie. czy to możliwe?

Alternatywą do podejmowania pole mniejsze jest usunięcie obrys skrzynki używając coś jak

legend = plt.legend() 
legend.get_frame().set_edgecolor('1.0') 

a następnie przesuwając etykietę gdzie chcę. W takim razie chciałbym być w stanie określić położenie etykiety przez pierwszy najmu python/matplotlib go umieścić za pomocą

plt.label(loc = 'upper right') 

a następnie na przykład przesuwając go nieco w prawo. czy to możliwe? Próbowałem używać get_bbox_to_anchor() i set_bbox_to_anchor(), ale nie mogę go uruchomić.

Odpowiedz

8

Możesz przenieść legendę po jej automatycznym umieszczeniu przez narysowanie, a następnie uzyskanie pozycji boksa. Oto przykład:

import matplotlib.pyplot as plt 
import numpy as np 

# Plot data 
x = np.linspace(0,1,100) 
y = x**2 
fig = plt.figure() 
ax = fig.add_subplot(221) #small subplot to show how the legend has moved. 

# Create legend 
plt.plot(x, y, label = '{\\footnotesize \$y = x^2\$}') 
leg = plt.legend(loc = 'upper right') 

plt.draw() # Draw the figure so you can find the positon of the legend. 

# Get the bounding box of the original legend 
bb = leg.get_bbox_to_anchor().inverse_transformed(ax.transAxes) 

# Change to location of the legend. 
xOffset = 1.5 
bb.x0 += xOffset 
bb.x1 += xOffset 
leg.set_bbox_to_anchor(bb, transform = ax.transAxes) 


# Update the plot 
plt.show() 

legend moved after first drawing

+0

To wygląda świetnie. Nigdy wcześniej nie widziałem "legendPatch", dlaczego nie jest to wspomniane w [docs] (http://matplotlib.org/api/legend_api.html#module-matplotlib.legend)? –

+0

Nie wiem. Nauczyłem się tej sztuczki z listy e-mailowej użytkowników Matplotlib, ale nie mogę znaleźć tego postu.Mam nadzieję, że ktoś inny zadzwoni z bardziej kompletną odpowiedzią! – Molly

+0

to nie działa z wersją matplotlib '1.5.1 + 1304.gc0728d2' 'matplotlib/transforms.ps in get_points (self) 1101 # to samo. 1102 punktów = self._transform.transform ( -> 1103 [[p [0, 0], p [0, 1]], 1104 [p [1, 0], p [0, 1]], 1105 [p [0, 0], p [1, 1]], TypeError: indeksy listy muszą być liczbami całkowitymi, a nie krotką " –

5

Można użyć parametrów bbox_to_anchor i bbox_transform pomóc ustawienie kotwicę do legendy:

ax = plt.gca() 
plt.legend(bbox_to_anchor=(1.1, 1.1), bbox_transform=ax.transAxes) 

Zauważ, że (1.1, 1.1) są w osiach współrzędnych w ten przykład. Jeśli chcesz użyć współrzędnych danych, musisz użyć wartości bbox_transform=ax.transData.

+1

Dzięki. Nie pozwala mi to przenosić legend po ich umieszczeniu.A przy okazji, 'transAxes' jest rzeczywiście domyślne zgodnie z [doc] (http://matplotlib.org/api/legend_api.html#module-matplotlib .legend). –

+0

@FilipSund, tak, 'transAxes' jest domyślnym ... możesz przejść do' bbox_to_achor' krotki z 4 zmiennymi (x, y, width, height), które powinny dać ci większą kontrolę nad zachowanie boksów ... –