Estou familiarizado com as seguintes perguntas:
Matplotlib savefig com uma legenda fora da plotagem
Como colocar a lenda fora da trama
Parece que as respostas nessas perguntas têm o luxo de poder mexer com o encolhimento exato do eixo, para que a legenda se encaixe.
Diminuir os eixos, no entanto, não é uma solução ideal, pois diminui os dados, dificultando a interpretação; particularmente quando é complexo e há muitas coisas acontecendo ... portanto, precisamos de uma grande lenda
O exemplo de uma legenda complexa na documentação demonstra a necessidade disso, porque a legenda em sua plotagem na verdade obscurece completamente vários pontos de dados.
http://matplotlib.sourceforge.net/users/legend_guide.html#legend-of-complex-plots
O que eu gostaria de poder fazer é expandir dinamicamente o tamanho da caixa de figuras para acomodar a legenda da figura em expansão.
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-2*np.pi, 2*np.pi, 0.1)
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(x, np.sin(x), label='Sine')
ax.plot(x, np.cos(x), label='Cosine')
ax.plot(x, np.arctan(x), label='Inverse tan')
lgd = ax.legend(loc=9, bbox_to_anchor=(0.5,0))
ax.grid('on')
Observe como o rótulo final 'bronzeado inverso' está realmente fora da caixa de figuras (e parece muito ruim - não qualidade de publicação!)
Finalmente, me disseram que esse é um comportamento normal no R e no LaTeX, então estou um pouco confuso por que isso é tão difícil em python ... Existe uma razão histórica? O Matlab é igualmente pobre nesse assunto?
Eu tenho a versão (apenas um pouco) mais longa desse código em pastebin http://pastebin.com/grVjc007
fonte
tight_layout()
deve ser alterado para levar em consideração as lendas.Respostas:
Desculpe o EMS, mas na verdade recebi outra resposta da lista de emails matplotlib (Agradecemos a Benjamin Root).
O código que estou procurando é ajustar a chamada savefig para:
Aparentemente, isso é semelhante a chamar tight_layout, mas você permite que o savefig considere artistas extras no cálculo. Na verdade, isso redimensionou a caixa de figuras conforme desejado.
Isso produz:
[editar] O objetivo desta pergunta era evitar completamente o uso de posicionamentos arbitrários de coordenadas de texto arbitrário, como era a solução tradicional para esses problemas. Apesar disso, várias edições recentemente insistiram em inseri-las, geralmente de maneiras que levaram o código a gerar um erro. Corrigi os problemas e arrumei o texto arbitrário para mostrar como eles também são considerados no algoritmo bbox_extra_artists.
fonte
plt.show()
. Alguma correção para isso?fig.legend()
método , muito estranho.Adicionado: Encontrei algo que deve resolver o problema imediatamente, mas o restante do código abaixo também oferece uma alternativa.
Use a
subplots_adjust()
função para mover a parte inferior da subparcela para cima:Em seguida, brinque com o deslocamento na
bbox_to_anchor
parte da legenda do comando legend, para obter a caixa de legenda onde desejar. Alguma combinação de definirfigsize
e usar osubplots_adjust(bottom=...)
deve produzir um gráfico de qualidade para você.Alternativo: eu simplesmente mudei a linha:
para:
e mudou
para
e aparece bem na minha tela (um monitor CRT de 24 polegadas).
Aqui
figsize=(M,N)
define a janela da figura como M polegadas por N polegadas. Apenas brinque com isso até parecer certo para você. Converta-o para um formato de imagem mais escalável e use o GIMP para editar, se necessário, ou apenas recorte com aviewport
opção LaTeX ao incluir gráficos.fonte
Aqui está outra solução muito manual. Você pode definir o tamanho do eixo e os paddings são considerados adequadamente (incluindo legenda e marcas de escala). Espero que seja útil para alguém.
Exemplo (o tamanho dos eixos é o mesmo!):
Código:
fonte
plt.draw()
paraax.figure.canvas.draw()
. Não sei por que, mas antes dessa alteração, o tamanho da legenda não era atualizado.fig.set_size_inches(widthTot,heightTot)
parafig.set_size_inches(widthTot,heightTot, forward=True)
.