J'ai un chiffre avec deux sous-intrigues en 2 lignes et 1 colonne. Je peux ajouter une légende de belle figure avec
fig.legend((l1, l2), ['2011', '2012'], loc="lower center",
ncol=2, fancybox=True, shadow=True, prop={'size':'small'})
Cependant, cette légende est positionnée au centre du figure et non en dessous du centre du axes comme je voudrais l'avoir. Maintenant, je peux obtenir mes coordonnées d'axes avec
axbox = ax[1].get_position()
et en théorie je devrais pouvoir positionner la légende en spécifiant le mot-clé loc avec un Tuple:
fig.legend(..., loc=(axbox.x0+0.5*axbox.width, axbox.y0-0.08), ...)
Cela fonctionne, sauf que la légende est alignée à gauche de sorte que loc spécifie le bord/coin gauche de la boîte de légende et non le centre. J'ai recherché des mots clés tels que align , alignement horizontal , etc., mais n'a pas pu en trouver. J'ai également essayé d'obtenir la "position de légende", mais la légende n'a pas de méthode * get_position () *. J'ai lu à propos de * bbox_to_anchor * mais je ne peux pas le comprendre lorsqu'il est appliqué à une légende de figure. Cela semble être fait pour les légendes des haches.
Ou: dois-je utiliser une légende d'axes décalés à la place? Mais alors, pourquoi y a-t-il des légendes des figures en premier lieu? Et d'une manière ou d'une autre, il doit être possible d'aligner au centre une légende de figure, car loc = "centre inférieur" le fait aussi.
Merci pour toute aide,
Martin
Dans ce cas, vous pouvez utiliser des axes pour les méthodes figure legend
. Dans tous les cas, bbox_to_anchor
C'est la clé. Comme vous l'avez déjà remarqué bbox_to_anchor
spécifie un tuple de coordonnées (ou une boîte) sur lequel placer la légende. Lorsque vous utilisez bbox_to_anchor
pensez au location
kwarg comme contrôlant l'alignement horizontal et vertical.
La différence est simplement de savoir si le tuple de coordonnées est interprété comme des axes ou des coordonnées de figures.
Comme exemple d'utilisation d'une légende de figure:
import numpy as np
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True)
x = np.linspace(0, np.pi, 100)
line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')
# The key to the position is bbox_to_anchor: Place it at x=0.5, y=0.5
# in figure coordinates.
# "center" is basically saying center horizontal alignment and
# center vertical alignment in this case
fig.legend([line1, line2], ['yep', 'nope'], bbox_to_anchor=[0.5, 0.5],
loc='center', ncol=2)
plt.show()
Comme exemple d'utilisation de la méthode des axes, essayez quelque chose comme ceci:
import numpy as np
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True)
x = np.linspace(0, np.pi, 100)
line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')
# The key to the position is bbox_to_anchor: Place it at x=0.5, y=0
# in axes coordinates.
# "upper center" is basically saying center horizontal alignment and
# top vertical alignment in this case
ax1.legend([line1, line2], ['yep', 'nope'], bbox_to_anchor=[0.5, 0],
loc='upper center', ncol=2, borderaxespad=0.25)
plt.show()
C'est une très bonne question et la réponse acceptée indique la clé (c'est-à-dire loc
désigne l'alignement et bbox_to_anchor
Indique la position). J'ai également essayé quelques codes et je voudrais souligner l'importance de la propriété bbox_transform
cela peut parfois être explicitement spécifié pour obtenir les effets souhaités. Ci-dessous, je vais vous montrer mes résultats sur fig.legend
. ax.legend
Devrait être très similaire à loc
et bbox_to_anchor
Fonctionne de la même manière.
Lorsque vous utilisez le paramètre par défaut, nous aurons les éléments suivants.
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6,4), sharex=True)
x = np.linspace(0, np.pi, 100)
line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')
fig.legend([line1, line2], ['yep', 'nope'], loc='lower center', ncol=2)
C'est fondamentalement satisfaisant. Mais il pourrait être facilement trouvé que la légende se superpose avec les graduations de l'axe des x de ax2
. C'est le problème qui deviendra encore plus grave lorsque figsize
et/ou dpi
de la figure change, voir ce qui suit.
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6,12), sharex=True, facecolor='w', gridspec_kw={'hspace':0.01})
x = np.linspace(0, np.pi, 100)
line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')
fig.legend([line1, line2], ['yep', 'nope'], loc='lower center', ncol=2)
Vous voyez donc qu'il y a de grands écarts entre ax2
Et la légende. Ce n'est pas ce que nous voulons. Comme le questionneur, nous aimerions contrôler manuellement l'emplacement de la légende. Tout d'abord, j'utiliserai le style à 2 chiffres de bbox_to_anchor
Comme l'a fait la réponse.
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6,12), sharex=True, facecolor='w', gridspec_kw={'hspace':0.01})
x = np.linspace(0, np.pi, 100)
line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')
axbox = ax2.get_position()
# to place center point of the legend specified by loc at the position specified by bbox_to_anchor.
fig.legend([line1, line2], ['yep', 'nope'], loc='center', ncol=2,
bbox_to_anchor=[axbox.x0+0.5*axbox.width, axbox.y0-0.05])
Presque là! Mais c'est totalement faux car le centre de la légende n'est pas au centre de ce que nous voulons vraiment dire! La clé pour résoudre ce problème est que nous devons informer explicitement le bbox_transform
En tant que fig.transFigure
. Par défaut None, la transformation transAxes des Axes sera utilisée . Ceci est compréhensible car la plupart du temps nous utiliserons ax.legend()
.
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6,12), sharex=True, facecolor='w', gridspec_kw={'hspace':0.01})
x = np.linspace(0, np.pi, 100)
line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')
axbox = ax2.get_position()
# to place center point of the legend specified by loc at the position specified by bbox_to_anchor!
fig.legend([line1, line2], ['yep', 'nope'], loc='center', ncol=2,
bbox_to_anchor=[axbox.x0+0.5*axbox.width, axbox.y0-0.05], bbox_transform=fig.transFigure)
Comme alternative, nous pouvons également utiliser un style à 4 chiffres bbox_to_anchor
Pour loc
. Il s'agit essentiellement de spécifier une vraie boîte pour la légende et loc
indique vraiment l'alignement! La valeur par défaut bbox_to_anchor
Devrait simplement être [0,0,1,1]
, Ce qui signifie la totalité de la boîte à chiffres! Les quatre nombres représentent respectivement x0,y0,width,height
. C'est très similaire à en spécifiant un cax pour une barre de couleurs partagée ! Par conséquent, vous pouvez facilement modifier le y0
Juste un peu plus bas que axbox.y0
Et ajuster loc
en conséquence.
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6,12), sharex=True, facecolor='w', gridspec_kw={'hspace':0.01})
x = np.linspace(0, np.pi, 100)
line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')
axbox = ax2.get_position()
# to place center point specified by loc at the position specified by bbox_to_anchor!
fig.legend([line1, line2], ['yep', 'nope'], loc='lower center', ncol=2,
bbox_to_anchor=[0, axbox.y0-0.05,1,1], bbox_transform=fig.transFigure)