Placer la légende (bbox_to_anchor
)
Une légende est positionnée à l'intérieur du cadre de sélection des axes à l'aide de l' loc
argument to plt.legend
.
Par exemple, loc="upper right"
place la légende dans le coin supérieur droit du cadre de sélection, qui s'étend par défaut de (0,0)
à (1,1)
en coordonnées d'axe (ou en notation de cadre de sélection(x0,y0, width, height)=(0,0,1,1)
).
Pour placer la légende en dehors du cadre de délimitation des axes, on peut spécifier un tuple (x0,y0)
de coordonnées d'axes du coin inférieur gauche de la légende.
plt.legend(loc=(1.04,0))
Cependant, une approche plus polyvalente serait de spécifier manuellement la boîte englobante dans laquelle la légende doit être placée, en utilisant l' bbox_to_anchor
argument. On peut se limiter à ne fournir que la (x0,y0)
partie de la bbox. Cela crée une zone de portée nulle, à partir de laquelle la légende s'étendra dans la direction donnée par l' loc
argument. Par exemple
plt.legend (bbox_to_anchor = (1.04,1), loc = "en haut à gauche")
place la légende en dehors des axes, de sorte que le coin supérieur gauche de la légende se trouve en position des (1.04,1)
coordonnées des axes.
D'autres exemples sont donnés ci-dessous, où en plus l'interaction entre différents arguments comme mode
et ncols
est montrée.
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")
Les détails sur la façon d'interpréter l'argument à 4 tuples bbox_to_anchor
, comme dans l4
, se trouvent dans cette question . Le mode="expand"
développe la légende horizontalement à l'intérieur de la boîte englobante donnée par le quadruple. Pour une légende étendue verticalement, voir cette question .
Parfois, il peut être utile de spécifier le cadre de délimitation en coordonnées de figure au lieu de coordonnées d'axe. Ceci est illustré dans l'exemple l5
ci-dessus, où lebbox_transform
argument est utilisé pour placer la légende dans le coin inférieur gauche de la figure.
Post-traitement
Le fait d'avoir placé la légende en dehors des axes conduit souvent à la situation indésirable qu'elle est complètement ou partiellement en dehors du canevas de la figure.
Les solutions à ce problème sont:
Ajuster les paramètres de sous-intrigue
On peut ajuster les paramètres de sous-intrigue de telle sorte que les axes prennent moins d'espace à l'intérieur de la figure (et ainsi laissent plus d'espace à la légende) en utilisant plt.subplots_adjust
. Par exemple
plt.subplots_adjust(right=0.7)
laisse 30% d'espace sur le côté droit de la figure, où l'on pourrait placer la légende.
Disposition serrée
Utilisation plt.tight_layout
Permet d'ajuster automatiquement les paramètres du sous- tracé de sorte que les éléments de la figure soient bien serrés contre les bords de la figure. Malheureusement, la légende n'est pas prise en compte dans cet automatisme, mais nous pouvons fournir une boîte rectangulaire dans laquelle toute la zone des sous-parcelles (y compris les étiquettes) rentrera.
plt.tight_layout(rect=[0,0,0.75,1])
Enregistrement de la figure avecbbox_inches = "tight"
L'argument bbox_inches = "tight"
à plt.savefig
peut être utilisé pour enregistrer la figure de telle sorte que tous les artistes sur la toile (y compris la légende) soient placés dans la zone enregistrée. Si nécessaire, la taille de la figure est automatiquement ajustée.
plt.savefig("output.png", bbox_inches="tight")
- ajustement automatique des paramètres de sous-intrigue
Un moyen d'ajuster automatiquement la position du sous-tracé de telle sorte que la légende s'adapte à l'intérieur du canevas sans changer la taille de la figure se trouve dans cette réponse: Création d'une figure avec la taille exacte et sans remplissage (et légende en dehors des axes)
Comparaison entre les cas discutés ci-dessus:
Alternatives
Une légende des figures
,
on peut utiliser une légende à la figure au lieu des axes, matplotlib.figure.Figure.legend
. Ceci est devenu particulièrement utile pour la version matplotlib> = 2.1, où aucun argument spécial n'est nécessaire
fig.legend(loc=7)
créer une légende pour tous les artistes dans les différents axes de la figure. La légende est placée en utilisant l' loc
argument, similaire à la façon dont elle est placée à l'intérieur d'un axe, mais en référence à la figure entière - elle sera donc en dehors des axes un peu automatiquement. Il reste à ajuster les sous-tracés de manière à ce qu'il n'y ait pas de chevauchement entre la légende et les axes. Ici, le point "Ajuster les paramètres du sous-tracé" ci-dessus sera utile. Un exemple:
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()
Légende à l'intérieur des axes de sous-tracé dédiés
Une alternative à l'utilisation bbox_to_anchor
serait de placer la légende dans ses axes de sous-tracé dédiés ( lax
). Étant donné que le sous-tracé de légende doit être plus petit que le tracé, nous pouvons utiliser gridspec_kw={"width_ratios":[4,1]}
lors de la création des axes. Nous pouvons masquer les axes lax.axis("off")
mais toujours mettre une légende. Les poignées et les étiquettes de légende doivent être obtenues à partir du tracé réel via h,l = ax.get_legend_handles_labels()
, et peuvent ensuite être fournies à la légende dans lelax
sous - intrigue, lax.legend(h,l)
. Un exemple complet est ci-dessous.
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()
Cela produit une intrigue qui est visuellement assez similaire à l'intrigue ci-dessus:
Nous pourrions également utiliser les premiers axes pour placer la légende, mais utiliser le bbox_transform
axes de légende,
ax.legend(bbox_to_anchor=(0,0,1,1), bbox_transform=lax.transAxes)
lax.axis("off")
Dans cette approche, nous n'avons pas besoin d'obtenir les poignées de légende en externe, mais nous devons spécifier le bbox_to_anchor
argument.
Lectures complémentaires et notes:
- Considérez le guide de légende matplotlib avec quelques exemples d'autres choses que vous voulez faire avec des légendes.
- Un exemple de code pour placer des légendes pour les graphiques à secteurs peut être trouvé directement en réponse à cette question: Python - La légende chevauche le graphique à secteurs
- L'
loc
argument peut prendre des nombres au lieu de chaînes, ce qui raccourcit les appels, cependant, ils ne sont pas très intuitivement mappés les uns aux autres. Voici le mappage pour référence: