pyqt5 matlibplot结合使用 简单演示(可直接使用plt)

Pyqt5中使用matplotlib

最初在qtdesigner里面看到QwPlot,但经过查阅,发现这是一个已经没有维护的c++的库,虽然可以找到别人做的对应的python库,但使用起来并不方便,这里推荐结合matplotlib和pyqt5可以实现很好的绘图效果。

设计基本框架

在qtdesigner中做这样一个界面,这里我就简单放一个graohicsView,注意这里的宽度和高度,最好和后面画图时的figure相匹配。
在这里插入图片描述用.ui文件生成的.py文件内容如下,当然你也可以跳过UI,直接用这个文件测试
Test_UI.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'Test_UI.ui'
#
# Created by: PyQt5 UI code generator 5.14.1
#
# 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.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(150, 120, 500, 300))
        self.graphicsView.setObjectName("graphicsView")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 28))
        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"))

这里后面的操作可以分为两种方法,这里推荐第二种方法,第一种作为理解的参考

方法1

创建Figure类

以下最小示例设置了一个 Matplotlib 画布FigureCanvasQTAgg,该画布创建Figure并添加了一组轴。这个画布对象也是一个QWidget,因此可以像任何其他 Qt 小部件一样直接嵌入到应用程序中。

class Figure_Canvas(FigureCanvas):   # 通过继承FigureCanvas类,使得该类既是一个PyQt5的Qwidget,又是一个matplotlib的FigureCanvas,这是连接pyqt5与matplot lib的关键

    def __init__(self, parent=None, width=5, height=3, dpi=100):
        fig = Figure(figsize=(width, height), dpi=100)  # 创建一个Figure,注意:该Figure为matplotlib下的figure,不是matplotlib.pyplot下面的figure

        FigureCanvas.__init__(self, fig) # 初始化父类
        self.setParent(parent)

        self.axes = fig.add_subplot(111) # 调用figure下面的add_subplot方法,类似于matplotlib.pyplot下面的subplot方法

    def test(self):
        x = [1,2,3,4,5,6,7,8,9]
        y = [23,21,32,13,3,132,13,3,1]
        self.axes.plot(x, y)

将绘制的图放到界面中

这里继承我们之前的界面,执行画图操作,将绘制的图放入QGraphicsView,进行显示

class Test_window(QtWidgets.QMainWindow,Test_UI.Ui_MainWindow):
    def __init__(self,parent=None):
        super(Test_window,self).__init__(parent)
        self.setupUi(self)
        dr = Figure_Canvas()
        # 实例化一个FigureCanvas
        time1 =time.time()
        dr.test()  # 画图
        graphicscene = QtWidgets.QGraphicsScene()  # 第三步,创建一个QGraphicsScene,因为加载的图形(FigureCanvas)不能直接放到graphicview控件中,必须先放到graphicScene,然后再把graphicscene放到graphicview中
        graphicscene.addWidget(dr)  # 第四步,把图形放到QGraphicsScene中,注意:图形是作为一个QWidget放到QGraphicsScene中的
        self.graphicsView.setScene(graphicscene)  # 第五步,把QGraphicsScene放入QGraphicsView
        self.graphicsView.show()  # 最后,调用show方法呈现图形!
        time2 = time.time()
        print(time2-time1)

总的就是形成这样一个文件
test_qt.py

import matplotlib
matplotlib.use("Qt5Agg")  # 声明使用QT5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

from PyQt5 import QtWidgets,QtCore
from PyQt5.QtWidgets import QMainWindow,QApplication
import sys

import Test_UI

import time

class Figure_Canvas(FigureCanvas):   # 通过继承FigureCanvas类,使得该类既是一个PyQt5的Qwidget,又是一个matplotlib的FigureCanvas,这是连接pyqt5与matplot lib的关键

    def __init__(self, parent=None, width=5, height=3, dpi=100):
        fig = Figure(figsize=(width, height), dpi=100)  # 创建一个Figure,注意:该Figure为matplotlib下的figure,不是matplotlib.pyplot下面的figure

        FigureCanvas.__init__(self, fig) # 初始化父类
        self.setParent(parent)

        self.axes = fig.add_subplot(111) # 调用figure下面的add_subplot方法,类似于matplotlib.pyplot下面的subplot方法

    def test(self):
        x = [1,2,3,4,5,6,7,8,9]
        y = [23,21,32,13,3,132,13,3,1]
        self.axes.plot(x, y)

class Test_window(QtWidgets.QMainWindow,Test_UI.Ui_MainWindow):
    def __init__(self,parent=None):
        super(Test_window,self).__init__(parent)
        self.setupUi(self)
        dr = Figure_Canvas()
        # 实例化一个FigureCanvas
        time1 =time.time()
        dr.test()  # 画图
        graphicscene = QtWidgets.QGraphicsScene()  # 第三步,创建一个QGraphicsScene,因为加载的图形(FigureCanvas)不能直接放到graphicview控件中,必须先放到graphicScene,然后再把graphicscene放到graphicview中
        graphicscene.addWidget(dr)  # 第四步,把图形放到QGraphicsScene中,注意:图形是作为一个QWidget放到QGraphicsScene中的
        self.graphicsView.setScene(graphicscene)  # 第五步,把QGraphicsScene放入QGraphicsView
        self.graphicsView.show()  # 最后,调用show方法呈现图形!
        time2 = time.time()
        print(time2-time1)




if __name__ == '__main__':
    app = QApplication(sys.argv)
    mytest = Test_window()
    mytest.show()
    app.exec_()

和前面的Test_UI.py放在一起跑就可以得到效果
在这里插入图片描述

方法2

方法1是网上常见的方法我在使用中发现,其不能直接把matplotlib.pyplot 的东西拿来用,所以我测试了这样的做法,发现是可行的,这样就可以直接使用pyplot的方法了

    def plot_test(self):
        figure = plt.figure(figsize=(4, 2), dpi=100)
        canvas = FigureCanvas(figure)
        x = np.arange(1, 1000)
        y = x ** 2
        plt.plot(x, y)
        canvas.draw()  # 这是关键
        return canvas

观察这个函数我们可知还是直接用的plt.figure,这个和方法1就区分开了,后面我们还是用FigureCanvas把这个figure进行包装得到canvas,后续的操作完全按照plt画就行了,最后一定加上canvas,draw(),再返回这个canvas就可以直接再pyqt里面显示

完整代码

import matplotlib
matplotlib.use("Qt5Agg")  # 声明使用QT5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt


import numpy as np

from PyQt5 import QtWidgets,QtCore
from PyQt5.QtWidgets import QMainWindow,QApplication
import sys

import Test_UI

import time


class Test_window(QtWidgets.QMainWindow,Test_UI.Ui_MainWindow):
    def __init__(self,parent=None):
        super(Test_window,self).__init__(parent)
        self.setupUi(self)
        canvas = self.plot_test()
        graphicscene = QtWidgets.QGraphicsScene()  # 第三步,创建一个QGraphicsScene,因为加载的图形(FigureCanvas)不能直接放到graphicview控件中,必须先放到graphicScene,然后再把graphicscene放到graphicview中
        graphicscene.addWidget(canvas)  # 第四步,把图形放到QGraphicsScene中,注意:图形是作为一个QWidget放到QGraphicsScene中的
        self.graphicsView.setScene(graphicscene)  # 第五步,把QGraphicsScene放入QGraphicsView
        self.graphicsView.show()  # 最后,调用show方法呈现图形!

    def plot_test(self):
        figure = plt.figure(figsize=(4, 2), dpi=100)
        canvas = FigureCanvas(figure)
        x = np.arange(1, 1000)
        y = x ** 2
        plt.plot(x, y)
        canvas.draw()  # 这是关键
        return canvas


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mytest = Test_window()
    mytest.show()
    app.exec_()

运行效果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qin_liang/article/details/127018270