La légende de Python chevauche le diagramme à secteurs

utilisant matplotlib en python. La légende chevauche mon diagramme à secteurs. Essayé diverses options pour "loc", comme "meilleur" ,1,2,3... mais en vain. Des Suggestions quant à la façon de mentionner exactement la position de la légende (par exemple, en donnant un rembourrage à partir des limites du diagramme à secteurs) ou au moins s'assurer qu'elle ne se chevauche pas?

9
demandé sur cassandra 2017-04-07 10:30:39

1 réponses

la réponse courte est: vous pouvez utiliser plt.legend 's arguments loc , bbox_to_anchor et en outre bbox_transform et mode , pour positionner la légende dans un axe ou une figure.


La version longue:

Étape 1: s'assurer qu'une légende est nécessaire.

dans de nombreux cas, aucune légende n'est nécessaire et l'information peut être déduite par le contexte ou la couleur directement:

enter image description here

enter image description here

si l'intrigue ne peut vivre sans légende, passez à l'étape 2.

Étape 2: s'assurer qu'un diagramme à secteurs est nécessaire.

dans de nombreux cas, les diagrammes circulaires ne sont pas la meilleure façon de transmettre l'information.

enter image description here

si le besoin d'un diagramme à secteurs est déterminé sans ambiguïté, procédons à placer la légende.

placer la légende

plt.legend() a deux arguments principaux pour déterminer la position de la légende. Le plus important et suffisant en soi est l'argument loc .

Par exemple: plt.legend(loc="upper left") placé la légende telle qu'elle se trouve dans le coin supérieur gauche de sa boite. Si aucun argument supplémentaire n'est spécifié, cette zone de limitation sera les axes entiers.

Cependant, nous pouvons spécifier notre propre zone limitative en utilisant l'argument bbox_to_anchor . Si bbox_to_anchor est donné un 2-tuple par exemple bbox_to_anchor=(1,1) cela signifie que la boîte de limite est située au coin supérieur droit des axes et n'a aucune étendue. Il agit alors comme un point relatif auquel la légende sera placée selon l'argument loc . Il se développera ensuite hors de la zone de limite de taille zéro. Par exemple: si loc est "upper left" , le coin supérieur gauche de la légende est à la position (1,1) et la légende s'étendra vers la droite et vers le bas.

ce concept est utilisé pour le complot ci-dessus, qui nous dit la vérité choquante sur le parti pris dans les élections Miss Univers.

import matplotlib.pyplot as plt
import matplotlib.patches

total = [100]
labels = ["Earth", "Mercury", "Venus", "Mars", "Jupiter",  "Saturn", 
           "Uranus", "Neptune", "Pluto *"]
plt.title('Origin of Miss Universe since 1952')
plt.gca().axis("equal")
pie = plt.pie(total, startangle=90, colors=[plt.cm.Set3(0)],
                            wedgeprops = { 'linewidth': 2, "edgecolor" :"k" })
handles = []
for i, l in enumerate(labels):
    handles.append(matplotlib.patches.Patch(color=plt.cm.Set3((i)/8.), label=l))
plt.legend(handles,labels, bbox_to_anchor=(0.85,1.025), loc="upper left")
plt.gcf().text(0.93,0.04,"* out of competition since 2006", ha="right")
plt.subplots_adjust(left=0.1, bottom=0.1, right=0.75)

pour que la légende ne dépasse pas la figure, nous utilisons plt.subplots_adjust pour obtenir plus d'espace entre le bord de la figure et l'axe, qui peuvent ensuite être repris par la légende.

il y a aussi la possibilité d'utiliser un 4-tuple à bbox_to_anchor . Comment utiliser ou interpréter ceci est détaillé dans cette question: que signifie un argument tuple à 4 éléments pour 'bbox_to_anchor' dans matplotlib?

et on peut alors utiliser l'argument mode="expand" pour faire entrer la légende dans la zone de délimitation spécifiée.

Il y certaines des solutions de rechange utiles à cette approche:

utilisant les coordonnées de la figure

au lieu de spécifier la position de la légende dans les coordonnées des axes, on peut utiliser les coordonnées des figures. L'avantage est que cela va permettre de placer simplement la légende dans un coin de la figure sans modifier le reste. À cette fin, on utiliserait l'argument bbox_transform et on lui fournirait la transformation de la figure. Les coordonnées données à bbox_to_anchor sont alors interprété comme des coordonnées de figure.

plt.legend(pie[0],labels, bbox_to_anchor=(1,0), loc="lower right", 
                          bbox_transform=plt.gcf().transFigure)

Ici (1,0) est le coin inférieur droit de la figure. En raison de l'espacement par défaut entre les axes et le bord de la figure, cela suffit pour placer la légende de sorte qu'elle ne se chevauche pas avec le gâteau.

enter image description here

dans d'autres cas, il peut encore être nécessaire d'adapter ces espaces de manière à éviter tout chevauchement, par exemple:

title = plt.title('What slows down my computer')
title.set_ha("left")
plt.gca().axis("equal")
pie = plt.pie(total, startangle=0)
labels=["Trojans", "Viruses", "Too many open tabs", "The anti-virus software"]
plt.legend(pie[0],labels, bbox_to_anchor=(1,0.5), loc="center right", fontsize=10, 
           bbox_transform=plt.gcf().transFigure)
plt.subplots_adjust(left=0.0, bottom=0.1, right=0.45)

enter image description here

sauvegarder le fichier avec bbox_inches="tight"

maintenant, il peut y avoir des cas où nous sommes plus intéressés par la figure sauvegardée que par ce qui est affiché à l'écran. Nous pouvons alors simplement placer la légende au bord de la figure, comme si

enter image description here

mais alors sauvegardez-le en utilisant le bbox_inches="tight" à savefig ,

plt.savefig("output.png", bbox_inches="tight")

cela va créer une plus grande figure, qui se trouve serré autour du contenu de la toile:

enter image description here

une approche sophistiquée, qui permet de placer la légende étroitement à l'intérieur de la figure, sans changer la taille de la figure est présentée ici: créer figure avec la taille exacte et pas de rembourrage (et la légende en dehors des axes)

À L'Aide Des Sous-Parcelles

une alternative est d'utiliser des sous-lots pour réserver l'espace pour la légende. Dans ce cas, une intrigue secondaire pourrait prendre le camembert, une autre intrigue secondaire contient la légende. Ceci est illustré ci-dessous.

fig = plt.figure(4, figsize=(3,3))
ax = fig.add_subplot(211) 
total = [4,3,2,81]
labels = ["tough working conditions", "high risk of accident", 
              "harsh weather", "it's not allowed to watch DVDs"]
ax.set_title('What people know about oil rigs')
ax.axis("equal")
pie = ax.pie(total, startangle=0)
ax2 = fig.add_subplot(212)
ax2.axis("off") 
ax2.legend(pie[0],labels, loc="center")

enter image description here

31
répondu ImportanceOfBeingErnest 2017-05-23 11:55:07