Estou plotando o mesmo tipo de informação, mas para países diferentes, com várias subparcelas com matplotlib. Ou seja, tenho 9 gráficos em uma grade 3x3, todos iguais para linhas (é claro, valores diferentes por linha).
No entanto, eu não descobri como colocar uma única legenda (uma vez que todas as 9 subparcelas têm as mesmas linhas) na figura apenas uma vez.
Como faço isso?
python
matplotlib
pocketfullofcheese
fonte
fonte
handles, labels = [(a + b) for a, b in zip(ax1.get_legend_handles_labels(), ax2.get_legend_handles_labels())]
figlegend pode ser o que você está procurando: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.figlegend
Exemplo aqui: http://matplotlib.org/examples/pylab_examples/figlegend_demo.html
Outro exemplo:
ou:
fonte
lines
variável para colocar no argumentolegend
?lines
é uma lista de resultados retornadosaxes.plot()
(por exemplo, cadaaxes.plot
rotina semelhante ou semelhante retorna uma "linha"). Veja também o exemplo vinculado.Para o posicionamento automático de uma única legenda em um
figure
com muitos eixos, como os obtidos comsubplots()
, a seguinte solução funciona muito bem:Com
bbox_to_anchor
ebbox_transform=plt.gcf().transFigure
você está definindo uma nova caixa delimitadora do tamanho do seufigure
para ser uma referêncialoc
. O uso(0,-0.1,1,1)
move esta caixa de empacotamento levemente para baixo para impedir que a legenda seja colocada sobre outros artistas.OBS: use esta solução DEPOIS de usar
fig.set_size_inches()
e ANTES de usarfig.tight_layout()
fonte
loc='upper center', bbox_to_anchor=(0.5, 0), bbox_transform=plt.gcf().transFigure
e não se sobrepõe com certeza.Você só precisa pedir a legenda uma vez, fora do seu loop.
Por exemplo, neste caso, tenho 4 subparcelas, com as mesmas linhas e uma única legenda.
fonte
figlegend
, Como sugerido por Evert, parece ser uma solução muito melhor;)fig.legend()
é que ele requer identificação para todas as linhas (plotagens) ... como, para cada subtrama, estou usando um loop para gerar as linhas, a única solução que descobri para superar isso é criar uma lista vazia antes o segundo loop e, em seguida, acrescente as linhas à medida que elas estão sendo criadas ... Então eu uso essa lista como argumento para afig.legend()
função.dados
ai?dados
havia um conjunto de dados de um arquivo netCDF4 (para cada um dos arquivos definidos na listaficheiros
). Em cada loop, um arquivo diferente é lido e uma subparcela é adicionada à figura.Notei que nenhuma resposta exibe uma imagem com uma única legenda referenciando muitas curvas em diferentes subparcelas, por isso tenho que mostrar uma ... para deixar você curioso ...
Agora, você quer ver o código, não é?
As duas linhas
merecem uma explicação - para esse objetivo, encapsulei a parte complicada de uma função, apenas 4 linhas de código, mas muito comentadas
PS Eu reconheço que
sum(list_of_lists, [])
é um método realmente ineficiente para achatar uma lista de listas, mas eu amo sua compactação, geralmente há algumas curvas em algumas subparcelas e Matplotlib e eficiência? ;-)fonte
Embora seja um pouco tarde para o jogo, darei outra solução aqui, pois esse ainda é um dos primeiros links para aparecer no google. Usando o matplotlib 2.2.2, isso pode ser alcançado usando o recurso gridspec. No exemplo abaixo, o objetivo é ter quatro subparcelas organizadas de forma 2x2 com a legenda mostrada na parte inferior. Um eixo 'falso' é criado na parte inferior para colocar a legenda em um ponto fixo. O eixo 'falso' é desativado para que apenas a legenda seja exibida. Resultado: https://i.stack.imgur.com/5LUWM.png .
fonte
se você estiver usando subtramas com gráficos de barras, com cores diferentes para cada barra. pode ser mais rápido criar você mesmo os artefatos usando
mpatches
Digamos que você tenha quatro barras com cores diferentes, pois
r
m
c
k
você pode definir a legenda da seguinte maneirafonte
plt.legend
ter uma legenda para todas as minhas subparcelas #handles, _ = plt.gca().get_legend_handles_labels()
fig.legend(handles, labels)
Esta resposta é um complemento para o @ Evert na posição da legenda.
Minha primeira tentativa na solução do @ Evert falhou devido a sobreposições da legenda e do título da subtrama.
De fato, as sobreposições são causadas por
fig.tight_layout()
, o que altera o layout das subparcelas sem considerar a legenda da figura. No entanto,fig.tight_layout()
é necessário.Para evitar sobreposições, podemos dizer
fig.tight_layout()
para deixar espaços para a legenda da figurafig.tight_layout(rect=(0,0,1,0.9))
.Descrição dos parâmetros tight_layout () .
fonte
Para aproveitar as respostas de @ gboffi e Ben Usman:
Em uma situação em que se tem linhas diferentes em subparcelas diferentes com a mesma cor e rótulo, pode-se fazer algo ao longo das linhas de
fonte