PyQt5:QChart绘制动态折线图(2)

前言

前置工作都在上文的博客里边说过了,链接如下:PyQt5:QChart绘制折线图(1)
,在这边文章里边直接说绘制动态折线相关了。

Charts相关刷新函数

1.append()

Qt官方解释:

append(qreal x, qreal y):Adds the data point with the coordinates x and y to the series.
append(const QPointF &point):This is an overloaded function.Adds the data point point to the series.
append(const QList<QPointF> &points):This is an overloaded function.Adds the list of data points specified by points to the series.

将点的坐标信息或者说数据添加到series中,我的理解为追加。

2.replace()

Qt官方解释:

replace(qreal oldX, qreal oldY, qreal newX, qreal newY):Replaces the point with the coordinates oldX and oldY with the point with the coordinates newX and newY. Does nothing if the old point does not exist.
replace(const QPointF &oldPoint, const QPointF &newPoint):Replaces the point specified by oldPoint with the one specified by newPoint.
replace(int index, qreal newX, qreal newY):Replaces the point at the position specified by index with the point that has the coordinates newX and newY.
replace(int index, const QPointF &newPoint):Replaces the point at the position specified by index with the point specified by newPoint.
replace(QList<QPointF> points):Replaces the current points with the points specified by points
replace(QVector<QPointF> points):Replaces the current points with the points specified by points.

字面意思替换,单个坐标点的替换,组坐标数据替换等,在下文我用的是List,群组替换。

思路

将思路主要拆解为3个部分:数据源,坐标列表更新,折线图的刷新
1.数据源:可以为外部实时动态数据,或者是内部动态计算产生的数据。这里我随机造了一些动态数据。
2.坐标列表更新:在我的折线图中,坐标设置了固定显示6个点,这里可以自己随意,或者将x轴更新为时间轴,就为实时数据了。在迭代更新中,定时器检测源数据大于0,就可以更新数据,
3.坐标轴刷新:采用了 replace()函数,替换。

源码

1.数据源

import random
DataVector = [] 
mutex = QMutex()
class ThreadCtl(QThread):
	def __init__(self):
		super().__init__()
		self.threadstatus = 1

	def run(self):
		while self.threadstatus == 1:
			#产生随机数据值,坐标点 y值
			self.randdata_h = random.uniform(1, 6)
			self.randdata_h = round(self.randdata_h, 2)
#			self.randdata_w = random.uniform(1, 6)
#			self.randdata_w = round(self.randdata_w, 2)
#			self.points = [self.post,self.randdata_h,]
			#休眠1S
			time.sleep(1)
			#加锁,插入数据,解锁
			mutex.lock()
			DataVector.append(self.randdata_h)
			mutex.unlock()
			print("DataVector:",DataVector)

采用多线程方式,继承QThread 类,定时产生数据,数据为:1~6,小数点后两位的float数据。
DataVector 一个list容器,用来存储数据列表。
加一把资源锁,防止对DataVector读写造成的资源抢占问题。

2.坐标列表更新

		#定时器
		self.timer = QTimer()
		self.timer.timeout.connect(self.update)
		self.timer.start(2000)
	def update(self):
		if 	len(DataVector) > 0 :
			#取出第一位数据,加锁,解锁
			mutex.lock()
			self.value = DataVector[0]
			DataVector.pop(0)
			mutex.unlock()
			#删除最后一个坐标点
			del self._1_point_list[len(self._1_point_list)-1]
			#第一位插入坐标点
			self._1_point_list.insert(0,QPointF(0,self.value)) 
			#更新x坐标点值
			for i in range(0,len(self._1_point_list)):
					self._1_point_list[i].setX(i)

采用定时器方式,定时去读取DataVector 列表,列表数据大于0就去取出第一位数据。
self._1_point_list 坐标点列表更新规则,最后一位删掉,剩下的前几位向后移位一位,第一位填入DataVector 列表取出的第一位数据。
采用 insert函数,在第一位插入,后续相当于自动移位。然后横坐标更新。

3.折线更新

			for i in range(0,len(self._1_point_list)):
					self._1_point_list[i].setX(i)
			#replace更新折线图
			self.series_1.replace(self._1_point_list)

引申

在实际的项目使用中,数据源的获取,如果是实时数据,如果数据更新速度较快,应该采用什么方式?如果数据量很大应该采用什么方式?折线图刷新时有什么要求?队列积压,应该采用什么方式来处理
我上述采用的方法是,多线程,子线程处理数据源,主线程定时器方式,处理折线图
实际使用中,数据源处理坐标列表更新界面折线图刷新,都有实际的问题。每一个过程,都单独做一个线程来处理,给不同的数据量,设置不同的阈值,对应不同的更新速度,刷新速度。检测到数据积压,就去提高坐标列表更新的处理速度,为了减小,界面折线图刷新的处理压力,将坐标列表也改为坐标点List,改为List[[],[]]模式,设置好界面更新时,直接调用提前处理好的坐标更新,加快刷新速度
实际还有一次刷新大批量数据时,应该怎么处理的问题?这一块暂没有碰到,随后写的时候在处理一下。

源码

源码

  • 1
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
可以使用QChart和QChartView类来绘制实时折线图。以下是一个简单的例子: ```python import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QSizePolicy, QVBoxLayout, QHBoxLayout, QWidget, QPushButton from PyQt5.QtChart import QChart, QChartView, QLineSeries from PyQt5.QtCore import Qt, QRandomGenerator, QTimer class MainWindow(QMainWindow): def __init__(self): super().__init__() # 创建折线图 self.series = QLineSeries() self.chart = QChart() self.chart.addSeries(self.series) self.chart.setTitle("Real-time Line Chart") self.chart.createDefaultAxes() # 创建图表视图 self.chart_view = QChartView(self.chart) self.chart_view.setRenderHint(QPainter.Antialiasing) # 创建按钮 self.start_button = QPushButton("Start") self.stop_button = QPushButton("Stop") # 创建布局 button_layout = QHBoxLayout() button_layout.addWidget(self.start_button) button_layout.addWidget(self.stop_button) main_layout = QVBoxLayout() main_layout.addWidget(self.chart_view) main_layout.addLayout(button_layout) # 创建主窗口 central_widget = QWidget() central_widget.setLayout(main_layout) self.setCentralWidget(central_widget) # 连接按钮信号和槽函数 self.start_button.clicked.connect(self.start) self.stop_button.clicked.connect(self.stop) # 创建定时器 self.timer = QTimer() self.timer.setInterval(1000) self.timer.timeout.connect(self.update_chart) def start(self): self.timer.start() def stop(self): self.timer.stop() def update_chart(self): # 生成随机数 value = QRandomGenerator.global_().bounded(100) # 添加数据 self.series.append(self.series.count(), value) # 移动X轴 self.chart.scroll(self.chart.plotArea().width() / self.series.count(), 0) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_()) ``` 这个例子使用QLineSeries类来存储数据,并使用QChart类来绘制折线图。定时器每秒钟更新一次数据,然后将数据添加到折线图中。注意,这个例子只是一个简单的演示,实际应用中可能需要更复杂的逻辑来处理数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值