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:

Como Tirar A Lenda do enredo

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)

enter image description here

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?

Author: mzzx, 2017-06-07

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".

enter image description here

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.

 17
Author: ImportanceOfBeingErnest, 2017-06-07 14:48:14

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()
 2
Author: Drahoš Maďar, 2017-06-07 13:28:43