pyside6中使用matplotlib画折线图

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

pyside6中使用matplotlib画折线图

在这里插入图片描述



import sys
import time
import random
import numpy as np
from datetime import datetime, timedelta
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PySide6.QtCore import QTimer
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg, NavigationToolbar2QT
from matplotlib.figure import Figure
from matplotlib.widgets import SpanSelector
from matplotlib.dates import date2num, num2date, DateFormatter
import matplotlib.pyplot as plt

# 设置字体为SimHei显示中文
plt.rcParams['font.sans-serif']=['SimHei']
# 设置正常显示符号
plt.rcParams['axes.unicode_minus']=False



class DynamicPlot(FigureCanvasQTAgg):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)
        super().__init__(fig)

        self.xdata, self.ydata = [], []
        self.line = None
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_plot)
        self.timer.start(1000)

        self.axes.grid(True, linestyle=':')
        self.axes.set_xlabel('Time')
        self.axes.set_ylabel('Value')

        # 设置x轴为日期格式,并指定日期格式化器
        self.axes.xaxis_date()
        self.axes.xaxis.set_major_formatter(DateFormatter('%H:%M:%S'))
        self.axes.fmt_xdata = DateFormatter('%H:%M:%S')

        # 假设第一个数据点的时间为start_time
        start_time = self.xdata[0] if self.xdata else datetime.now()

        # 在数据序列开始之前添加一个(0,0)的点
        self.xdata.insert(0, start_time - timedelta(seconds=1))
        self.ydata.insert(0, 0)

        # 设置x轴的初始范围,确保包含(0,0)点
        self.axes.set_xlim(start_time - timedelta(seconds=1), start_time + timedelta(hours=1))
        # 设置y轴的初始范围,确保包含0
        self.axes.set_ylim(0, max(self.ydata) if self.ydata else 200)


        # 初始化时设置坐标轴范围
        self.axes.set_xlim(datetime.min, datetime.min + timedelta(minutes=1))
        self.axes.set_ylim(0, 200)

        self.line, = self.axes.plot([], [], 'o-', lw=1, ms=2)

        self.span = SpanSelector(self.axes, self.onselect, 'horizontal', useblit=True,
                                 props=dict(alpha=0.5, facecolor='red'),
                                 interactive=True, drag_from_anywhere=True)

        # 标记坐标轴范围已设置的标志
        self.xlim_set = False

    def update_plot(self):
        current_time = datetime.now()
        if len(self.ydata) < 20:
            self.xdata.append(current_time)
            self.ydata.append(random.randint(0, 200))
        self.line.set_data(self.xdata, self.ydata)

        # 确保x轴的范围至少包含(0,0)点
        self.axes.set_xlim(self.xdata[0], self.xdata[-1])
        # 确保y轴的范围包含0
        self.axes.set_ylim(0, max(self.ydata) if self.ydata else 200)

        # 如果是第一次添加数据点,设置坐标轴范围
        if not self.xlim_set:
            self.axes.set_xlim(self.xdata[0], self.xdata[-1])
            self.axes.set_ylim(0, max(self.ydata))
            self.xlim_set = True

        # 每次更新数据后,重新计算轴的极限并重新缩放视图
        self.axes.relim()
        self.axes.autoscale_view()
        self.draw()

    def onselect(self, xmin, xmax):
        xdata = np.array(self.xdata)
        ydata = np.array(self.ydata)

        xdata_numeric = date2num(xdata)

        indmin, indmax = np.searchsorted(xdata_numeric, (xmin, xmax))
        indmax = min(len(xdata) - 1, int(indmax))

        region_x = xdata[indmin:indmax]
        region_y = ydata[indmin:indmax]

        if len(region_y) == 0:
            print("No data selected.")
            return

        min_val = np.min(region_y)
        max_val = np.max(region_y)
        avg_val = np.mean(region_y)
        cumsum_val = np.sum(region_y)

        mid_index = (indmin + indmax) // 2

        # 确保mid_index在有效范围内
        if mid_index >= len(region_x):
            mid_index = len(region_x) - 1

        mid_x = region_x[mid_index]

        for txt in self.axes.texts:
            txt.remove()

        self.axes.text(mid_x, max_val, f"最大: {max_val:.9f}\n最小: {min_val:.9f}\n平均: {avg_val:.9f}\n总和: {cumsum_val:.9f}",
                       transform=self.axes.transData, fontsize=8,
                       verticalalignment='top', bbox=dict(boxstyle="round", fc="w", ec="0.5", alpha=0.9))

        self.draw_idle()

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        dp = DynamicPlot(self, width=5, height=4, dpi=100)

        layout = QVBoxLayout()
        layout.addWidget(dp)
        toolbar = NavigationToolbar2QT(dp, self)
        layout.addWidget(toolbar)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec())

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值