首页 > 其他分享 >PyQt,PySide2中嵌入Matplotlib图像

PyQt,PySide2中嵌入Matplotlib图像

时间:2023-07-12 15:36:25浏览次数:42  
标签:__ self Matplotlib PyQt matplotlib ui PySide2 np import

PyQt,PySide2中嵌入Matplotlib图像
方式1
使用Qt Designer新建一个Main Window,在此之上创建一个Vertical Layout。

import sys
import numpy as np

from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication

import matplotlib
matplotlib.use("Qt5Agg")
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号

class FigureCanvasDemo1(FigureCanvas):
    def __init__(self):
        fig = Figure()
        FigureCanvas.__init__(self, fig)
        self.axes = fig.add_subplot()

        # 开始作图
        x = np.linspace(0, 10, 100)
        y = 2 * np.sin(2 * x)
        self.axes.plot(x, y)
        self.axes.set_title('样例-sin图像')

        self.axes.grid()
        self.draw()


class MainWindow():
    def __init__(self):
        super().__init__()
        loader = QUiLoader()
        # 加载之前新建的ui文件
        self.ui = loader.load("./ui/PicDemo1.ui")

        self.plot = FigureCanvasDemo1()
        layout = self.ui.verticalLayout
        layout.addWidget(self.plot)
        self.ui.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainwindow = MainWindow()
    mainwindow.ui.show()
sys.exit(app.exec_())

显示效果

方式2
使用Qt Designer新建一个Main Window,在此之上创建一个Graphics View。

import sys
import numpy as np

from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication, QGraphicsScene

import matplotlib
matplotlib.use("Qt5Agg")
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号


class FigureCanvasDemo2(FigureCanvas):
    def __init__(self, parent=None, width=10, height=5):
        # 创建一个Figure 如果不加figsize 显示图像过大 需要缩小
        fig = plt.Figure(figsize=(width, height), tight_layout=True)  # tight_layout: 用于去除画图时两边的空白

        FigureCanvas.__init__(self, fig)  # 初始化父类
        self.setParent(parent)
        self.axes = fig.add_subplot(111)  # 添加子图
        self.axes.spines['top'].set_visible(False)  # 去掉绘图时上面的横线
        self.axes.spines['right'].set_visible(False)  # 去掉绘图时右面的横线


class MainWindow():
    def __init__(self):
        super().__init__()
        loader = QUiLoader().load("./ui/PicDemo2.ui")  # 加载之前新建的ui文件

        # 缩小图像尺寸
        self.visual_data = FigureCanvasDemo2(width=self.ui.graphicsView.width() / 101,
                                            height=self.ui.graphicsView.height() / 101)
        x = np.linspace(0, 10, 100)
        y = 2 * np.sin(2 * x)
        self.visual_data.axes.plot(x, y)
        self.visual_data.axes.grid()

        # 加载的图形(FigureCanvas)不能直接放到graphicview控件中,必须先放到graphicScene,然后再把graphicscene放到graphicview中
        self.graphicsScene = QGraphicsScene()  # 创建一个QGraphicsScene
        # 把图形放到QGraphicsScene中,注意:图形是作为一个QWidget放到放到QGraphicsScene中的
        self.graphicsScene.addWidget(self.visual_data)
        # 把QGraphicsScene放入QGraphicsView中
        # self.ui 后跟的是对象的名字 这里QGraphicsView对象的名字是graphicsView
        self.ui.graphicsView.setScene(self.graphicsScene)
        self.ui.graphicsView.show()  # 调用show方法呈现图形

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainwindow = MainWindow()
    mainwindow.ui.show()
    sys.exit(app.exec_())

显示效果

方式3
ui文件同方式2,还是GraphicsView

import sys
import numpy as np

from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication, QGraphicsScene

import matplotlib
matplotlib.use("Qt5Agg")
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号


class FigureCanvasDemo3(FigureCanvas):
    def __init__(self, parent=None, width=10, height=5):
        fig = Figure(figsize=(width, height), tight_layout=True)
        FigureCanvas.__init__(self, fig)
        self.axes = fig.add_subplot()

        # 开始作图
        x = np.linspace(0, 10, 100)
        y = 2 * np.sin(2 * x)
        self.axes.plot(x, y)
        self.axes.set_title('样例-sin图像')

        self.axes.grid()
        self.draw()


class MainWindow():
    def __init__(self):
        super().__init__()
        loader = QUiLoader()
        # 加载之前新建的ui文件
        self.ui = loader.load("./ui/PicDemo2.ui")

        self.plot = FigureCanvasDemo3(
            width=self.ui.graphicsView.width() / 101,
            height=self.ui.graphicsView.height() / 101
        )
        self.graphicsScene = QGraphicsScene()  # 创建一个QGraphicsScene
        self.graphicsScene.addWidget(self.plot)
        self.ui.graphicsView.setScene(self.graphicsScene)
        self.ui.graphicsView.show()  # 调用show方法呈现图形


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainwindow = MainWindow()
    mainwindow.ui.show()
    sys.exit(app.exec_())

显示效果

在PyQt5设计的GUI界面中显示matplotlib绘制的图形

一、matplotlib如何嵌入PyQt5中?

通过matplotlib.backends.backend_qt5agg类连接PyQt5。在实际代码中,我们需要在引用部分加入内容:

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

二、如何使用FigureCanvas和Figure类

在使用FigureCanvas和Figure类创建plot绘制窗口时设计的相关内容可参考:
【matplotlib.figure类】https://matplotlib.org/api/figure_api.html
【backend类】https://matplotlib.org/api/index_backend_api.html
其中构造函数Figure()用来创建一个类似Matlab的figure()或matplotlib.pyplot的figure()。

class matplotlib.figure.Figure(figsize=None, dpi=None,
facecolor=None, edgecolor=None, linewidth=0.0,
tight_layout=None, constrained_layout=None)
例如:
width=5, height=4, dpi=100
self.fig = Figure(figsize=(width, height), dpi=dpi)
其中:width,height,为窗口尺寸,5英寸*4英寸,分辨率为dpi=100
另外一个函数是:add_subplot(221)
它是用来创建子图,如图matlab的subplot(2,2,1),表示共有4个子图,当前为第一个子图。具体应用如下:

sefl.axes = self.fig.add_subplot(221)
1
然后在self.axes中绘制图形如下:

t = np.arange(0.0, 3.0, 0.01)
s = np.sin(2 * np.pi * t)
self.axes.plot(t, s)

上述介绍的是使用Figure和subplot如何绘制图形,图形是可以绘制了,但是怎么将其在Gui界面控件中显示呢?

三、如何将图形显示在Gui控件上?

图形:正弦曲线,使用Figure实现的self.axes.plot(t, s)
GUi:Widget、Dialog和MainWindow三种窗口类型
控件(部件):
1)QTabWidget()部件的页面上
2)QGraphicsView图形视图
3)QgroupBox组框控件
4)还有其他可以作为Ui容器的控件都可以
【因为创建的Figure本身是一个部件,它也是PyQt中的Widget,所以我们只需要将创建的图形添加到GUI界面中的容器控件中即可显示图形。】

例1 在对话框中添加一个Widget中心部件,然后再在中心部件中添加一个GroupBox部件,保存ui文件(使用Qt designer)。并将其转为.py文件,代码如下:

# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'testplot2pyqt5.ui'
# Created by: PyQt5 UI code generator 5.10
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(718, 515)
        self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
        self.buttonBox.setGeometry(QtCore.QRect(370, 470, 341, 32))
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.widget = QtWidgets.QWidget(Dialog)
        self.widget.setGeometry(QtCore.QRect(10, 10, 691, 451))
        self.widget.setObjectName("widget")
        self.groupBox = QtWidgets.QGroupBox(self.widget)
        self.groupBox.setGeometry(QtCore.QRect(0, 0, 691, 451))
        self.groupBox.setObjectName("groupBox")

        self.retranslateUi(Dialog)
        self.buttonBox.accepted.connect(Dialog.accept)
        self.buttonBox.rejected.connect(Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.groupBox.setTitle(_translate("Dialog", "GroupBox_Matplotlib的图形显示:"))

下面另新建一个python文件用于写主函数部分,具体代码如下:

#-*-coding:utf-8-*-
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
import numpy as np
from testplot2pyqt5 import Ui_Dialog

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

#创建一个matplotlib图形绘制类
class MyFigure(FigureCanvas):
    def __init__(self,width=5, height=4, dpi=100):
        #第一步:创建一个创建Figure
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        #第二步:在父类中激活Figure窗口
        super(MyFigure,self).__init__(self.fig) #此句必不可少,否则不能显示图形
        #第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
        self.axes = self.fig.add_subplot(111)
    #第四步:就是画图,【可以在此类中画,也可以在其它类中画】
    def plotsin(self):
        self.axes0 = self.fig.add_subplot(111)
        t = np.arange(0.0, 3.0, 0.01)
        s = np.sin(2 * np.pi * t)
        self.axes0.plot(t, s)
    def plotcos(self):
        t = np.arange(0.0, 3.0, 0.01)
        s = np.sin(2 * np.pi * t)
        self.axes.plot(t, s)


class MainDialogImgBW(QDialog,Ui_Dialog):
    def __init__(self):
        super(MainDialogImgBW,self).__init__()
        self.setupUi(self)
        self.setWindowTitle("显示matplotlib绘制图形")
        self.setMinimumSize(0,0)

        #第五步:定义MyFigure类的一个实例
        self.F = MyFigure(width=3, height=2, dpi=100)
        #self.F.plotsin()
        self.plotcos()
        #第六步:在GUI的groupBox中创建一个布局,用于添加MyFigure类的实例(即图形)后其他部件。
        self.gridlayout = QGridLayout(self.groupBox)  # 继承容器groupBox
        self.gridlayout.addWidget(self.F,0,1)

        #补充:另创建一个实例绘图并显示
        self.plotother()

    def plotcos(self):
        t = np.arange(0.0, 5.0, 0.01)
        s = np.cos(2 * np.pi * t)
        self.F.axes.plot(t, s)
        self.F.fig.suptitle("cos")
    def plotother(self):
        F1 = MyFigure(width=5, height=4, dpi=100)
        F1.fig.suptitle("Figuer_4")
        F1.axes1 = F1.fig.add_subplot(221)
        x = np.arange(0, 50)
        y = np.random.rand(50)
        F1.axes1.hist(y, bins=50)
        F1.axes1.plot(x, y)
        F1.axes1.bar(x, y)
        F1.axes1.set_title("hist")
        F1.axes2 = F1.fig.add_subplot(222)

  ## 调用figure下面的add_subplot方法,类似于matplotlib.pyplot下面的subplot方法
        x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        y = [23, 21, 32, 13, 3, 132, 13, 3, 1]
        F1.axes2.plot(x, y)
        F1.axes2.set_title("line")
        # 散点图
        F1.axes3 = F1.fig.add_subplot(223)
        F1.axes3.scatter(np.random.rand(20), np.random.rand(20))
        F1.axes3.set_title("scatter")
        # 折线图
        F1.axes4 = F1.fig.add_subplot(224)
        x = np.arange(0, 5, 0.1)
        F1.axes4.plot(x, np.sin(x), x, np.cos(x))
        F1.axes4.set_title("sincos")
        self.gridlayout.addWidget(F1, 0, 2)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = MainDialogImgBW()
    main.show()
    #app.installEventFilter(main)
    sys.exit(app.exec_())

结果如下图:

例2,在上例基础上,添加一个TabWidget控件,将绘制的图形显示在Tabwidget控件中。【主要修改第六步即可】

第五步:定义MyFigure类的一个实例

        self.F = MyFigure(width=3, height=2, dpi=100)
        #self.F.plotsin()
        self.plotcos()
        #**修改第六步**:在GUI的groupBox中创建一个布局,用于添加MyFigure类的实例(即图形)后其他部件。
        # self.gridlayout = QGridLayout(self.groupBox)  # 继承容器groupBox
        # self.gridlayout.addWidget(self.F,0,1)


        vlayout = QVBoxLayout(self.widget)   #在中心部件上创建一个布局添加TabWidget控件
        self.tabwidget = QTabWidget()  # 添加一个Tab控件用于存放显示图像的部件
        #下面这些属性设置可不要
        self.tabwidget.setTabsClosable(True)
        self.tabwidget.setUsesScrollButtons(True)
        self.tabwidget.setTabPosition(0)
        self.tabwidget.setElideMode(2)
        self.tabwidget.setMovable(True)
        self.tabwidget.resize(300, 500)

        vlayout.addWidget(self.tabwidget)

        self.gridlayout1 = QGridLayout(self.tabwidget)
        self.gridlayout1.addWidget(self.F,0,0)

结果:

例3 同样在例1基础上修改第六步,在GroupBox框中添加QGraphicsView视图窗口显示图形,具体修改如下:

修改第六步:在groupBox框中使用QGraphicsView控件来显示

        self.gridlayout = QGridLayout(self.groupBox)  # 继承容器groupBox
        self.graphicsview = QGraphicsView(self.groupBox)
        self.gridlayout.addWidget(self.graphicsview, 1, 0)

        self.scene = QGraphicsScene()  #创建一个场景
        self.scene.addWidget(self.F)   #将图形元素添加到场景中
        self.graphicsview.setScene(self.scene) #将创建添加到图形视图显示窗口
        self.graphicsview.show()       #显示

结果:

从3个结果图我们可以看出,例3使用GraphicsView显示比较浪费空间,显示不够饱满,例1和例2显示效果较好些。

标签:__,self,Matplotlib,PyQt,matplotlib,ui,PySide2,np,import
From: https://www.cnblogs.com/HeroZhang/p/17547573.html

相关文章

  • pyqt5-pyqtSignal信号
    1、介绍pyqt项目中,子线程中存在两种需求:子线程结束时,以信号的形式触发事件,调用方法,与ui组件交互子线程运行过程中,持续以信号的形式触发事件,调用方法与ui组件交互可以基于pyqtSignal实现。(189条消息)【python编程】使用pyqtsignal实现消息回调的注意事项_时空worker的博客......
  • python: PyQt5 beginner
     fromPyQt5.QtWidgetsimportQWidget,QApplication,QMainWindow,QLabel,QPushButtonfromPyQt5importQtCore,QtGuiimportsysimportosdefclick():print("HyButtonisclicked!")#Pressthegreenbuttonintheguttertorunthescri......
  • 【慢慢买嗅探神器】基于scrapy+pyqt的电商数据爬虫系统
    项目预览项目演示代码部分爬虫模块GUI......
  • python环境问题--import matplotlib.pyplot as plt报错
        python环境配置好后,刚开始没问题,过几天用vscode写python代码的时候,突然导matplotlib包报错:DLLloadfailed:找不到指定的模块。    首先定位报错的具体代码,发现是导入matplotlib包报错,去掉那条命令后程序正常执行,然后继续尝试,importmatplotlib没有问题,但是im......
  • matplotlib.pyplot箱线图绘制
    读取csv数据,并画出箱线图importmatplotlib.pyplotaspltimportpandasaspddefdraw_box(csv_file_path):data=pd.read_csv(csv_file_path,encoding='utf-8')plt.rc('font',family='TimesNewRoman')data=data.iloc[:,1:]......
  • pyqt5-样式设置
    1、介绍pyqt5中,允许通过类似css的层叠样式表的形式,直接为组件声明显示样式,比如设置字体、字体颜色和背景色等。具体的是,是通过QWidget类中声明的setStyle或setStyleSheet方法设置。setStyle(self,a0:QStyle)setStyleSheet(self,styleSheet:str)style(self)->QStylesty......
  • matplotlib基础
    绘图与可视化如果想在jupyternotebook中使用%matplotlibnotebook导入matplotlib包importmatplotlib.pyplotasplt直接生成一个简单图形data=np.arange(10)plt.plot(data)matplotlib所绘制的图位于Figure对象中,使用plt.figure就生成一个图片fig=plt.figure()不能......
  • 玩转Matplotlib的10个高级技巧
    Matplotlib是Python中流行的数据可视化库,仅使用简单的几行代码就可以生成图表。但是默认的方法是生成的图表很简单,如果想增强数据演示的影响和清晰度,可以试试本文总结的10个高级技巧,这些技巧可以将可视化提升到一个新的水平:https://avoid.overfit.cn/post/fece2cde8dbd4f899de0......
  • pyqt5-QPlainTextEdit与文本详解
    1、纯文本setPlainText(self,text:str)直接设置普通文本,不显示任何样式是组件整体进行设值appendPlainText(self,text:str)拼接纯文本如果拼接前的组件中已经输出文本,会换行再输出纯文本。如果未输出,则直接在首行输出纯文本insertPlainText(self,text:str)在......
  • [python] 基于matplotlib-scalebar库绘制比例尺
    matplotlib-scalebar是一个Python库,用于在matplotlib图形中添加比例尺。它允许用户指定比例尺的大小、位置、字体和颜色,以及比例尺的单位。该库支持不同的比例尺单位,例如米、英尺、英寸等。matplotlib-scalebar安装命令如下:pipinstallmatplotlib-scalebar比例尺是一种用于描......