Python PyQtGraphでリージョンを実装する方法を説明する。
結論
LinearRegionItem()のインスタンスを生成し(下記例ではself.region)、addPlot()のインスタンス(下記例ではself.p0)に.addItemする。
self.region = pg.LinearRegionItem(values=(0,0.2)) # values=(リージョンの最小値、最大値)
self.p0.addItem(self.region, ignoreBounds=True)
コード例
- リージョンを設置
- リージョン変更時の動作にコネクト
- リージョン変更時の動作を記述
#!/usr/bin/env python3
import numpy as np
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QGraphicsProxyWidget, QLabel
import pyqtgraph as pg
class GuiWindow(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.サイン波を作成()
self.グラフを描画()
self.文字表示版を設置()
self.リージョンを設置()
self.リージョン変更時の動作にコネクト()
def サイン波を作成(self):
self.freq = 1 # サイン波の周波数 [Hz]
self.Ts = 0.001 # サンプリング周期 [秒]
self.Ns = 1000 # サンプリング点数 [個]
self.ns = np.arange(0, self.Ns) # サンプル番号
self.time = self.ns * self.Ts
self.sin = 10 * np.sin(2 * np.pi * self.freq * (self.ns * self.Ts))
def グラフを描画(self):
self.graph = pg.GraphicsLayoutWidget(show=True)
self.p0 = self.graph.addPlot(row=0, colspan=3)
self.p0.plot(x=self.time, y=self.sin, pen=pg.mkPen((255,255,0), width=10))
def 文字表示版を設置(self):
self.文字表示版_項目_max = FlexibleSpace(app=self, win=self.graph, row=1, col=0, h=25, w=50, text='max : ')
self.文字表示版_項目_min = FlexibleSpace(app=self, win=self.graph, row=2, col=0, h=25, w=50, text='min : ')
self.文字表示版_値_max = FlexibleSpace(app=self, win=self.graph, row=1, col=1, h=25, w=100)
self.文字表示版_値_min = FlexibleSpace(app=self, win=self.graph, row=2, col=1, h=25, w=100)
self.スペーサー1 = FlexibleSpace(app=self, win=self.graph, row=1, col=2, h=25)
self.スペーサー2 = FlexibleSpace(app=self, win=self.graph, row=2, col=2, h=25)
def リージョンを設置(self): # ? 1
self.region = pg.LinearRegionItem(values=(0,0.2))
self.region.lines[0].setPen(128,128,128)
self.region.lines[1].setPen(128,128,128)
# self.region.setBrush(pg.mkBrush(255,255,0,100)) # region内の色
# self.region.setHoverBrush(pg.mkBrush(255,255,0,100)) # ホバー時のregion内の色
self.region.setZValue(10)
self.p0.addItem(self.region, ignoreBounds=True)
def リージョン変更時の動作にコネクト(self): # ? 2
self.region.sigRegionChanged.connect(self.update_region)
def update_region(self): # ? 3
def リージョンに含まれるデータのインデックスを取得():
r_min, r_max = self.region.getRegion()
self.ind_rmin = int(np.ceil (r_min/self.Ts))
self.ind_rmax = int(np.floor(r_max/self.Ts))
def リージョンがデータ範囲を超えたらインデックスをクリップ():
if self.ind_rmin < 0:
self.ind_rmin = 0
if self.ind_rmax < 0:
self.ind_rmax = 0
if self.ind_rmin > self.Ns:
self.ind_rmin = self.Ns
if self.ind_rmax > self.Ns:
self.ind_rmax = self.Ns
def 文字表示版を更新():
最大値 = np.max(self.sin[self.ind_rmin : self.ind_rmax + 1])
最小値 = np.min(self.sin[self.ind_rmin : self.ind_rmax + 1])
self.文字表示版_値_max.setInnerText(str(np.round(最大値,3)))
self.文字表示版_値_min.setInnerText(str(np.round(最小値,3)))
try:
リージョンに含まれるデータのインデックスを取得()
リージョンがデータ範囲を超えたらインデックスをクリップ()
文字表示版を更新()
except:
pass
class FlexibleSpace(QWidget):
def __init__(self, app, win, row, col, rowspan=1, colspan=1, w=0, h=0, name='', text=''):
super().__init__()
self.set_layout(win=win, row=row, col=col, rowspan=rowspan, colspan=colspan)
self.set_object(app=app, w=w, h=h, name=name, text=text)
self.set_proxy()
self.setInnerText(text=text)
def set_layout(self, win, row, col, rowspan, colspan):
self.p = win.addLayout(row=row, col=col, rowspan=rowspan, colspan=colspan)
self.p.setContentsMargins(10,0,10,0) # 左,上,右,下
def set_object(self, app, w, h, name, text):
def make_object():
self.object = QLabel()
def set_style():
style = ('QLabel{'
'background-color: rgba(0,0,0,0);'
'color: darkgray;'
'}')
self.object.setStyleSheet(style)
def set_size(w, h):
def set_wsize(w):
self.object.setMinimumWidth(w)
self.object.setMaximumWidth(w)
def set_hsize(h):
self.object.setMinimumHeight(h)
self.object.setMaximumHeight(h)
if w > 0:
set_wsize(w)
else:
pass # free size
if h > 0:
set_hsize(h)
else:
pass # free size
make_object()
set_style()
set_size(w=w, h=h)
def set_proxy(self):
self.proxy = QGraphicsProxyWidget()
self.item = self.p.addItem(self.proxy)
self.proxy.setWidget(self.object)
def setInnerText(self, text):
self.object.setText(text)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = GuiWindow()
sys.exit(app.exec())
まとめ
Python PyQtGraphでリージョンを実装する方法を説明した。
コメント