Menggambar non-blok dan memperbarui grafik dengan bokeh

gambar

Saya punya satu skrip Python dengan perhitungan. Ada siklus sekitar 2000 iterasi, yang masing-masing dianggap beberapa menit.

Dan saya memutuskan untuk secara pintar men-debug skrip itu, menampilkan grafik beberapa metrik dari nomor iterasi. Dan sebagai iterasi berikutnya dihitung, jadi ini jadwal dan pembaruan.

Cara termudah untuk melakukan ini adalah dengan bokeh. Lebih tepatnya, menggunakan server bokeh untuk menggambar grafik. Bagaimana - sekarang saya akan memberi tahu Anda.

Pertama, mulai server: server keluar dari kotak bersama dengan bokeh itu sendiri, jadi setelah pip install bokeh, ketik saja servis bokeh di konsol dan server dimulai.

Mengapa itu dibutuhkan? Dan kemudian menunjukkan grafik

  • tidak memblokir eksekusi sisa kode (karena terjadi di browser, dalam proses terpisah),
  • sehingga grafik merespons perubahan ukuran jendela (atau meminimalkan-memaksimalkan-memaksimalkan)
  • dan agar kapan saja kita dapat mengubah jadwal ini seperti yang kita inginkan, langsung dari proses Python kami!

Ini dilakukan seperti ini:

import time import sys from bokeh.plotting import figure from bokeh.client import pull_session from bokeh.models import ColumnDataSource #     --    -,    bokeh serve # Please run "bokeh serve" in console before start! if __name__ == "__main__": #    (  ,     ) session = pull_session() #  .. ,      (    ) fig = figure(title=("Total TBS (in bits)"), plot_height=300, plot_width=800) #         datasource = ColumnDataSource(data={"x": [], "y": []}) line = fig.line(x="x", y="y", source=datasource, line_width=2, legend=("Super dooper line from hell")) #        session.show(fig) #     for i in range(10000): #          .   datasource     #       = ) datasource.stream({"x": [i], "y": [i ** 2]}) #       30-40      ,   session.force_roundtrip() #  ! 

Sebelumnya, saya juga harus melakukan ini, tetapi keputusan sebelumnya adalah, secara halus, tidak begitu baik. Apa yang belum saya coba dalam hidup saya ...

Perhatian, pemberat otak!
Anda dapat menggunakan matplotlib dalam mode non-blocking dengan menarik secara manual plt.draw () di setiap iterasi. Benar, matplotlib tidak memiliki pemrosesan pesan sendiri dari GUI dalam mode non-blocking, dan jika jendela meminimalkan atau menutup dengan jendela lain, kita harus menunggu iterasi berikutnya untuk menggambar ulang. Kruk begitu-begitu, tetapi untuk debugging itu akan dilakukan.

Dimungkinkan di Negro untuk menghasilkan gambar dengan bagan dari matplotlib yang sama dan membuangnya ke disk. Juga kruk yang ganas, tetapi menunggang kekurangan ikan. Atau pada mesin jarak jauh tanpa gambar.

Anda dapat melakukannya dengan cara yang keren: gunakan PyQt, bungkus kode perhitungan dalam sebuah QObject, dorong ke dalam aliran terpisah, bungkus grafik matplotlib dalam QWidget (atau gunakan grafik dari Qt Data Visualizaion, atau dari PyQtGraph), hubungkan matematika ke grafik melalui sinyal dengan sebuah slot , dan akan ada kebahagiaan. Benar, ini sedikit seperti solusi debugging cepat, dan Qt perlu diajarkan, tetapi saya melakukannya beberapa kali.

Anda dapat meningkatkan aplikasi server kecil untuk menggambar grafik dalam proses terpisah (misalnya, menggunakan aiohttp + PyQt + PyQtGraph), yang dapat diketuk melalui REST API dari proses utama. Setelah saya melakukan ini, tetapi tidak menarik perbaikan cepat untuk debugging juga.

Anda dapat menulis ke beberapa jenis database (apa yang ada di mode saat ini?), Dan kemudian biarkan Grafan masuk ke mode. Benar, Anda perlu meletakkan kedua basis data dan Grafan, mengonfigurasinya, dan umumnya repot menulis ke basis data. Mungkin, ini juga dimungkinkan melalui file, tetapi untuk dua grafik untuk seribu poin masing-masing adalah seperti sparrow ...

Atau Anda dapat memahami plotly.dash, letakkan matematika dalam aliran terpisah, bungkus dalam aplikasi dasbor, dan lakukan banyak sampah. Ini belum saya kuasai, meskipun itu perlu.

Singkatnya, debugging berhasil!

Source: https://habr.com/ru/post/id474378/


All Articles