Eu tenho jogado com Numpy e matplotlib nos últimos dias. Estou tendo problemas ao tentar fazer do matplotlib plot uma função sem bloquear a execução. Eu sei que já existem muitos tópicos aqui no SO, fazendo perguntas semelhantes, e eu pesquisei bastante no Google, mas não consegui fazer isso funcionar.
Eu tentei usar show (block = False) como algumas pessoas sugerem, mas tudo o que recebo é uma janela congelada. Se eu simplesmente chamar show (), o resultado será plotado corretamente, mas a execução será bloqueada até que a janela seja fechada. De outros tópicos que li, suspeito que o show (block = False) funcione ou não, dependendo do back-end. Isso está correto? Meu back-end é Qt4Agg. Você poderia dar uma olhada no meu código e me dizer se vê algo errado? Aqui está o meu código. Obrigado por qualquer ajuda.
from math import *
from matplotlib import pyplot as plt
print plt.get_backend()
def main():
x = range(-50, 51, 1)
for pow in range(1,5): # plot x^1, x^2, ..., x^4
y = [Xi**pow for Xi in x]
print y
plt.plot(x, y)
plt.draw()
#plt.show() #this plots correctly, but blocks execution.
plt.show(block=False) #this creates an empty frozen window.
_ = raw_input("Press [enter] to continue.")
if __name__ == '__main__':
main()
PS. Esqueci de dizer que gostaria de atualizar a janela existente toda vez que plotar algo, em vez de criar uma nova.
fonte
plt.ion()
antesplt.show()
? Em seguida, deve ser sem bloqueio, pois cada plot é gerado em um thread filho.matplotlib
.Respostas:
Passei muito tempo procurando soluções e encontrei esta resposta .
Parece que, a fim de obter o que você (e eu) quer, você precisa a combinação de
plt.ion()
,plt.show()
(não comblock=False
) e, mais importante,plt.pause(.001)
(ou o tempo que você quiser). A pausa é necessária porque os eventos da GUI acontecem enquanto o código principal está em suspensão, incluindo o desenho. É possível que isso seja implementado com a obtenção de tempo em um encadeamento adormecido, então talvez os IDEs mexam com isso - eu não sei.Aqui está uma implementação que funciona para mim no python 3.5:
fonte
plt.draw
segui,plt.show(block = False)
mas ele parou de funcionar: a figura não respondeu, fechando-o travou o iPython. Minha solução foi remover todas as instânciasplt.draw()
e substituí-las porplt.pause(0.001)
. Em vez de tê-lo seguido deplt.show(block = False)
comoplt.draw
era antes, foi precedido porplt.ion()
eplt.show()
. Agora tenho um,MatplotlibDeprecationWarning
mas deixe-me traçar meus números, por isso estou feliz com esta solução.raw_input
nãoinput
. Veja aquiUm truque simples que funciona para mim é o seguinte:
Exemplo :
Nota :
plt.show()
é a última linha do meu script.fonte
Você pode evitar o bloqueio da execução gravando o gráfico em uma matriz e exibindo a matriz em um encadeamento diferente. Aqui está um exemplo de geração e exibição de gráficos simultaneamente usando pf.screen a partir de pyformulas 0.2.8 :
Resultado:
Disclaimer: Eu sou o mantenedor de pyformulas.
Referência: Matplotlib: salvar plot para numpy array
fonte
Muitas dessas respostas são superinfladas e, pelo que pude encontrar, a resposta não é tão difícil de entender.
Você pode usar
plt.ion()
se quiser, mas eu achei o usoplt.draw()
tão eficazPara o meu projeto específico, estou plotando imagens, mas você pode usar
plot()
ou o quescatter()
quer que sejafigimage()
, não importa.Ou
Se você estiver usando uma figura real.
Eu usei o @ krs013 e as respostas do @Default Picture para descobrir isso.
Espero que isso evite que alguém lance cada figura em um tópico separado ou que precise ler esses romances apenas para descobrir isso.
fonte
Plotagem ao vivo
se a quantidade de dados for demais, você pode diminuir a taxa de atualização com um contador simples
Retendo a plotagem após a saída do programa
Esse era o meu problema real que não conseguia encontrar uma resposta satisfatória. Queria traçar que não fechasse após a conclusão do script (como MATLAB),
Se você pensar bem, depois que o script terminar, o programa será encerrado e não haverá uma maneira lógica de manter o gráfico dessa maneira, portanto, existem duas opções
isso não foi satisfatório para mim, então encontrei outra solução fora da caixa
SaveToFile e View no visualizador externo
Para isso, o salvamento e a visualização devem ser rápidos e o visualizador não deve bloquear o arquivo e atualizar o conteúdo automaticamente
Selecionando o formato para salvar
formatos baseados em vetor são pequenos e rápidos
Visualizador leve e rápido com atualização ao vivo
Para PDF, existem várias boas opções
No Windows, uso o SumatraPDF , gratuito, rápido e leve (usa apenas 1,8 MB de RAM no meu caso)
No Linux, existem várias opções, como Evince (GNOME) e Ocular (KDE)
Código de exemplo e resultados
Código de amostra para saída da plotagem em um arquivo
após a primeira execução, abra o arquivo de saída em um dos visualizadores mencionados acima e aproveite.
Aqui está uma captura de tela do VSCode ao lado do SumatraPDF, também o processo é rápido o suficiente para obter uma taxa de atualização semi-ao vivo (posso chegar perto de 10Hz na minha configuração, basta usar
time.sleep()
entre intervalos)fonte
A resposta de Iggy foi a mais fácil para eu seguir, mas recebi o seguinte erro ao executar um
subplot
comando subseqüente que não estava lá quando eu estava apenas fazendoshow
:Para evitar esse erro, ajuda a fechar (ou limpar ) a plotagem depois que o usuário pressiona enter.
Aqui está o código que funcionou para mim:
fonte
O pacote Python drawow permite atualizar um gráfico em tempo real de maneira não-bloqueadora.
Também funciona com uma webcam e OpenCV, por exemplo, para traçar medidas para cada quadro.
Veja a postagem original .
fonte