Pertama, (meskipun ini tidak akan mengubah kinerja sama sekali) pertimbangkan untuk membersihkan kode Anda, seperti ini:
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)
Dengan contoh di atas, saya mendapatkan sekitar 10fps.
Hanya catatan singkat, tergantung pada kasus penggunaan Anda, matplotlib mungkin bukan pilihan yang bagus. Ini berorientasi pada figur berkualitas publikasi, bukan tampilan waktu nyata.
Namun, ada banyak hal yang dapat Anda lakukan untuk mempercepat contoh ini.
Ada dua alasan utama mengapa ini berjalan lambat.
1) Memanggil fig.canvas.draw()
menggambar ulang segalanya . Ini hambatan Anda. Dalam kasus Anda, Anda tidak perlu menggambar ulang hal-hal seperti batas sumbu, label centang, dll.
2) Dalam kasus Anda, ada banyak subplot dengan banyak label centang. Ini membutuhkan waktu lama untuk menggambar.
Keduanya dapat diperbaiki dengan menggunakan blitting.
Untuk melakukan blitting secara efisien, Anda harus menggunakan kode khusus backend. Dalam praktiknya, jika Anda benar-benar khawatir tentang animasi yang mulus, Anda biasanya menyematkan plot matplotlib di semacam toolkit gui, jadi ini bukan masalah.
Namun, tanpa mengetahui lebih banyak tentang apa yang Anda lakukan, saya tidak dapat membantu Anda di sana.
Meskipun demikian, ada cara netral gui untuk melakukannya yang masih cukup cepat.
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)
Ini memberi saya ~ 200fps.
Untuk membuatnya sedikit lebih nyaman, ada animations
modul dalam versi terbaru matplotlib.
Sebagai contoh:
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()