2024-06-13

動的に QChart を利用する ~ PySide6

PySide (Qt for Python) は、Qt(キュート)の Python バインディングで、GUI などを構築するためのクロスプラットフォームなライブラリです。Linux/X11, macOS および Microsoft Windows をサポートしています。配布ライセンスは LGPL で公開されています。

本ブログで、Matplotlib のチャートを PySide6 の GUI に埋め込んで、QTimer でイベントを発生させて動的にチャートに正弦曲線を描画するサンプルを示しました [1]

このぐらいのチャートであれば、PySide6 の QChart でも実現できるだろうと考え、同じようなサンプルを作ってみました。

下記の OS 環境で動作確認をしています。

RHEL 9.4 x86_64
Python 3.12.1
PySide6 6.7.1

今回もタイマーで 50 ミリ秒毎にイベントを発生させて正弦曲線 (Sin) を描画していますが、時刻の扱いが不慣れだったので、単純に 0.02π 刻みでプロットして、10π になったらタイマーを止めています。またチャートの y 軸のレンジは固定し、x 軸はある程度の頻度で更新するようにしました、

qtcharts_linechart_realtime.py
#!/usr/bin/env python
import sys
from math import sin, pi
from PySide6.QtCharts import (
QChart,
QChartView,
QLineSeries,
QValueAxis,
)
from PySide6.QtCore import QTimer, Qt
from PySide6.QtGui import QPainter, QPen
from PySide6.QtWidgets import QApplication, QMainWindow
def get_red_pen() -> QPen:
pen = QPen(Qt.GlobalColor.red)
pen.setWidth(1)
return pen
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.x = 0
self.series = QLineSeries()
self.series.setPen(get_red_pen())
self.series.setPointsVisible(True)
self.series.setMarkerSize(2.0)
self.series.append(self.x, 0)
self.axis_x = QValueAxis()
self.axis_x.setTitleText('X')
self.axis_x.setTickCount(5)
self.axis_x.setRange(0, 0)
self.axis_y = QValueAxis()
self.axis_y.setTitleText('Y')
self.axis_y.setRange(-1, 1)
chart = QChart()
chart.setTitle("Sample")
chart.addSeries(self.series)
chart.legend().hide()
chart.addAxis(self.axis_x, Qt.AlignmentFlag.AlignBottom)
self.series.attachAxis(self.axis_x)
chart.addAxis(self.axis_y, Qt.AlignmentFlag.AlignLeft)
self.series.attachAxis(self.axis_y)
view = QChartView(chart)
view.setRenderHint(QPainter.RenderHint.Antialiasing)
self.setCentralWidget(view)
self.resize(600, 400)
self.timer = QTimer()
self.timer.timeout.connect(self.update_data)
self.timer.setInterval(50)
self.timer.start()
def update_data(self):
self.x += 0.02 * pi
self.series.append(self.x, sin(self.x))
x_max = round(self.x + 0.5)
if self.axis_x.max() < x_max:
self.axis_x.setRange(0, self.axis_x.max() + 4)
if self.x > 10 * pi:
self.timer.stop()
def main():
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()

このサンプルを実行した例を示しました。

qtcharts_linechart_realtime.py の実行例

Matplotlib でチャートを描画する作法とは異なるものの、QLineSeries にデータ点を追加するだけでチャートを更新でき、必要があればデータ全体を簡単に取り出せます。PySide6 だけで完結させたければ、これでもよいのかもしれません。個人的には、圧倒的に Matplotlib を利用する頻度が高いので、QChart によるプロットは慣れが必要です。

参考サイト

  1. bitWalk's: 動的に Matplotlib のチャートを利用する ~ PySide6 [2024-06-10]
  2. QChart - Qt for Python
  3. QChartView - Qt for Python
  4. QLineSeries - Qt for Python
  5. QValueAxis - Qt for Python

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



0 件のコメント: