Tout d'abord, (bien que cela ne change pas du tout les performances), pensez à nettoyer votre code, de la manière suivante :
import matplotlib.pyplot as plt
import numpy as np
import time
x = np.arange(0, 2*np.pi, 0.01)
y = np.sin(x)
fig, axes = plt.subplots(nrows=6)
styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
lines = [ax.plot(x, y, style)[0] for ax, style in zip(axes, styles)]
fig.show()
tstart = time.time()
for i in xrange(1, 20):
for j, line in enumerate(lines, start=1):
line.set_ydata(np.sin(j*x + i/10.0))
fig.canvas.draw()
print 'FPS:' , 20/(time.time()-tstart)
Avec l'exemple ci-dessus, j'obtiens environ 10fps.
Juste une petite note, selon votre cas d'utilisation exact, matplotlib peut ne pas être un excellent choix. Il est orienté vers les chiffres de qualité publication, pas vers l'affichage en temps réel.
Cependant, il y a beaucoup de choses que vous pouvez faire pour accélérer cet exemple.
Deux raisons principales expliquent cette lenteur.
1) 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 des tics, etc.
2) Dans votre cas, il y a beaucoup de sous-intrigues avec beaucoup d'étiquettes à cocher. 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 soucieux de la fluidité des animations, vous intégrez généralement les tracés de matplotlib dans une sorte de boîte à outils graphique, donc ce n'est pas un gros problème.
Cependant, sans en savoir un peu plus sur ce que vous faites, je ne peux pas vous aider.
Néanmoins, il existe une manière neutre de le faire qui est encore raisonnablement rapide.
import matplotlib.pyplot as plt
import numpy as np
import time
x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)
fig, axes = plt.subplots(nrows=6)
fig.show()
# We need to draw the canvas before we start animating...
fig.canvas.draw()
styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
def plot(ax, style):
return ax.plot(x, y, style, animated=True)[0]
lines = [plot(ax, style) for ax, style in zip(axes, styles)]
# Let's capture the background of the figure
backgrounds = [fig.canvas.copy_from_bbox(ax.bbox) for ax in axes]
tstart = time.time()
for i in xrange(1, 2000):
items = enumerate(zip(lines, axes, backgrounds), start=1)
for j, (line, ax, background) in items:
fig.canvas.restore_region(background)
line.set_ydata(np.sin(j*x + i/10.0))
ax.draw_artist(line)
fig.canvas.blit(ax.bbox)
print 'FPS:' , 2000/(time.time()-tstart)
Cela me donne ~200fps.
Pour rendre cela un peu plus pratique, il y a une fonction animations
dans les versions récentes de matplotlib.
A titre d'exemple :
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)
fig, axes = plt.subplots(nrows=6)
styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
def plot(ax, style):
return ax.plot(x, y, style, animated=True)[0]
lines = [plot(ax, style) for ax, style in zip(axes, styles)]
def animate(i):
for j, line in enumerate(lines, start=1):
line.set_ydata(np.sin(j*x + i/10.0))
return lines
# We'd normally specify a reasonable "interval" here...
ani = animation.FuncAnimation(fig, animate, xrange(1, 200),
interval=0, blit=True)
plt.show()
0 votes
Les éléments suivants pourraient être pertinents : stackoverflow.com/questions/5003094/
2 votes
@aix - Glumpy n'a été utile dans cet exemple que parce qu'il s'agissait d'un affichage rapide de données d'image. Il ne sera pas utile dans ce cas.
1 votes
Essayez de changer le backend. Voir ma réponse : stackoverflow.com/a/30655528/2066079 . ou la présente FAQ sur les backends : matplotlib.org/faq/usage_faq.html#what-is-a-backend
0 votes
Utilisation de
fig.canvas.draw_idle()
au lieu defig.canvas.draw()
a fonctionné pour moi.