Estou tendo problemas para redesenhar a figura aqui. Permito que o usuário especifique as unidades na escala de tempo (eixo x) e depois recalculo e chamo essa função plots()
. Quero que a trama simplesmente atualize, não acrescente outra trama à figura.
def plots():
global vlgaBuffSorted
cntr()
result = collections.defaultdict(list)
for d in vlgaBuffSorted:
result[d['event']].append(d)
result_list = result.values()
f = Figure()
graph1 = f.add_subplot(211)
graph2 = f.add_subplot(212,sharex=graph1)
for item in result_list:
tL = []
vgsL = []
vdsL = []
isubL = []
for dict in item:
tL.append(dict['time'])
vgsL.append(dict['vgs'])
vdsL.append(dict['vds'])
isubL.append(dict['isub'])
graph1.plot(tL,vdsL,'bo',label='a')
graph1.plot(tL,vgsL,'rp',label='b')
graph2.plot(tL,isubL,'b-',label='c')
plotCanvas = FigureCanvasTkAgg(f, pltFrame)
toolbar = NavigationToolbar2TkAgg(plotCanvas, pltFrame)
toolbar.pack(side=BOTTOM)
plotCanvas.get_tk_widget().pack(side=TOP)
python
matplotlib
tkinter
o apelido
fonte
fonte
Respostas:
Você tem essencialmente duas opções:
Faça exatamente o que está fazendo no momento, mas ligue
graph1.clear()
egraph2.clear()
antes de substituir os dados. Essa é a opção mais lenta, porém mais simples e mais robusta.Em vez de substituir novamente, você pode apenas atualizar os dados dos objetos de plotagem. Você precisará fazer algumas alterações no seu código, mas isso deve ser muito, muito mais rápido do que substituir sempre as coisas. No entanto, a forma dos dados que você está plotando não pode mudar e, se o intervalo dos dados estiver mudando, você precisará redefinir manualmente os limites dos eixos xey.
Para dar um exemplo da segunda opção:
fonte
clear
? Você deve ser chamadograph1.clear(); graph2.clear()
dentro de seufor
loop, apenas antes de chamargraph1.plot(...)
,graph2.plot(...)
etc ...fig.canvas.draw()
ouplt.draw()
depois de plotar cada quadro? (Ou seja, você deve ter uma sequência declear
,plot
,draw
cada vez que você quiser mostrar um frame) Eu estou supondo, mas acho que poderia causar exatamente o comportamento que você está descrevendo ... Boa sorte, de qualquer forma!Você também pode fazer o seguinte: Isso desenhará uma matriz aleatória de 10x1 no gráfico para 50 ciclos do loop for.
fonte
%matplotlib inline
no caderno Jupyter.plt.clf()
. Ohmatplotlib
, você Rascal :)Isso funcionou para mim. Chama repetidamente uma função que atualiza o gráfico sempre.
"diversão" é uma função que retorna um número inteiro. O FuncAnimation chamará repetidamente "update", fará isso vezes "xmax".
fonte
Caso alguém se depare com este artigo procurando o que eu estava procurando, encontrei exemplos em
Como visualizar dados 2D escalares com o Matplotlib?
e
http://mri.brechmos.org/2009/07/automatically-update-a-figure-in-a-loop (em web.archive.org)
depois os modificou para usar imshow com uma pilha de quadros de entrada, em vez de gerar e usar contornos em tempo real.
Começando com uma matriz 3D de imagens de forma (nBins, nBins, nBins), chamadas
frames
.Também achei uma maneira muito mais simples de executar todo esse processo, embora menos robusto:
Note que ambos parecem funcionar
ipython --pylab=tk
, também conhecido comobackend = TkAgg
Obrigado pela ajuda com tudo.
fonte
Lancei um pacote chamado python-drawnow que fornece funcionalidade para permitir a atualização de uma figura, normalmente chamada dentro de um loop for, semelhante ao Matlab
drawnow
.Um exemplo de uso:
Este pacote funciona com qualquer figura do matplotlib e fornece opções para aguardar após cada atualização da figura ou soltar no depurador.
fonte
Todas as alternativas acima podem ser verdadeiras, no entanto, para mim, a "atualização on-line" das figuras funciona apenas com alguns back-ends, especificamente
wx
. Você pode tentar mudar para isso, por exemplo, iniciando o ipython / pylab byipython --pylab=wx
! Boa sorte!fonte
Isso funcionou para mim:
fonte