J'évalue actuellement différentes bibliothèques de traçage python. En ce moment, j'essaye matplotlib et je suis assez déçu de la performance. L'exemple suivant est modifié à partir d' exemples SciPy et ne me donne que ~ 8 images par seconde!
Existe-t-il des moyens d'accélérer cela ou devrais-je choisir une bibliothèque de traçage différente?
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
moi-même
la source
la source
Réponses:
Tout d'abord, (bien que cela ne changera pas du tout les performances) envisagez de nettoyer votre code, comme ceci:
Avec l'exemple ci-dessus, j'obtiens environ 10fps.
Juste un petit mot, en fonction de votre cas d'utilisation exact, matplotlib peut ne pas être un excellent choix. Il est orienté vers des chiffres de qualité de publication, pas vers l'affichage en temps réel.
Cependant, vous pouvez faire beaucoup de choses pour accélérer cet exemple.
Il y a deux raisons principales pour lesquelles cela est aussi lent que cela.
1) L'appel
fig.canvas.draw()
redessine tout . C'est votre goulot d'étranglement. Dans votre cas, vous n'avez pas besoin de redessiner des éléments tels que les limites des axes, les étiquettes de graduation, etc.2) Dans votre cas, il y a beaucoup de sous-parcelles avec beaucoup d'étiquettes de graduation. Ceux-ci prennent beaucoup de temps à dessiner.
Ces deux problèmes peuvent être résolus en utilisant le blitting.
Pour faire du blitting efficacement, vous devrez utiliser du code spécifique au backend. En pratique, si vous êtes vraiment inquiet pour des animations fluides, vous intégrez généralement des tracés matplotlib dans une sorte de boîte à outils d'interface graphique, de toute façon, ce n'est donc pas vraiment un problème.
Cependant, sans en savoir un peu plus sur ce que vous faites, je ne peux pas vous y aider.
Néanmoins, il existe une manière de le faire, indépendante de l'interface graphique, qui est encore raisonnablement rapide.
Cela me donne environ 200 images par seconde.
Pour rendre cela un peu plus pratique, il existe un
animations
module dans les versions récentes de matplotlib.Par exemple:
la source
animation
semble mettre à jour l'intrigue parinterval
période de temps, que faire si je veux simplement le mettre à jour lorsque de nouvelles données sont prêtes?Matplotlib fait de superbes graphiques de qualité de publication, mais n'est pas très bien optimisé pour la vitesse. Il existe une variété de packages de traçage python conçus pour la vitesse:
[modifier: pyqwt n'est plus maintenu; le mainteneur précédent recommande pyqtgraph]
la source
Pour commencer, la réponse de Joe Kington fournit de très bons conseils en utilisant une approche indépendante de l'interface graphique, et vous devez absolument suivre ses conseils (en particulier sur Blitting) et les mettre en pratique. Plus d'informations sur cette approche, lisez le livre de recettes Matplotlib
Cependant, l'approche non neutre sur l'interface graphique (biaisée sur l'interface graphique?) Est essentielle pour accélérer le traçage. En d'autres termes, le backend est extrêmement important pour tracer la vitesse.
Mettez ces deux lignes avant d'importer quoi que ce soit d'autre depuis matplotlib:
Bien sûr, il existe différentes options à utiliser à la place
GTKAgg
, mais selon le livre de cuisine mentionné précédemment, c'était la plus rapide. Voir le lien sur les backends pour plus d'options.la source
Pour la première solution proposée par Joe Kington (.copy_from_bbox & .draw_artist & canvas.blit), j'ai dû capturer les arrière-plans après la ligne fig.canvas.draw (), sinon l'arrière-plan n'avait aucun effet et j'ai obtenu le même résultat que vous avez mentionné. Si vous le mettez après la fig.show (), il ne fonctionne toujours pas comme proposé par Michael Browne.
Il suffit donc de mettre la ligne d'arrière-plan après le canvas.draw ():
la source
Cela peut ne pas s'appliquer à beaucoup d'entre vous, mais j'utilise généralement mes ordinateurs sous Linux, donc par défaut, j'enregistre mes tracés matplotlib au format PNG et SVG. Cela fonctionne bien sous Linux mais est insupportablement lent sur mes installations Windows 7 [MiKTeX sous Python (x, y) ou Anaconda], donc j'ai commencé à ajouter ce code, et les choses fonctionnent bien là-bas à nouveau:
la source