Chamando pylab.savefig sem exibição em ipython

111

Preciso criar uma figura em um arquivo sem exibi-la no notebook IPython. Não estou claro sobre a interação entre IPythone a matplotlib.pylabesse respeito. Mas, quando ligo, pylab.savefig("test.png")o valor atual é exibido, além de ser salvo em test.png. Ao automatizar a criação de um grande conjunto de arquivos de plotagem, isso geralmente é indesejável. Ou na situação em que um arquivo intermediário para processamento externo por outro aplicativo seja desejado.

Não tenho certeza se esta é uma pergunta do matplotlibou do IPythoncaderno.

tnt
fonte
A resposta de @staticfloat funcionou para mim mesmo quando não estava em um notebook e ao usar matplotlib por meio de JuliaLang; usandoioff
Vass

Respostas:

173

Esta é uma questão matplotlib, e você pode contornar isso usando um back-end que não é exibido para o usuário, por exemplo, 'Agg':

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

plt.plot([1,2,3])
plt.savefig('/tmp/test.png')

EDITAR: Se você não quiser perder a capacidade de exibir gráficos, desative o modo interativo e só chame plt.show()quando estiver pronto para exibir os gráficos:

import matplotlib.pyplot as plt

# Turn interactive plotting off
plt.ioff()

# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('/tmp/test0.png')
plt.close(fig)

# Create a new figure, plot into it, then don't close it so it does get displayed
plt.figure()
plt.plot([1,3,2])
plt.savefig('/tmp/test1.png')

# Display all "open" (non-closed) figures
plt.show()
flutuação estática
fonte
2
Ok - mas, geralmente, quero manter a plotagem embutida no iPython. O que você sugere funciona bem se você fizer uma mudança completa no back-end. A questão é como você permite a situação geral de plotagem em linha com o caso excepcional de salvar números (sem mostrar em linha). Com sua sugestão, tentei recarregar os módulos e alterar o back-end temporariamente, mas sem sucesso. Alguma ideia sobre como alterar temporariamente o back-end em uma sessão de notebook do iPython?
tnt
1
Eu atualizei a questão para falar sobre plotagem interativa e os comandos close()e show(), que devem resolver seu problema. alterar back-ends em tempo real não é suportado, como você descobriu.
staticfloat
3
Obrigado pelo excelente feedback. Parece que o plt.close (fig.) É o comando-chave para minha necessidade. Ainda não estou certo sobre o ioff, pois não parece afetar a operação; mas, provavelmente estou faltando alguma coisa. Obrigado novamente.
tnt
1
A receita que dei é geral; se você não estiver trabalhando no notebook ipython, plt.ioff () é importante para impedir que as figuras pisquem dentro e fora da tela, já que na linha de comando as figuras do ipython são plotadas assim que você chama plt.plot()se o modo interativo estiver ativado . Desligar o modo interativo atrasa a exibição de qualquer plotagem até plt.show(). Como você está usando o notebook ipython, o modo interativo é tratado de maneira diferente.
staticfloat 01 de
Para mim, matplotlib.use('Agg')sozinha fez o truque. Eu não precisava de qualquer plt.show()ou plt.ioff()no meu código em tudo.
Zhanwen Chen
67

Não precisamos plt.ioff()ou plt.show()(se usarmos %matplotlib inline). Você pode testar o código acima sem plt.ioff(). plt.close()tem o papel essencial. Tente este:

%matplotlib inline
import pylab as plt

# It doesn't matter you add line below. You can even replace it by 'plt.ion()', but you will see no changes.
## plt.ioff()

# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('test0.png')
plt.close(fig)

# Create a new figure, plot into it, then don't close it so it does get displayed
fig2 = plt.figure()
plt.plot([1,3,2])
plt.savefig('test1.png')

Se você executar este código no iPython, ele exibirá um segundo gráfico e, se você adicionar plt.close(fig2)ao final dele, não verá nada.

Em conclusão, se você fechar a figura plt.close(fig), ela não será exibida.

Mojtaba Khodadadi
fonte
5
Melhor solução de fato! Eu gero e salvo muitos gráficos em um loop. Com plt.ioffeu entendo RuntimeWarning: More than 20 figures have been opened.... plt.closeResolvi-o.
Nagasaki45