Wizard Notes

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

PyQtGraph:プロットの基礎と、GraphicsWindowをGraphicsLayoutWidget に置き換える際の注意点

PyQtGraph の公式実装例*1やWeb上にあるソースコードを見ると、例えば PyQtGraph でのリアルタイムプロットのコードは以下のように実装されています。

# -*- coding: utf-8 -*-
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg

app = QtGui.QApplication([])# PyQtのアプリ生成
win = pg.GraphicsWindow() # GraphicsWindow() オブジェクト生成
win.resize(500, 500)

p = win.addPlot(title="real-time plot") # PlotItem オブジェクト生成
curve = p.plot(pen='c') # PlotDataItemオブジェクト生成
pg.setConfigOptions(antialias=True)

# x = ... #numpy.ndarray
# y = ... #numpy.ndarray

def update():
    global x, y, curve
    curve.setData(x, y)
    
fps = 30
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(1/fps * 1000)

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

ここで、GraphicsWindowオブジェクト生成を生成していますが、公式ドキュメントを見るとGraphicsWindowクラスは非推奨になっています。

具体的には、GraphicsWindowの親クラスであるGraphicsLayoutWidgetクラスの利用を薦めています。

f:id:Kurene:20210610000327p:plain:w500

Deprecated Window Classes — pyqtgraph 0.12.1 documentation

GraphicsWindow と GraphicsLayoutWidget の違い

GraphicsWindowクラスとGraphicsLayoutWidgetソースコードを比較してみます。

GraphicsWindow ソースコード

class GraphicsWindow(GraphicsLayoutWidget):
    def __init__(self, title=None, size=(800,600), **kargs):
        warnings.warn(
            'GraphicsWindow is deprecated, use GraphicsLayoutWidget instead,'
            'will be removed in 0.13',
            DeprecationWarning, stacklevel=2
        )
        mkQApp()
        GraphicsLayoutWidget.__init__(self, **kargs)
        self.resize(*size)
        if title is not None:
            self.setWindowTitle(title)
        self.show()

GraphicsLayoutWidget ソースコード

# -*- coding: utf-8 -*-
from ..Qt import QtGui, mkQApp
from ..graphicsItems.GraphicsLayout import GraphicsLayout
from .GraphicsView import GraphicsView

class GraphicsLayoutWidget(GraphicsView):
    def __init__(self, parent=None, show=False, size=None, title=None, **kargs):
        mkQApp()
        GraphicsView.__init__(self, parent)
        self.ci = GraphicsLayout(**kargs)
        for n in ['nextRow', 'nextCol', 'nextColumn', 'addPlot', 'addViewBox', 'addItem', 'getItem', 'addLayout', 'addLabel', 'removeItem', 'itemIndex', 'clear']:
            setattr(self, n, getattr(self.ci, n))
        self.setCentralItem(self.ci)
        
        if size is not None:
            self.resize(*size)
            
        if title is not None:
            self.setWindowTitle(title)
            
        if show is True:
            self.show()

上記を比較すると、self.show()の実行方法に違いがあります。

従って、GraphicsWindowクラスをGraphicsLayoutWidget クラスに置き換える際は 、以下のようにself.show()を実行する必要があります

win = pg.GraphicsLayoutWidget() 
win.show()
win = pg.GraphicsLayoutWidget(show=True) 

*1:python -m pyqtgraph.examples