Colocando la leyenda ( bbox_to_anchor
)
Se coloca una leyenda dentro del cuadro delimitador de los ejes utilizando el loc
argumento to plt.legend
.
Por ejemplo, loc="upper right"
coloca la leyenda en la esquina superior derecha del cuadro delimitador, que de forma predeterminada se extiende desde (0,0)
hasta (1,1)
en las coordenadas de los ejes (o en la notación del cuadro delimitador (x0,y0, width, height)=(0,0,1,1)
).
Para colocar la leyenda fuera del cuadro delimitador de ejes, se puede especificar una tupla (x0,y0)
de coordenadas de ejes de la esquina inferior izquierda de la leyenda.
plt.legend(loc=(1.04,0))
Sin embargo, un enfoque más versátil sería especificar manualmente el cuadro delimitador en el que se debe colocar la leyenda, utilizando el bbox_to_anchor
argumento. Uno puede restringirse para suministrar solo la (x0,y0)
parte de bbox. Esto crea un cuadro de intervalo cero, fuera del cual la leyenda se expandirá en la dirección dada por el loc
argumento. P.ej
plt.legend (bbox_to_anchor = (1.04,1), loc = "arriba a la izquierda")
coloca la leyenda fuera de los ejes, de modo que la esquina superior izquierda de la leyenda esté en posición (1.04,1)
en las coordenadas de los ejes.
A continuación se dan más ejemplos, donde además se muestra la interacción entre diferentes argumentos como mode
y 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")
Los detalles sobre cómo interpretar el argumento de 4 tuplas bbox_to_anchor
, como en l4
, se pueden encontrar en esta pregunta . El mode="expand"
expande la leyenda horizontalmente dentro del cuadro delimitador propuesta por el 4-tupla. Para una leyenda expandida verticalmente, vea esta pregunta .
A veces puede ser útil especificar el cuadro delimitador en las coordenadas de la figura en lugar de las coordenadas de los ejes. Esto se muestra en el ejemplo l5
de arriba, donde elbbox_transform
argumento se usa para poner la leyenda en la esquina inferior izquierda de la figura.
Postprocesamiento
Habiendo colocado la leyenda fuera de los ejes a menudo conduce a la situación no deseada de que está total o parcialmente fuera del lienzo de la figura.
Las soluciones a este problema son:
Ajuste los parámetros de la subtrama
Uno puede ajustar los parámetros de la subtrama de tal manera que los ejes ocupen menos espacio dentro de la figura (y, por lo tanto, dejen más espacio para la leyenda) plt.subplots_adjust
. P.ej
plt.subplots_adjust(right=0.7)
deja un 30% de espacio en el lado derecho de la figura, donde se puede colocar la leyenda.
Diseño ajustado
Usando plt.tight_layout
Permite ajustar automáticamente los parámetros de la subtrama de modo que los elementos de la figura se asienten firmemente contra los bordes de la figura. Desafortunadamente, la leyenda no se tiene en cuenta en este automatismo, pero podemos proporcionar un cuadro rectangular en el que se ajustará toda el área de subtramas (incluidas las etiquetas).
plt.tight_layout(rect=[0,0,0.75,1])
Guardar la figura conbbox_inches = "tight"
El argumento bbox_inches = "tight"
to plt.savefig
se puede usar para guardar la figura de modo que todos los artistas en el lienzo (incluida la leyenda) quepan en el área guardada. Si es necesario, el tamaño de la figura se ajusta automáticamente.
plt.savefig("output.png", bbox_inches="tight")
- ajuste automático de los parámetros de la subtrama
En esta respuesta se puede encontrar una forma de ajustar automáticamente la posición de la subtrama de modo que la leyenda se ajuste dentro del lienzo sin cambiar el tamaño de la figura : Crear una figura con tamaño exacto y sin relleno (y leyenda fuera de los ejes)
Comparación entre los casos discutidos anteriormente:
Alternativas
Una leyenda de la figura
se puede usar una leyenda para la figura en lugar de los ejes, matplotlib.figure.Figure.legend
. Esto se ha vuelto especialmente útil para matplotlib versión> = 2.1, donde no se necesitan argumentos especiales
fig.legend(loc=7)
para crear una leyenda para todos los artistas en los diferentes ejes de la figura. La leyenda se coloca usando el loc
argumento, similar a cómo se coloca dentro de los ejes, pero en referencia a la figura completa, por lo tanto, estará fuera de los ejes de forma algo automática. Lo que queda es ajustar las subtramas para que no haya superposición entre la leyenda y los ejes. Aquí será útil el punto "Ajustar los parámetros de la subtrama" desde arriba. Un ejemplo:
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()
Leyenda dentro de ejes de subtrama dedicados
Una alternativa al uso bbox_to_anchor
sería colocar la leyenda en sus ejes de subtrama dedicados ( lax
). Dado que la subtrama de la leyenda debe ser más pequeña que la trama, podemos usarla gridspec_kw={"width_ratios":[4,1]}
en la creación de ejes. Podemos ocultar los ejes lax.axis("off")
pero todavía poner una leyenda en. Los tiradores de leyenda y etiquetas necesitan obtenida a partir de la trama real a través h,l = ax.get_legend_handles_labels()
, y luego se puede suministrar a la leyenda en la lax
trama secundaria, lax.legend(h,l)
. Un ejemplo completo está abajo.
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()
Esto produce una trama que es visualmente bastante similar a la trama de arriba:
También podríamos usar los primeros ejes para colocar la leyenda, pero usar los bbox_transform
ejes de la leyenda,
ax.legend(bbox_to_anchor=(0,0,1,1), bbox_transform=lax.transAxes)
lax.axis("off")
En este enfoque, no necesitamos obtener los identificadores de leyenda externamente, pero necesitamos especificar el bbox_to_anchor
argumento.
Lecturas adicionales y notas:
- Considere la guía de la leyenda matplotlib con algunos ejemplos de otras cosas que desea hacer con las leyendas.
- Algunos códigos de ejemplo para colocar leyendas para gráficos circulares se pueden encontrar directamente en respuesta a esta pregunta: Python - La leyenda se superpone con el gráfico circular
- El
loc
argumento puede tomar números en lugar de cadenas, lo que hace que las llamadas sean más cortas, sin embargo, no están muy intuitivamente asignadas entre sí. Aquí está el mapeo para referencia: