gpt4 book ai didi

python - pyqtgraph 中的动画图表

转载 作者:行者123 更新时间:2023-12-01 08:39:30 26 4
gpt4 key购买 nike

我正在使用 pyqtchart 进行第一次测试,但由于有关动画图表的文档很差,我遇到了一些问题。我构建了一个图表,显示“sin”、“cos”和“tan”函数(近似于正切值),为了使其生效,我构建了一个线程,每次都会清除并重新绘制图表。它有效,但我不知道这是否是正确的方法或最有效的方法。我发现一个托管在 github 上的示例但我不太清楚。

我不明白这是否是“官方方式”,或者 pyqtgraph 是否提供了一些内置函数来实现自动化。我将非常感谢任何能给我一些建议的人。

这是我的代码:

from PyQt5.QtWidgets import *
from PyQt5.QtCore import QThread, pyqtSignal
import pyqtgraph as pg
import math
import numpy as np
import sys
import time

class Gui(QWidget):
def __init__(self):
super().__init__()
self.setupUI()

def setupUI(self):
pg.setConfigOption('background', 0.95)
pg.setConfigOptions(antialias=True)
self.plot = pg.PlotWidget()
self.plot.setAspectLocked(lock=True, ratio=0.01)
self.plot.setYRange(-3, 3)
self.widget_layout = QVBoxLayout()
self.widget_layout.addWidget(self.plot)
self.setLayout(self.widget_layout)

def plot_data(self, data):
self.plot.clear()
self.plot.plot(range(0, 720), data[0], pen=pg.mkPen(color='g', width=2))
self.plot.plot(range(0, 720), data[1], pen=pg.mkPen(color='r', width=2))
self.plot.plot(range(0, 720), data[2], pen=pg.mkPen(color='y', width=2))

class Thread(QThread):
sig_plot = pyqtSignal(list)
def __init__(self):
super().__init__()
self.sig_plot.connect(gui.plot_data)

def run(self):
sin_func = np.empty(720)
cos_func = np.empty(720)
tan_func = np.empty(720)
cont = 0
while True:
indx = 0
for ang in range(cont, cont + 720):
rad = math.radians(ang)
cos = math.cos(rad)
sin = math.sin(rad)
if cos != 0: tan = sin / cos
else: tan = sin / 0.00000000001
sin_func[indx] = sin
cos_func[indx] = cos
if tan >= -3 and tan <= 3: tan_func[indx] = tan
else: tan_func[indx] = np.NaN
indx += 1
data = [sin_func, cos_func, tan_func]
self.sig_plot.emit(data)
time.sleep(0.01)
if cont == 720: cont = 0
else: cont += 1

if __name__ == '__main__':
app = QApplication(sys.argv)
gui = Gui()
gui.show()
thread = Thread()
thread.start()
sys.exit(app.exec_())

最佳答案

在 pyqtgraph 中没有制作动画的官方方法,但是您示例的方法不是最好的,因为只有在任务繁重但创建数组的任务不是时才需要 GUI 中的线程,这是另一个错误是清理和创建绘图,在这些情况下最好重用。最后,最好在矩阵和数组级别使用 numpy 的计算能力,而不是进行循环。

考虑到上述情况,我实现了一个类,该类每隔一定时间间隔使用适当的索引调用函数generate_data,并在 QTimer 的帮助下生成无限循环。

from PyQt5 import QtCore, QtWidgets
import pyqtgraph as pg
import numpy as np

class TimeLine(QtCore.QObject):
frameChanged = QtCore.pyqtSignal(int)

def __init__(self, interval=60, loopCount=1, parent=None):
super(TimeLine, self).__init__(parent)
self._startFrame = 0
self._endFrame = 0
self._loopCount = loopCount
self._timer = QtCore.QTimer(self, timeout=self.on_timeout)
self._counter = 0
self._loop_counter = 0
self.setInterval(interval)

def on_timeout(self):
if self._startFrame <= self._counter < self._endFrame:
self.frameChanged.emit(self._counter)
self._counter += 1
else:
self._counter = 0
self._loop_counter += 1

if self._loopCount > 0:
if self._loop_counter >= self.loopCount():
self._timer.stop()

def setLoopCount(self, loopCount):
self._loopCount = loopCount

def loopCount(self):
return self._loopCount

interval = QtCore.pyqtProperty(int, fget=loopCount, fset=setLoopCount)

def setInterval(self, interval):
self._timer.setInterval(interval)

def interval(self):
return self._timer.interval()

interval = QtCore.pyqtProperty(int, fget=interval, fset=setInterval)

def setFrameRange(self, startFrame, endFrame):
self._startFrame = startFrame
self._endFrame = endFrame

@QtCore.pyqtSlot()
def start(self):
self._counter = 0
self._loop_counter = 0
self._timer.start()


class Gui(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setupUI()

def setupUI(self):
pg.setConfigOption('background', 0.95)
pg.setConfigOptions(antialias=True)
self.plot = pg.PlotWidget()
self.plot.setAspectLocked(lock=True, ratio=0.01)
self.plot.setYRange(-3, 3)
widget_layout = QtWidgets.QVBoxLayout(self)
widget_layout.addWidget(self.plot)

self._plots = [self.plot.plot([], [], pen=pg.mkPen(color=color, width=2)) for color in ("g", "r", "y")]
self._timeline = TimeLine(loopCount=0, interval=10)
self._timeline.setFrameRange(0, 720)
self._timeline.frameChanged.connect(self.generate_data)
self._timeline.start()

def plot_data(self, data):
for plt, val in zip(self._plots, data):
plt.setData(range(len(val)), val)

@QtCore.pyqtSlot(int)
def generate_data(self, i):
ang = np.arange(i, i + 720)
cos_func = np.cos(np.radians(ang))
sin_func = np.sin(np.radians(ang))
tan_func = sin_func/cos_func
tan_func[(tan_func < -3) | (tan_func > 3)] = np.NaN
self.plot_data([sin_func, cos_func, tan_func])

if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
gui = Gui()
gui.show()
sys.exit(app.exec_())

关于python - pyqtgraph 中的动画图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53573670/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com