• PyQt5快速开发与实战 9.5 PyQtGraph在PyQt中的应用 && 9.6 Plotly在PyQt中的应用


    PyQt5快速开发与实战

    9. 第9章 PyQt5 扩展应用

    9.5 PyQtGraph在PyQt中的应用

    PyQtGraph是纯 Python图形GUI库,它充分利用PyQt和 PySide的高质量的图形表现水平和NumPy的快速的科学计算与处理能力,在数学、科学和工程领域都有广泛的应用。PyQtGraph是免费的,并且是在MIT的开源许可下发布的。

    PyQtGraph的主要目标:

    • 为数据、绘图、视频等提供快速、可交互的图形显示。
    • 提供快速开发应用的工具。

    尽管目前PyQtGraph还没有Matplotlib成熟,但是 PyQtGraph 比 Matplotlib 要快得多,尤其是在显示时间序列的实时行情图时,Matplotlib 在性能上有些捉襟见肘。PyQtGraph有自己的特殊应用,如图形交互、参数树、流程图等。由于PyQtGraph是基于PyQt开发的集成绘图模块,所以使用PyQtGraph绘图与通过底层方式来实现PyQt的绘图功能在速度上没有太大的区别。

    9.5.1 PyQtGraph的安装
    pip install pyqtgraph -i https://pypi.tuna.tsinghua.edu.cn/simple
    
    • 1

    在这里插入图片描述

    9.5.2 官方示例

    在这里插入图片描述

    在这里插入图片描述

    核心代码

    在这里插入图片描述

    9.5.3 设置提升的窗口控件

    在这里插入图片描述

    在这里插入图片描述

    ui转py

    在这里插入图片描述

    9.5.4 PyQtGraph的使用

    程序初始化设置

    class MainWindow(QMainWindow, Ui_MainWindow):
        """
        Class documentation goes here.
        """
    
        def __init__(self, parent=None):
            """
            Constructor
            
            @param parent reference to the parent widget
            @type QWidget
            """
            super(MainWindow, self).__init__(parent)
    
            pg.setConfigOption('background', '#f0f0f0')  # 设置背景为灰色
            pg.setConfigOption('foreground', 'd')  # 设置前景(包括坐标轴,线条,文本等等)为黑色。
    
            pg.setConfigOptions(antialias=True) # 使曲线看起来更光滑,而不是锯齿状
            # pg.setConfigOption('antialias',True) # 等价于上一句,所不同之处在于setconfigOptions可以传递多个参数进行多个设置,而setConfigOption一次只能接受一个参数进行一个设置。
            self.setupUi(self)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    绘图部分

    @pyqtSlot()
    def on_pushButton_clicked(self):
        """
        Slot documentation goes here.
        """
        self.pyqtgraph1.clear() # 清空里面的内容,否则会发生重复绘图的结果
    
        '''第一种绘图方式'''
        self.pyqtgraph1.addPlot(title="绘图单条线", y=np.random.normal(size=100), pen=pg.mkPen(color='b', width=2))
    
        '''第二种绘图方式'''
        plt2 = self.pyqtgraph1.addPlot(title='绘制多条线')
    
        plt2.plot(np.random.normal(size=150), pen=pg.mkPen(color='r', width=2), name="Red curve") # pg.mkPen的使用方法,设置线条颜色为红色,宽度为2。
        plt2.plot(np.random.normal(size=110) + 5, pen=(0, 255, 0), name="Green curve")
        plt2.plot(np.random.normal(size=120) + 10, pen=(0, 0, 255), name="Blue curve")
    
    
    @pyqtSlot()
    def on_pushButton_2_clicked(self):
        """
        Slot documentation goes here.
        """
        '''如果没有进行第一次绘图,就开始绘图,然后做绘图标记,否则就什么都不做'''
        try:
            self.first_plot_flag # 检测是否进行过第一次绘图。
        except:
    
            plt = self.pyqtgraph2.addPlot(title='绘制条状图')
            x = np.arange(10)
            y1 = np.sin(x)
            y2 = 1.1 * np.sin(x + 1)
            y3 = 1.2 * np.sin(x + 2)
    
            bg1 = pg.BarGraphItem(x=x, height=y1, width=0.3, brush='r')
            bg2 = pg.BarGraphItem(x=x + 0.33, height=y2, width=0.3, brush='g')
            bg3 = pg.BarGraphItem(x=x + 0.66, height=y3, width=0.3, brush='b')
    
            plt.addItem(bg1)
            plt.addItem(bg2)
            plt.addItem(bg3)
    
            self.pyqtgraph2.nextRow()
    
            p4 = self.pyqtgraph2.addPlot(title="参数图+显示网格")
            x = np.cos(np.linspace(0, 2 * np.pi, 1000))
            y = np.sin(np.linspace(0, 4 * np.pi, 1000))
            p4.plot(x, y, pen=pg.mkPen(color='d', width=2))
            p4.showGrid(x=True, y=True) # 显示网格
    
            self.first_plot_flag = True # 第一次绘图后进行标记
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    运行

    在这里插入图片描述

    9.5.5 更多扩展

    在官方示例中,修改代码,完成扩展

    import pyqtgraph.examples
    
    pyqtgraph.examples.run()
    
    • 1
    • 2
    • 3

    9.6 Plotly在PyQt中的应用

    Plotly本质上是基于 JavaScript 的图表库,支持不同类型的图表,如地图、箱形图、密度图,以及比较常见的条状图和线形图等。从2015年11月17日开始,Plotly个人版本可以免费使用了。

    9.6.1 Plotly的安装
    pip install plotly -i https://pypi.tuna.tsinghua.edu.cn/simple
    
    • 1

    在这里插入图片描述

    9.6.2 示例

    使用QWebEngineView与Plotly完成交互

    # -*- coding: utf-8 -*-
    
    """
    Module implementing MainWindow.
    """
    
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    import sys
    from PyQt5.QtWebEngineWidgets import QWebEngineView
    
    
    class Window(QWidget):
        def __init__(self):
            QWidget.__init__(self)
            self.qwebengine = QWebEngineView(self)
            self.qwebengine.setGeometry(QRect(50, 20, 1200, 600))
            self.qwebengine.load(QUrl.fromLocalFile('D:\DingJiaxiong\PycharmProjects\PyQt5Study\Plotly在PyQt中的应用\plotly_html\if_hs300_bais.html'))
    
    
    app = QApplication(sys.argv)
    screen = Window()
    screen.showMaximized()
    sys.exit(app.exec_())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述

    9.6.3 设置提升的窗口控件

    在这里插入图片描述

    UI.py

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.resize(800, 600)
            self.centralwidget = QtWidgets.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
            self.qwebengine = QWebEngineView(self.centralwidget)
            self.qwebengine.setGeometry(QtCore.QRect(10, 30, 451, 321))
            self.qwebengine.setAutoFillBackground(False)
            self.qwebengine.setStyleSheet("background-color: rgb(170, 170, 127);")
            self.qwebengine.setObjectName("qwebengine")
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtWidgets.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
            self.menubar.setObjectName("menubar")
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtWidgets.QStatusBar(MainWindow)
            self.statusbar.setObjectName("statusbar")
            MainWindow.setStatusBar(self.statusbar)
    
            self.retranslateUi(MainWindow)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
    
        def retranslateUi(self, MainWindow):
            _translate = QtCore.QCoreApplication.translate
            MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
    
    from PyQt5.QtWebEngineWidgets import QWebEngineView
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    9.6.4 Plotly_PyQt5的使用
    import pandas as pd
    import os
    import plotly.offline as pyof
    import plotly.graph_objs as go
    
    import numpy as np
    import matplotlib.pyplot as plt
    
    
    class Plotly_PyQt5():
       def __init__(self):
          plotly_dir = 'plotly_html'
          if not os.path.isdir(plotly_dir):
             os.mkdir(plotly_dir)
             
          self.path_dir_plotly_html = os.getcwd() + os.sep + plotly_dir
          
       def get_plotly_path_if_hs300_bais(self,file_name='if_hs300_bais.html'):
          path_plotly = self.path_dir_plotly_html + os.sep + file_name
          df = pd.read_excel(r'if_index_bais.xlsx')
          
          '''绘制散点图'''
          line_main_price = go.Scatter(
             x=df.index,
             y=df['main_price'],
             name='main_price',
             connectgaps=True, # 这个参数表示允许连接数据缺口
          )
          
          line_hs300_close = go.Scatter(
             x=df.index,
             y=df['hs300_close'],
             name='hs300_close',
             connectgaps=True,
          )
          data = [line_hs300_close,line_main_price]
    
          layout = dict(title='if_hs300_bais',
                     xaxis=dict(title='Date'),
                     yaxis=dict(title='Price'),
                     )
    
          fig = go.Figure(data=data, layout=layout)  
          pyof.plot(fig, filename=path_plotly, auto_open=False)
          return path_plotly
          
       def get_plot_path_matplotlib_plotly(self,file_name='matplotlib_plotly.html'):
          path_plotly = self.path_dir_plotly_html + os.sep + file_name
    
          N = 50
          x = np.random.rand(N)
          y = np.random.rand(N)
          colors = np.random.rand(N)
          area = np.pi * (15 * np.random.rand(N)) ** 2  # 0 to 15 point radii
          scatter_mpl_fig = plt.figure()
          plt.scatter(x, y, s=area, c=colors, alpha=0.5)
    
          pyof.plot_mpl(scatter_mpl_fig, filename=path_plotly, resize=True,auto_open=False)
          return path_plotly
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    主程序

    from PyQt5.QtCore import pyqtSlot
    from PyQt5.QtWidgets import QMainWindow
    
    from Ui_plotly_pyqt import Ui_MainWindow
    
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    import sys
    from Plotly_PyQt5 import Plotly_PyQt5
    
    
    class MainWindow(QMainWindow, Ui_MainWindow):
        """
        Class documentation goes here.
        """
    
        def __init__(self, parent=None):
            """
            Constructor
    
            @param parent reference to the parent widget
            @type QWidget
            """
            super(MainWindow, self).__init__(parent)
            self.setupUi(self)
            self.plotly_pyqt5 = Plotly_PyQt5()
            self.qwebengine.setGeometry(QRect(50, 20, 1200, 600))
            self.qwebengine.load(QUrl.fromLocalFile(self.plotly_pyqt5.get_plotly_path_if_hs300_bais()))
    
    
    app = QApplication(sys.argv)
    win = MainWindow()
    win.showMaximized()
    app.exec_()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    运行

    在这里插入图片描述

    9.6.5 更多扩展

    https://plot.ly/python

    根据相关案例,修改函数,得到想要的绘图结果

    9.6.6 Plotly与PyQt5.6的结合

    使用QWebView与Plotly进行交互

    在这里插入图片描述

    在新版本里面,官方已经把QtWebKitWidgets这个东西移除了

    在这里插入图片描述

    使用QtWebEngineWidgets替代它

    ui.py

    # -*- coding: utf-8 -*-
    
    # Form implementation generated from reading ui file 'plotly_matplotlib_pyqt.ui'
    #
    # Created by: PyQt5 UI code generator 5.6
    #
    # WARNING! All changes made in this file will be lost!
    
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.resize(800, 600)
            self.centralwidget = QtWidgets.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
            self.webView = QtWebEngineWidgets.QWebEngineView(self.centralwidget)
            self.webView.setGeometry(QtCore.QRect(50, 50, 300, 200))
            self.webView.setUrl(QtCore.QUrl("about:blank"))
            self.webView.setObjectName("webView")
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtWidgets.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
            self.menubar.setObjectName("menubar")
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtWidgets.QStatusBar(MainWindow)
            self.statusbar.setObjectName("statusbar")
            MainWindow.setStatusBar(self.statusbar)
    
            self.retranslateUi(MainWindow)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
    
        def retranslateUi(self, MainWindow):
            _translate = QtCore.QCoreApplication.translate
            MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
    
    from PyQt5 import QtWebEngineWidgets
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    调用主程序

    from PyQt5.QtCore import pyqtSlot
    from PyQt5.QtWidgets import QMainWindow
    
    from Ui_plotly_matplotlib_pyqt import Ui_MainWindow
    
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    import sys
    from Plotly_PyQt5 import Plotly_PyQt5
    
    
    class MainWindow(QMainWindow, Ui_MainWindow):
        """
        Class documentation goes here.
        """
    
        def __init__(self, parent=None):
            """
            Constructor
    
            @param parent reference to the parent widget
            @type QWidget
            """
            super(MainWindow, self).__init__(parent)
            self.setupUi(self)
            self.plotly_pyqt5 = Plotly_PyQt5()
            self.webView.setGeometry(QRect(50, 20, 1200, 600))
            self.webView.load(QUrl.fromLocalFile(self.plotly_pyqt5.get_plot_path_matplotlib_plotly()))
    
    
    app = QApplication(sys.argv)
    win = MainWindow()
    win.showMaximized()
    app.exec_()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    运行

    在这里插入图片描述

    报错了,跟着找过去

    在这里插入图片描述

    意思好像这个不能用了

    开始谷歌…

    在这里插入图片描述

    找到这个了

    仿佛是版本问题

    在这里插入图片描述

    啊这

    在这里插入图片描述

    好的,那就把版本降到3.2

    在这里插入图片描述

    在这里插入图片描述

    再试一次

    在这里插入图片描述

    完美解决。

    9.6.7 更多扩展

    https://matplotlib.org/stable/gallery/index.html

    在官网获取示例,修改在这里插入图片描述

    这个函数,使用QWebEngineView间接实现交互。

  • 相关阅读:
    Java Multithreading
    webgl 系列 —— 绘制一个点(版本2、版本3、版本4、版本5)
    LeetCode_排序_中等_912.排序数组
    想裁剪视频时长,用电脑怎么裁剪视频时长
    十五. 实战——mysql建库建表 字符集 和 排序规则
    752.打开转盘锁 | 773.滑动谜题
    MTK Pump Express 快速充电原理分析
    Frp内网穿透
    程序员 40 岁之后的出路在哪里?
    制药企业GMP合规检查要点有哪些?
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/126082094