Wizard Notes

Pythonを使った音楽信号分析の技術録、作曲活動に関する雑記

Python: PyQtGraphでリアルタイムプロット/アニメーション(サンプルコード・実装デモ付き)

PyQtGraph の導入理由

matplotlib ではダメなのか?

Pythonにおけるグラフプロットライブラリとしては matplotlib が非常によく使われています。

Matplotlib: Python plotting — Matplotlib 3.4.2 documentation

matplotlibはデータのプロットに必要な機能を十分に持っており,また,wxPythonPyQt/PySideといったGUIライブラリと組み合わせることも可能です。

そのため使用実績も多く、Web検索で情報が集めやすいのもお勧めされる理由の1つです。

f:id:Kurene:20210606135455p:plain:w500
https://matplotlib.org/stable/gallery/index.html

そんなmatplotlibにもいくつか課題があり、特にアニメーションやリアルタイムプロットでは、

  • リアルタイムでの描画更新頻度を高くできない
  • リアルタイムでの描画更新間隔が不安定
  • アニメーションのレンダリングが遅い

という課題があります。特にリアルタイムプロットに関しては、経験的に10~30fps 以上の描画更新を必要とするリアルタイムプロット/アプリケーションは matplotlib では厳しいと思います*1

www.wizard-notes.com

www.wizard-notes.com

PyQtGraph のメリット・デメリット

f:id:Kurene:20210606001252p:plain:w500
https://www.pyqtgraph.org/

PyQtGraphは

  • Qt::QGraphicsViewクラス
  • Numpy
  • PyOpenGL

を利用することで高速に動作し、30fps以上のリアルタイムプロットにも耐えられることが分かっています。

また、matplotlib以上にインタラクティブに操作することもできます。最小の依存関係としては Numpy と PyQt/PySide があれば動くというポータビリティ性の高さも魅力的です。

hope-is-dream.hatenablog.com

ただし、PyQtGraph 利用の注意として、PyQt/PySideへの依存が挙げられます。

PyQtGraph自体はMITライセンスですが、PyQt/PySideのライセンスはGPL, LGPLであるため、ソフトウェア配布や他のライセンスのライブラリと組み合わせる際には注意が必要になります。

PyQtGraph の導入方法

公式Webサイトでは、以下の3つの方法が紹介されています。

# 方法1: pip
pip install pyqtgraph
# 方法2: conda
conda install -c conda-forge pyqtgraph
# 方法3: ソースコードからインストール
git clone https://github.com/pyqtgraph/pyqtgraph
cd pyqtgraph
python setup.py install

PyQtGraph - Scientific Graphics and GUI Library for Python

バージョン情報(PyQtGraph==0.12 向け):

  • Python 3.7+
  • Qt 5.12-5.15, 6.1
  • Required
    • PyQt5
    • PyQt6
    • PySide2
    • PySide6
  • numpy 1.17+

なお,Python==3.6ではPyQtGraph=0.11の動作を確認しました.

ただし,PyQtGraph=0.12の方が便利な機能が多いです.(例:matplotlibのカラーマップ利用)

PyQtGraphのエラー対処

PyQtGraphをimportするスクリプトの実行時に遭遇する可能性のあるエラーについて,以下の記事でまとめています.

www.wizard-notes.com

導入・サンプルコードの実行でMKLライブラリに関するエラーが出た場合、以下の記事が役立つかもしれません。

www.wizard-notes.com

リアルタイムプロット/アニメーションの実装例

PyQtGraphのExamplesをベースに、いくつかリアルタイムプロットの例を作成してみました。

1次元プロット(折れ線グラフ)

周波数がスイープするサイン波を実装してみました。

f:id:Kurene:20210606164234p:plain

複数の折れ線・カーブプロット

www.wizard-notes.com

f:id:Kurene:20210627190411g:plain:w500

2D散布図プロット(2D点群)

f:id:Kurene:20210610233143g:plain

www.wizard-notes.com

f:id:Kurene:20210622195609g:plain

www.wizard-notes.com

2Dイメージプロット(スペクトログラム)

f:id:Kurene:20210626090345g:plain

www.wizard-notes.com

3D サーフェスプロット(波のシミュレーション)

f:id:Kurene:20210613222103g:plain www.wizard-notes.com

公式サンプルコード・描画デモ

様々なプロットのサンプルコードが提供されているのがPyQtGraphの良い所の1つです。

サンプルコード・描画デモを見る方法は2つあります。

# 方法1: 以下のコマンドを実行
> python -m pyqtgraph.examples
# 方法2: Pythonインタプリタを起動し、以下の2行を入力
>python
>>import pyqtgraph.examples
>>pyqtgraph.examples.run()

すると、次のようなGUI画面が起動します。左側のメニューから適当なExampleを選んで、デモを体験しつつサンプルコードを読むことができます。

f:id:Kurene:20210606002055p:plain

まとめ

PyQtGraphとPyQtGraphを使ったリアルタイムプロットの実装例を紹介しました。

matplotlibほど有名なライブラリではありませんが、リアルタイムでのデータ可視化を高速に実行できるため、時系列データ分析やメディア信号処理のプロトタイプ/アプリケーション開発などで活躍すると思います。Pythonでリアルタイムでのデータ分析を必要としている方はぜひ試してみてください。

参考文献

*1:figsize, dpi, データサイズ, 更新頻度,プロット種別などにも依存