Zunächst einmal (obwohl dies die Leistung überhaupt nicht ändert) sollten Sie Ihren Code bereinigen, ähnlich wie folgt:
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)
Mit dem obigen Beispiel erhalte ich ungefähr 10 fps.
Nur eine kurze Anmerkung: Abhängig von Ihrem genauen Anwendungsfall ist matplotlib möglicherweise keine gute Wahl. Es ist auf Zahlen in Publikationsqualität ausgerichtet, nicht auf Echtzeitanzeigen.
Es gibt jedoch eine Menge Dinge, die Sie tun können, um dieses Beispiel zu beschleunigen.
Es gibt zwei Hauptgründe, warum dies so langsam ist wie es ist.
1) Beim Aufrufen fig.canvas.draw()
wird alles neu gezeichnet . Es ist dein Engpass. In Ihrem Fall müssen Sie Dinge wie Achsengrenzen, Häkchen usw. nicht neu zeichnen.
2) In Ihrem Fall gibt es viele Nebenhandlungen mit vielen Häkchen. Das Zeichnen dauert lange.
Beide können durch Blitting behoben werden.
Um das Blitting effizient durchzuführen, müssen Sie Backend-spezifischen Code verwenden. Wenn Sie sich in der Praxis wirklich Sorgen um flüssige Animationen machen, binden Sie in der Regel ohnehin Matplotlib-Plots in eine Art GUI-Toolkit ein, sodass dies kein großes Problem darstellt.
Ohne ein bisschen mehr darüber zu wissen, was Sie tun, kann ich Ihnen dort nicht helfen.
Trotzdem gibt es eine gui-neutrale Methode, die immer noch recht schnell ist.
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)
Das gibt mir ~ 200fps.
Um dies ein wenig bequemer zu machen, gibt es animations
in neueren Versionen von matplotlib ein Modul.
Als Beispiel:
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()