Como especificar a posição da legenda em matplotlib nas coordenadas do grafo
Estou ciente da palavra-chave bbox_ to_ Anchor e deste tópico, que muito Ajuda sugere como colocar manualmente a legenda:
No entanto, gostaria de usar as coordenadas do meu eixo x e y no gráfico para especificar a posição da legenda (dentro do gráfico), dado que posso precisar de mover a figura para uma figura grande com um ambiente de eixo diferente, e não quero brincar manualmente com essas coordenadas sempre que eu fazer. Isto é possível?
editar: um pequeno exemplo está aqui:
import numpy as n
f, axarr = plt.subplots(2,sharex=True)
axarr[1].set_ylim([0.611,0.675])
axarr[0].set_ylim([0.792,0.856])
axarr[0].plot([0, 0.04, 0.08],n.array([ 0.83333333, 0.82250521,0.81109048]), label='test1')
axarr[0].errorbar([0, 0.04, 0.08],n.array([ 0.8, 0.83, 0.82]),n.array([0.1,0.1,0.01]), label='test2')
axarr[1].plot([0, 0.04, 0.08],n.array([ 0.66666667, 0.64888304, 0.63042428]))
axarr[1].errorbar([0, 0.04, 0.08],n.array([ 0.67, 0.64, 0.62]),n.array([ 0.01, 0.05, 0.1]))
axarr[0].legend(bbox_to_anchor=(0.04, 0.82, 1., .102),labelspacing=0.1, handlelength=0.1, handletextpad=0.1,frameon=False, ncol=4, columnspacing=0.7)
eu acho que o que me confunde é que a legenda não realmente começam em 0.82, e na verdade o meu maior parcela (com 5 subparcelas deste tipo), eu preciso usar lenda coordenadas bbox_to_anchor=(0.04, 1.15, 1., .102) para que a legenda apareça nas coordenadas (0.02, 0.83). Mas talvez esteja a perceber algo de errado?
2 answers
O parâmetro loc
especifica em que Canto da caixa envolvente é colocada a legenda. O valor por omissão para loc
é loc="best"
o que dá resultados imprevisíveis quando o argumento bbox_to_anchor
é usado.
Por conseguinte, ao especificar bbox_to_anchor
, Sempre especifique loc
também.
O valor por omissão para bbox_to_anchor
é (0,0,1,1)
, que é uma caixa delimitadora sobre os eixos completos. Se for especificada uma caixa envolvente diferente, esta é normalmente suficiente para utilizar os dois primeiros valores, que dão (x0, y0) caixa envolvente.
Abaixo está um exemplo em que a caixa envolvente é colocada na posição (0.6,0.5)
(ponto verde) e são ensaiados diferentes parâmetros loc
. Uma vez que a legenda existe fora da caixa envolvente, o parâmetro loc
pode ser interpretado como "qual o canto da legenda deve ser colocado na posição dada pelo argumento bbox_to_anchor 2-tuple".
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = 6, 3
fig, axes = plt.subplots(ncols=3)
locs = ["upper left", "lower left", "center right"]
for l, ax in zip(locs, axes.flatten()):
ax.set_title(l)
ax.plot([1,2,3],[2,3,1], "b-", label="blue")
ax.plot([1,2,3],[1,2,1], "r-", label="red")
ax.legend(loc=l, bbox_to_anchor=(0.6,0.5))
ax.scatter((0.6),(0.5), s=81, c="limegreen", transform=ax.transAxes)
plt.tight_layout()
plt.show()
Ver especialmente esta resposta {[28] } para uma explicação detalhada e a pergunta O Que um argumento duplo de 4 elementos para "bbox_to_ Anchor" significa em matplotlib? .
Se quiser indicar a posição da legenda noutras coordenadas que não as coordenadas dos eixos, poderá fazê-lo usando o argumento
bbox_transform
. Se puder fazer sentido usar as coordenadas da figura
ax.legend(bbox_to_anchor=(1,0), loc="lower right", bbox_transform=fig.transFigure)
Pode não fazer muito sentido usar coordenadas de dados, mas como você pediu isso seria feito via bbox_transform=ax.transData
.
Poderá alterar a localização da legenda usando o argumento loc. https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.legend
import matplotlib.pyplot as plt
plt.subplot(211)
plt.plot([1,2,3], label="test1")
plt.plot([3,2,1], label="test2")
# Place a legend above this subplot, expanding itself to
# fully use the given bounding box.
plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
ncol=2, mode="expand", borderaxespad=0.)
plt.subplot(223)
plt.plot([1,2,3], label="test1")
plt.plot([3,2,1], label="test2")
# Place a legend to the right of this smaller subplot.
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
plt.show()