J'ai une série de 20 parcelles (pas de sous-parcelles) à faire en une seule figure. Je veux que la légende soit en dehors de la boîte. En même temps, je ne veux pas changer les axes, car la taille de la figure se réduit. Veuillez m'aider pour les requêtes suivantes:
- Je souhaite conserver la zone de légende en dehors de la zone de traçage. (Je veux que la légende soit à l'extérieur sur le côté droit de la zone de traçage).
- Existe-t-il de toute façon que je réduise la taille de la police du texte à l'intérieur de la zone de légende, de sorte que la taille de la zone de légende soit petite.
python
matplotlib
legend
pottigopi
la source
la source
https://stackoverflow.com/a/43439132/52074
. et le fait avec deux lignes de code! la réponse votée +1200 est également bonne mais je l'ai trouvée moins générique.Réponses:
Vous pouvez réduire le texte de la légende en créant des propriétés de police:
la source
plot1
contient cette réponse?legend
contient cette réponse?plt.legend(fontsize='small')
Il existe plusieurs façons de faire ce que vous voulez. Pour ajouter à ce que @inalis et @Navi ont déjà dit, vous pouvez utiliser l'
bbox_to_anchor
argument mot - clé pour placer la légende partiellement en dehors des axes et / ou diminuer la taille de la police.Avant d'envisager de réduire la taille de la police (ce qui peut rendre les choses extrêmement difficiles à lire), essayez de jouer avec le placement de la légende à différents endroits:
Commençons donc par un exemple générique:
Si nous faisons la même chose, mais en utilisant l'
bbox_to_anchor
argument mot - clé, nous pouvons déplacer la légende légèrement en dehors des limites des axes:De même, vous pouvez rendre la légende plus horizontale et / ou la placer en haut de la figure (j'allume également des coins arrondis et une simple ombre portée):
Vous pouvez également réduire la largeur du tracé actuel et placer la légende entièrement en dehors de l'axe de la figure (remarque: si vous utilisez tight_layout () , puis omettez ax.set_position ():
Et de la même manière, vous pouvez réduire l'intrigue verticalement et mettre la légende horizontale en bas:
Jetez un œil au guide de légende de matplotlib . Vous pouvez également consulter
plt.figlegend()
.la source
bbox_to_anchor
est un tuple de 4 flotteurs (x, y, largeur, hauteur de la bbox), ou un tuple de 2 flotteurs (x, y) dans des axes normalisés coordonnées. "legend = ax.legend()
-à- dire et plus tardfig.savefig(bbox_extra_artists=(legend,))
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 toplt.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.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 exempleplace 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
etncols
est montrée.Les détails sur la façon d'interpréter l'argument à 4 tuples
bbox_to_anchor
, comme dansl4
, se trouvent dans cette question . Lemode="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 exemplelaisse 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.Enregistrement de la figure avec
bbox_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.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écessairecré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: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 utilisergridspec_kw={"width_ratios":[4,1]}
lors de la création des axes. Nous pouvons masquer les axeslax.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 viah,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.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,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:
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:la source
fig.tight_layout
. Si vous utilisezplt.subplots
pour créer les axes, donnez-lui simplement quelque chose commegridspec_kw={'height_ratios': [100, 1]}
(ou width_ratios) pour que les axes de la légende soient minuscules ... Ensuitefig.tight_layout()
, vous les agrandirez pour les ajuster. Au moins pour matplotlib 3.0.3.Il suffit d'
legend()
appeler après l'plot()
appel comme ceci:Les résultats ressembleraient à ceci:
la source
Pour placer la légende en dehors de la zone de tracé, utilisez les mots
loc
-bbox_to_anchor
clés etlegend()
. Par exemple, le code suivant placera la légende à droite de la zone de traçage:Pour plus d'informations, consultez le guide des légendes
la source
plt.tight_layout()
?Réponse courte: vous pouvez utiliser
bbox_to_anchor
+bbox_extra_artists
+bbox_inches='tight'
.Réponse plus longue: vous pouvez utiliser
bbox_to_anchor
pour spécifier manuellement l'emplacement de la zone de légende, comme d'autres personnes l'ont souligné dans les réponses.Cependant, le problème habituel est que la zone de légende est rognée, par exemple:
Afin d'empêcher la zone de légende de se recadrer, lorsque vous enregistrez la figure, vous pouvez utiliser les paramètres
bbox_extra_artists
etbbox_inches
demandersavefig
d'inclure des éléments recadrés dans l'image enregistrée:fig.savefig('image_output.png', bbox_extra_artists=(lgd,), bbox_inches='tight')
Exemple (j'ai seulement changé la dernière ligne pour ajouter 2 paramètres
fig.savefig()
):Je souhaite que matplotlib autorise nativement l'emplacement extérieur pour la boîte de légende comme Matlab le fait :
la source
bbox_inches='tight'
fonctionne parfaitement pour moi même sans bbox_extra_artistEn plus de toutes les excellentes réponses ici, des versions plus récentes de
matplotlib
etpylab
peuvent déterminer automatiquement où placer la légende sans interférer avec les tracés , si possible.Cela placera automatiquement la légende loin des données si possible!
Cependant, s'il n'y a pas de place pour mettre la légende sans chevaucher les données, alors vous voudrez essayer l'une des autres réponses; l'utilisation
loc="best"
ne mettra jamais la légende en dehors de l'intrigue.la source
Réponse courte : invoquez le draggable sur la légende et déplacez-la de manière interactive où vous le souhaitez:
Réponse longue : Si vous préférez plutôt placer la légende de manière interactive / manuelle plutôt que par programme, vous pouvez basculer le mode de glissement de la légende afin de pouvoir la faire glisser où vous le souhaitez. Consultez l'exemple ci-dessous:
la source
Pas exactement ce que vous avez demandé, mais j'ai trouvé que c'était une alternative pour le même problème. Rendez la légende semi-transparente, comme ceci:
Faites ceci avec:
la source
Comme indiqué précédemment, vous pouvez également placer la légende dans l'intrigue, ou légèrement sur le bord également. Voici un exemple utilisant l' API Plotly Python , réalisée avec un bloc-notes IPython . Je fais partie de l'équipe.
Pour commencer, vous voudrez installer les packages nécessaires:
Ensuite, installez Plotly:
Cela crée votre graphique et vous permet de conserver la légende dans l'intrigue elle-même. La valeur par défaut de la légende si elle n'est pas définie est de la placer dans le tracé, comme illustré ici.
Pour un placement alternatif, vous pouvez aligner étroitement le bord du graphique et la bordure de la légende, et supprimer les lignes de bordure pour un ajustement plus proche.
Vous pouvez déplacer et remodeler la légende et le graphique avec du code ou avec l'interface graphique. Pour déplacer la légende, vous disposez des options suivantes pour positionner la légende à l'intérieur du graphique en affectant des valeurs x et y <= 1. Par exemple:
{"x" : 0,"y" : 0}
-- En bas à gauche{"x" : 1, "y" : 0}
-- En bas à droite{"x" : 1, "y" : 1}
-- En haut à droite{"x" : 0, "y" : 1}
-- En haut à gauche{"x" :.5, "y" : 0}
- En bas au centre{"x": .5, "y" : 1}
-- Centre supérieurDans ce cas, nous choisissons le coin supérieur droit
legendstyle = {"x" : 1, "y" : 1}
, également décrit dans la documentation :la source
Quelque chose dans ce sens a fonctionné pour moi. En commençant avec un peu de code extrait de Joe, cette méthode modifie la largeur de la fenêtre pour ajuster automatiquement une légende à droite de la figure.
la source
mgr.window.wm_geometry(...)
parmgr.window.setFixedWidth(winWidthNew)
.fig.set_size_inches(...)
s'occupe du redimensionnement dont vous avez besoin.Il vaut la peine de rafraîchir cette question, car les nouvelles versions de Matplotlib ont beaucoup facilité la position de la légende en dehors de l'intrigue. J'ai produit cet exemple avec la version Matplotlib
3.1.1
.Les utilisateurs peuvent transmettre un tuple de coordonnées au
loc
paramètre pour positionner la légende n'importe où dans le cadre de sélection. Le seul problème est que vous devez exécuterplt.tight_layout()
pour que matplotlib recalcule les dimensions du tracé afin que la légende soit visible:Cela conduit à l'intrigue suivante:
Références:
la source
Vous pouvez également essayer
figlegend
. Il est possible de créer une légende indépendante de tout objet Axes. Cependant, vous devrez peut-être créer des chemins "factices" pour vous assurer que la mise en forme des objets est correctement transmise.la source
Voici un exemple du tutoriel matplotlib que vous trouverez ici . C'est l'un des exemples les plus simples, mais j'ai ajouté de la transparence à la légende et ajouté plt.show () afin que vous puissiez le coller dans le shell interactif et obtenir un résultat:
la source
La solution qui a fonctionné pour moi quand j'avais une énorme légende était d'utiliser une disposition d'image vide supplémentaire. Dans l'exemple suivant, j'ai fait 4 rangées et en bas, je trace l'image avec un décalage pour la légende (bbox_to_anchor) en haut, elle n'est pas coupée.
la source
Voici une autre solution, similaire à l'ajout
bbox_extra_artists
etbbox_inches
, où vous n'avez pas besoin d'avoir vos artistes supplémentaires dans le cadre de votresavefig
appel. Je suis venu avec cela depuis que je génère la plupart de mes fonctions intrigue à l'intérieur.Au lieu d'ajouter tous vos ajouts à la boîte englobante lorsque vous souhaitez l'écrire, vous pouvez les ajouter à l'avance aux
Figure
artistes de. En utilisant quelque chose de similaire à la réponse de Franck Dernoncourt ci - dessus :Voici l'intrigue générée.
la source
Je ne sais pas si vous avez déjà réglé votre problème ... probablement oui, mais ... j'ai simplement utilisé la chaîne "extérieur" pour l'emplacement, comme dans matlab. J'ai importé pylab de matplotlib. voir le code comme suit:
Cliquez pour voir l'intrigue
la source