Atualmente estou avaliando diferentes bibliotecas de plotagem de python. No momento estou tentando matplotlib e estou bastante decepcionado com o desempenho. O exemplo a seguir foi modificado a partir de exemplos SciPy e me dá apenas ~ 8 quadros por segundo!
Alguma maneira de acelerar isso ou devo escolher uma biblioteca de plotagem diferente?
from pylab import *
import time
ion()
fig = figure()
ax1 = fig.add_subplot(611)
ax2 = fig.add_subplot(612)
ax3 = fig.add_subplot(613)
ax4 = fig.add_subplot(614)
ax5 = fig.add_subplot(615)
ax6 = fig.add_subplot(616)
x = arange(0,2*pi,0.01)
y = sin(x)
line1, = ax1.plot(x, y, 'r-')
line2, = ax2.plot(x, y, 'g-')
line3, = ax3.plot(x, y, 'y-')
line4, = ax4.plot(x, y, 'm-')
line5, = ax5.plot(x, y, 'k-')
line6, = ax6.plot(x, y, 'p-')
# turn off interactive plotting - speeds things up by 1 Frame / second
plt.ioff()
tstart = time.time() # for profiling
for i in arange(1, 200):
line1.set_ydata(sin(x+i/10.0)) # update the data
line2.set_ydata(sin(2*x+i/10.0))
line3.set_ydata(sin(3*x+i/10.0))
line4.set_ydata(sin(4*x+i/10.0))
line5.set_ydata(sin(5*x+i/10.0))
line6.set_ydata(sin(6*x+i/10.0))
draw() # redraw the canvas
print 'FPS:' , 200/(time.time()-tstart)
python
matplotlib
eu mesmo
fonte
fonte
Respostas:
Em primeiro lugar, (embora isso não mude o desempenho de forma alguma), considere limpar seu código, semelhante a este:
Com o exemplo acima, obtenho cerca de 10 fps.
Apenas uma nota rápida, dependendo do seu caso de uso exato, matplotlib pode não ser uma ótima escolha. É orientado para números de qualidade de publicação, não para exibição em tempo real.
No entanto, há muitas coisas que você pode fazer para acelerar este exemplo.
Existem duas razões principais pelas quais isso é tão lento quanto é.
1) Chamar
fig.canvas.draw()
redesenha tudo . É o seu gargalo. No seu caso, você não precisa redesenhar coisas como os limites dos eixos, rótulos de escala, etc.2) No seu caso, há muitos subplots com muitos rótulos de escala. Demora muito para desenhar.
Ambos podem ser corrigidos usando blitting.
Para fazer blitting com eficiência, você terá que usar um código específico do backend. Na prática, se você está realmente preocupado com animações suaves, normalmente está incorporando gráficos matplotlib em algum tipo de kit de ferramentas de interface do usuário, então isso não é um grande problema.
Porém, sem saber um pouco mais sobre o que você está fazendo, não posso te ajudar nisso.
No entanto, existe uma maneira neutra de gui de fazer isso que ainda é razoavelmente rápida.
Isso me dá ~ 200 fps.
Para tornar isso um pouco mais conveniente, há um
animations
módulo nas versões recentes do matplotlib.Como um exemplo:
fonte
animation
parece atualizar o gráfico porinterval
período de tempo, e se eu só quiser atualizá-lo quando novos dados estiverem prontos?Matplotlib produz gráficos com ótima qualidade de publicação, mas não é muito bem otimizado para velocidade. Há uma variedade de pacotes de plotagem python que são projetados com a velocidade em mente:
[editar: pyqwt não é mais mantido; o mantenedor anterior está recomendando pyqtgraph]
fonte
Para começar, a resposta de Joe Kington fornece conselhos muito bons usando uma abordagem neutra do gui, e você definitivamente deve seguir o conselho dele (especialmente sobre Blitting) e colocá-lo em prática. Mais informações sobre esta abordagem, leia o Matplotlib Cookbook
No entanto, a abordagem não neutra da GUI (polarizada pela GUI?) É a chave para acelerar a plotagem. Em outras palavras, o back - end é extremamente importante para traçar a velocidade.
Coloque essas duas linhas antes de importar qualquer outra coisa de matplotlib:
Claro, existem várias opções para usar em vez de
GTKAgg
, mas de acordo com o livro de receitas mencionado antes, esta foi a mais rápida. Veja o link sobre back-ends para mais opções.fonte
Para a primeira solução proposta por Joe Kington (.copy_from_bbox & .draw_artist & canvas.blit), tive que capturar os fundos após a linha fig.canvas.draw (), caso contrário, o fundo não teve efeito e obtive o mesmo resultado que você mencionou. Se você colocá-lo após fig.show (), ele ainda não funcionará como proposto por Michael Browne.
Portanto, basta colocar a linha de fundo após o canvas.draw ():
fonte
Isso pode não se aplicar a muitos de vocês, mas geralmente estou operando meus computadores no Linux, então, por padrão, salvo meus gráficos matplotlib como PNG e SVG. Isso funciona bem no Linux, mas é insuportavelmente lento em minhas instalações do Windows 7 [MiKTeX em Python (x, y) ou Anaconda], então comecei a adicionar este código e as coisas funcionam bem lá novamente:
fonte