Saya sedang mengevaluasi pustaka plotting python yang berbeda. Saat ini saya mencoba matplotlib dan saya cukup kecewa dengan performanya. Contoh berikut dimodifikasi dari contoh SciPy dan memberi saya hanya ~ 8 frame per detik!
Adakah cara untuk mempercepat ini atau haruskah saya memilih perpustakaan plot yang berbeda?
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
saya sendiri
sumber
sumber
Jawaban:
Pertama, (meskipun ini tidak akan mengubah kinerja sama sekali) pertimbangkan untuk membersihkan kode Anda, seperti ini:
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.
Ini memberi saya ~ 200fps.
Untuk membuatnya sedikit lebih nyaman, ada
animations
modul dalam versi terbaru matplotlib.Sebagai contoh:
sumber
animation
sepertinya memperbarui plot berdasarkaninterval
periode waktu, bagaimana jika saya hanya ingin memperbaruinya ketika data baru sudah siap?Matplotlib membuat grafik kualitas publikasi yang bagus, tetapi tidak dioptimalkan dengan baik untuk kecepatan. Ada berbagai paket plotting python yang dirancang dengan mempertimbangkan kecepatan:
[edit: pyqwt tidak lagi dipertahankan; pengelola sebelumnya merekomendasikan pyqtgraph]
sumber
Untuk memulai, jawaban Joe Kington memberikan saran yang sangat baik dengan menggunakan pendekatan netral-gui, dan Anda harus mengikuti nasihatnya (terutama tentang Blitting) dan mempraktikkannya. Info lebih lanjut tentang pendekatan ini, baca Buku Masak Matplotlib
Namun, pendekatan non-GUI-netral (GUI-bias?) Adalah kunci untuk mempercepat plotting. Dengan kata lain, backend sangat penting untuk kecepatan plot.
Letakkan dua baris ini sebelum Anda mengimpor apa pun dari matplotlib:
Tentu saja, ada berbagai pilihan untuk digunakan sebagai pengganti
GTKAgg
, tetapi menurut buku resep yang disebutkan sebelumnya, ini adalah yang tercepat. Lihat tautan tentang backend untuk opsi lebih lanjut.sumber
Untuk solusi pertama yang diusulkan oleh Joe Kington (.copy_from_bbox & .draw_artist & canvas.blit), saya harus menangkap latar belakang setelah garis fig.canvas.draw (), jika tidak, latar belakang tidak berpengaruh dan saya mendapatkan hasil yang sama seperti Anda sebutkan. Jika Anda meletakkannya setelah fig.show (), itu masih tidak berfungsi seperti yang diusulkan oleh Michael Browne.
Jadi letakkan saja garis latar belakang setelah canvas.draw ():
sumber
Ini mungkin tidak berlaku untuk banyak dari Anda, tetapi saya biasanya mengoperasikan komputer saya di Linux, jadi secara default saya menyimpan plot matplotlib saya sebagai PNG dan SVG. Ini berfungsi dengan baik di Linux tetapi sangat lambat pada instalasi Windows 7 saya [MiKTeX dengan Python (x, y) atau Anaconda], jadi saya telah menambahkan kode ini, dan semuanya berfungsi dengan baik di sana lagi:
sumber