Posizionamento della legenda ( bbox_to_anchor
)
Una legenda viene posizionata all'interno del rettangolo di selezione degli assi usando l' loc
argomento to plt.legend
.
Ad esempio loc="upper right"
posiziona la legenda nell'angolo in alto a destra del rettangolo di selezione, che per impostazione predefinita si estende da (0,0)
a (1,1)
in coordinate degli assi (o nella notazione del rettangolo di selezione (x0,y0, width, height)=(0,0,1,1)
).
Per posizionare la legenda all'esterno del rettangolo di selezione degli assi, è possibile specificare una tupla (x0,y0)
di coordinate degli assi nell'angolo inferiore sinistro della legenda.
plt.legend(loc=(1.04,0))
Tuttavia, un approccio più versatile sarebbe quello di specificare manualmente il rettangolo di selezione in cui inserire la legenda, usando l' bbox_to_anchor
argomento. Ci si può limitare a fornire solo la (x0,y0)
parte della bbox. Questo crea una casella di span zero, fuori dalla quale la legenda si espanderà nella direzione data loc
dall'argomento. Per esempio
plt.legend (bbox_to_anchor = (1.04,1), loc = "in alto a sinistra")
posiziona la legenda fuori dagli assi, in modo tale che l'angolo superiore sinistro della legenda sia in posizione (1.04,1)
nelle coordinate degli assi.
Ulteriori esempi sono riportati di seguito, in cui sono mostrate anche l'interazione tra diversi argomenti come mode
e ncols
.
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")
I dettagli su come interpretare l'argomento in 4 tuple bbox_to_anchor
come, come in l4
, sono disponibili in questa domanda . Il mode="expand"
espande la legenda orizzontalmente all'interno del rettangolo di selezione in 4 parametri. Per una legenda espansa verticalmente, vedi questa domanda .
A volte può essere utile specificare il riquadro di delimitazione nelle coordinate della figura anziché nelle coordinate degli assi. Questo è mostrato nell'esempio l5
dall'alto, in cui l' bbox_transform
argomento viene utilizzato per posizionare la legenda nell'angolo in basso a sinistra della figura.
Post produzione
Avere posto la legenda fuori dagli assi spesso porta alla situazione indesiderata che è completamente o parzialmente al di fuori della tela della figura.
Le soluzioni a questo problema sono:
Regola i parametri della sottotrama
È possibile regolare i parametri della sottotrama in modo tale che gli assi occupino meno spazio all'interno della figura (e quindi lasciano più spazio alla legenda) utilizzando plt.subplots_adjust
. Per esempio
plt.subplots_adjust(right=0.7)
lascia il 30% di spazio sul lato destro della figura, dove è possibile posizionare la legenda.
Layout stretto
Utilizzo plt.tight_layout
Consente di regolare automaticamente i parametri della sottotrama in modo tale che gli elementi nella figura siano ben aderenti ai bordi della figura. Sfortunatamente, la leggenda non viene presa in considerazione in questo automatismo, ma possiamo fornire una scatola rettangolare in cui si adatterà l'intera area delle sottotrame (comprese le etichette).
plt.tight_layout(rect=[0,0,0.75,1])
Salvare la figura conbbox_inches = "tight"
L'argomento bbox_inches = "tight"
su plt.savefig
può essere usato per salvare la figura in modo tale che tutti gli artisti sulla tela (inclusa la legenda) siano adatti all'area salvata. Se necessario, la dimensione della figura viene regolata automaticamente.
plt.savefig("output.png", bbox_inches="tight")
- regolazione automatica dei parametri della sottotrama
Un modo per regolare automaticamente la posizione della sottotrama in modo tale che la legenda si adatti all'interno della tela senza cambiare la dimensione della figura si trova in questa risposta: Creazione di una figura con dimensioni esatte e nessuna imbottitura (e legenda fuori dagli assi)
Confronto tra i casi discussi sopra:
alternative
Una figura legenda
Uno può utilizzare una legenda alla figura invece degli assi, matplotlib.figure.Figure.legend
. Ciò è diventato particolarmente utile per la versione matplotlib> = 2.1, dove non sono necessari argomenti speciali
fig.legend(loc=7)
per creare una leggenda per tutti gli artisti nei diversi assi della figura. La legenda viene posizionata usando l' loc
argomento, in modo simile al modo in cui è posizionata all'interno di un asse, ma in riferimento all'intera figura - quindi sarà fuori dagli assi in qualche modo automaticamente. Ciò che rimane è regolare i grafici secondari in modo tale che non vi siano sovrapposizioni tra la legenda e gli assi. Qui sarà utile il punto "Regola i parametri della sottotrama" dall'alto. Un esempio:
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()
Legenda all'interno degli assi della sottotrama dedicata
Un'alternativa all'utilizzo bbox_to_anchor
sarebbe quella di posizionare la legenda nei suoi assi della trama secondaria dedicata ( lax
). Poiché la sottotrama della legenda dovrebbe essere più piccola della trama, possiamo usarla gridspec_kw={"width_ratios":[4,1]}
durante la creazione degli assi. Siamo in grado di nascondere gli assi lax.axis("off")
, ma ancora messo una leggenda. Le maniglie leggenda e le etichette devono ottenuto dalla trama vera via h,l = ax.get_legend_handles_labels()
, e può quindi essere fornito alla leggenda nella lax
sottotrama, lax.legend(h,l)
. Un esempio completo è di seguito.
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()
Questo produce una trama che è visivamente abbastanza simile alla trama dall'alto:
Potremmo anche usare i primi assi per posizionare la legenda, ma usare il bbox_transform
degli assi della legenda,
ax.legend(bbox_to_anchor=(0,0,1,1), bbox_transform=lax.transAxes)
lax.axis("off")
In questo approccio, non è necessario ottenere esternamente gli handle di legenda, ma è necessario specificare l' bbox_to_anchor
argomento.
Ulteriori letture e note:
- Considera la guida della legenda matplotlib con alcuni esempi di altre cose che vuoi fare con le leggende.
- Alcuni codici di esempio per il posizionamento di legende per grafici a torta possono essere trovati direttamente in risposta a questa domanda: Python - La legenda si sovrappone al grafico a torta
- L'
loc
argomento può accettare numeri anziché stringhe, il che rende le chiamate più brevi, tuttavia non sono mappate in modo molto intuitivo tra loro. Ecco la mappatura per riferimento: