Utilisation de matplotlib en python. La légende chevauche mon graphique à secteurs. J'ai essayé diverses options pour "loc" telles que "best", 1,2,3 ... mais en vain. Avez-vous des suggestions sur la façon de mentionner exactement la position de la légende (comme donner un remplissage à partir des limites du graphique à secteurs) ou au moins de vous assurer qu'elle ne se chevauche pas?
La réponse courte est: vous pouvez utiliser les arguments de plt.legend
loc
, bbox_to_anchor
Et en plus bbox_transform
Et mode
, pour positionner la légende dans un axe ou une figure.
Dans de nombreux cas, aucune légende n'est nécessaire et les informations peuvent être déduites directement du contexte ou de la couleur:
Si en effet l'intrigue ne peut pas vivre sans légende, passez à l'étape 2.
Dans de nombreux cas, les graphiques circulaires ne sont pas le meilleur moyen de transmettre des informations.
Si la nécessité d'un graphique à secteurs est déterminée sans ambiguïté, passons à la légende.
plt.legend()
a deux arguments principaux pour déterminer la position de la légende. L'argument loc
est le plus important et en lui-même suffisant.
Par exemple. plt.legend(loc="upper left")
a placé la légende de telle sorte qu'elle se trouve dans le coin supérieur gauche de son cadre de sélection. Si aucun autre argument n'est spécifié, ce cadre de sélection sera l'ensemble des axes.
Cependant, nous pouvons spécifier notre propre boîte englobante en utilisant l'argument bbox_to_anchor
. Si bbox_to_anchor
Reçoit un 2-Tuple par ex. bbox_to_anchor=(1,1)
cela signifie que le cadre de sélection est situé dans le coin supérieur droit des axes et n'a aucune étendue. Il agit alors comme un point par rapport auquel la légende sera placée selon l'argument loc
. Il se développera ensuite hors de la zone de délimitation de taille nulle. Par exemple. si loc
est "upper left"
, le coin supérieur gauche de la légende est en position (1,1) et la légende s'étendra vers la droite et vers le bas.
Ce concept est utilisé pour l'intrigue ci-dessus, qui nous dit la vérité choquante sur le parti pris dans les élections de 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)
Afin que la légende ne dépasse pas le chiffre, nous utilisons plt.subplots_adjust
Pour obtenir plus d'espace entre le bord de la figure et l'axe, qui peut ensuite être occupé par la légende.
Il y a aussi la possibilité d'utiliser un 4-Tuple pour bbox_to_anchor
. Comment utiliser ou interpréter cela est détaillé dans cette question: Que signifie un argument Tuple à 4 éléments pour 'bbox_to_anchor' dans matplotlib?
et on peut ensuite utiliser l'argument mode="expand"
pour que la légende tienne dans le cadre de délimitation spécifié.
Il existe des alternatives utiles à cette approche:
Au lieu de spécifier la position de la légende en coordonnées d'axe, on peut utiliser des coordonnées de figure. L'avantage est que cela permettra de placer simplement la légende dans un coin de la figure sans ajuster une grande partie du reste. À cette fin, on utiliserait l'argument bbox_transform
Et lui fournirait la transformation de la figure. Les coordonnées données à bbox_to_anchor
Sont alors interprétées 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 des espacements par défaut entre les axes et la figure Edge, cela suffit pour placer la légende de sorte qu'elle ne chevauche pas le graphique.
Dans d'autres cas, il peut être nécessaire d'adapter ces espacements de sorte qu'aucun chevauchement ne soit observé, par ex.
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)
bbox_inches="tight"
Maintenant, il peut y avoir des cas où nous sommes plus intéressés par le chiffre enregistré que par ce qui est affiché à l'écran. On peut alors simplement positionner la légende au bord de la figure, comme ça
mais enregistrez-le en utilisant le bbox_inches="tight"
dans savefig
,
plt.savefig("output.png", bbox_inches="tight")
Cela créera une figure plus grande, qui se tient bien autour du contenu de la toile:
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éation d'une figure avec une taille exacte et sans rembourrage (et légende en dehors des axes)
Une alternative consiste à utiliser des sous-tracés pour réserver de l'espace pour la légende. Dans ce cas, une sous-intrigue pourrait prendre le graphique à secteurs, une autre sous-intrigue contiendrait 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")