matplotlib 与 PyQt5 结合使用——PyQt5

1. 文档参考

Matplotlib官方使用文档:

Getting started --- Matplotlib 3.10.9 documentation

详细的用法可参考:

Matplotlib 图表------PyQt5、Python-CSDN博客

2.示例

2.1 单个图表

2.1.1 代码

在网上一搜就搞到了一个小示例:

复制代码
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt

import matplotlib
matplotlib.use('Qt5Agg')  # 必须在 import pyplot 之前执行

import matplotlib.pyplot as plt

class QPlotCanvas(FigureCanvas):
    def __init__(self, parent=None):
        fig, self.ax = plt.subplots()
        super().__init__(fig)
        self.plot()  # 绘制初始图表

    def plot(self):
        x = [0, 1, 2, 3, 4, 5]
        y = [10, 1, 20, 3, 40, 5]
        self.ax.plot(x, y, label='示例数据')
        self.ax.set_title('PyQt5 中的 matplotlib 图表')
        self.ax.legend()

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Matplotlib + PyQt5 示例")
        plt.rcParams['font.sans-serif'] = ['SimSun']  # 使用宋体
        plt.rcParams['axes.unicode_minus'] = False    # 正常显示负号
        self.canvas = QPlotCanvas(self)
        self.setCentralWidget(self.canvas)


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

2.1.2 代码结构分析

看上面的代码,可以看出起主要作用的是类 FigureCanvasQTAgg *,*单看字面意思也可以了解到这个是封装的Qt版的Figure (画布)。大概看了一眼,这个类也是继承了QWidget,所以就可以将其当做是一个控件。

复制代码
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

还看了一下backend_qt5agg.py 文件的内容(自行添加了注解),可以看到供Qt使用的各个类:

复制代码
"""
Render to qt from agg
"""
# 导入Matplotlib的后端模块
from .. import backends

# 【关键】强制Matplotlib使用Qt5绑定,禁用Qt6
backends._QT_FORCE_QT5_BINDING = True

# 从QtAgg基础后端导入核心类(忽略导入检查警告)
from .backend_qtagg import (    # noqa: F401, E402 # pylint: disable=W0611
    _BackendQTAgg,        # 后端基类
    FigureCanvasQTAgg,    # 画布组件(核心渲染)
    FigureManagerQT,      # 窗口管理
    NavigationToolbar2QT, # Qt工具栏
    FigureCanvasAgg,      # AGG渲染引擎
    FigureCanvasQT)       # Qt画布基类

# 导出为Matplotlib官方后端
@_BackendQTAgg.export
# 定义Qt5Agg后端,完全继承QtAgg的所有功能
class _BackendQT5Agg(_BackendQTAgg):
    pass

下方代码看出:自定义类继承了matplotlib的类FigureCanvasQTAgg ,plt.subplots()创建了子图,并将其figure 传给了FigureCanvasQTAgg 进行初始化。

复制代码
class QPlotCanvas(FigureCanvas):
    def __init__(self, parent=None):
        fig, self.ax = plt.subplots()
        super().__init__(fig)

后续跟直接使用Matplotlib创建图表没什么区别了。

复制代码
    def plot(self):
        x = [0, 1, 2, 3, 4, 5]
        y = [10, 1, 20, 3, 40, 5]
        self.ax.plot(x, y, label='示例数据')
        self.ax.set_title('PyQt5 中的 matplotlib 图表')
        self.ax.legend()

关键点,就是将matplotlib.pyplot 创建的figure 传给 FigureCanvasQTAgg(Qt版画布)。

2.1.3 效果图

2.2 显示多个图表

前面展示了一块画布上显示单个图表的用法,如何显示多个图表(子图)。我也进行了尝试,根据自己的猜想:只要将matplotlib.pyplot 创建的figure 传给 FigureCanvasQTAgg,后续直接在画布上添加就可以。

复制代码
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

import numpy as np

import matplotlib
matplotlib.use('Qt5Agg')  # 必须在 import pyplot 之前执行


import matplotlib.pyplot as plt

class QPlotCanvas(FigureCanvas):
    def __init__(self, parent=None):
        # fig, self.ax = plt.subplots()
        # super().__init__(fig)
        # self.plot()  # 绘制初始图表
        self.fig = plt.figure()
        super().__init__(self.fig)
        self.subplots()

    
    def subplots(self):
        #一、折线图(plot)------最常用
        #用途:展示数据随时间/变量的变化趋势
        #plt.subplot(行数, 列数, 子图序号),序号从1开始,从左到右、从上到下排列。
        self.fig.add_subplot(1,3,1)
        #1. 准备数据(模拟股价变化)
        x = np.arange(1,11) #X轴 1~10天
        y = np.array([12,15,13,18,16,20,19,22,25,23]) #Y轴:股价
        #2. 绘制折线图(设置线条颜色,样式,宽度)
        plt.plot(x,y,color = 'red',linestyle='-.',linewidth=2,marker='o',label='股价')
        #3. 添加细节
        plt.title('10天股价变化趋势',fontsize=14) #标题及其字体大小
        plt.xlabel('天数',fontsize=12)
        plt.ylabel('股价(元)',fontsize=12)
        plt.legend()
        plt.grid(True,alpha=0.3) #网格,alpha:(0~1)
        plt.xticks(x) #X轴刻度:显示1~10的所有整数
        
        #二、柱状图(bar/barh)--对比数据
        #用途:对比多个类别数据的差异(如不同产品销量、不同班级分数、不同地区人口)
        plt.subplot(1,2,2)
        #1. 准备数据(模拟不同产品销量)
        products = ['产品A','产品B','产品C','产品D',]
        sales = [500,720,380,650]
        #2. 绘制柱状图(垂直柱状图:bar; 水平柱状图:barh)
        colors = ['#4ECDC4', '#45B7D1', '#3498DB', '#2980B9'] # 蓝色系渐变
        # plt.bar(products,sales,color=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4'], width=0.6)
        plt.bar(products,sales,color=colors, width=0.6)
        #3. 添加细节(给每个柱子添加数值标签)
        for i,v in enumerate(sales):
            plt.text(i,v+10,str(v),ha='center',fontsize=10) #数值标签位置、对齐方式
        plt.title('不同产品销量对比',fontsize=14)
        plt.xlabel('产品名称',fontsize=12)
        plt.ylabel('销量(件)',fontsize=12)
        plt.grid(True,axis='y',alpha=0.3)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Matplotlib + PyQt5 示例")
        plt.rcParams['font.sans-serif'] = ['SimSun']  # 使用
        plt.rcParams['axes.unicode_minus'] = False    # 正常显示负号
        self.canvas = QPlotCanvas(self)
        self.setCentralWidget(self.canvas)


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

效果图:

相关推荐
风流 少年1 天前
数据可视化:matplotlib、pyecharts、panda、seaborn
数据挖掘·数据分析·matplotlib
fai厅的秃头姐!1 天前
Matplotlib
matplotlib
许彰午4 天前
78_Python数据可视化matplotlib
python·信息可视化·matplotlib
尘中远7 天前
【Qwt 7.0 系列】总体架构解析 —— 从单体到三库模块化的演进
qt·matplotlib·绘图·qwt·科学绘图
2501_942389557 天前
AI才女”罗福莉加盟小米
matplotlib·sublime text·广度优先·gunicorn
兵慌码乱18 天前
面向桌面端的资产管理系统分层架构设计与核心模块实现
python·系统架构·sqlite·pyqt5·数据库设计·桌面应用开发·mvc架构
兵慌码乱19 天前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·sqlite·信号与槽·pyqt5·数据库设计·桌面应用开发·事务处理
留白_1 个月前
Matplotlib绘图
信息可视化·数据分析·matplotlib
MATLAB代码顾问1 个月前
Python Matplotlib数据可视化实战指南
python·信息可视化·matplotlib
王小王-1231 个月前
基于机器学习算法的恶意软件行为分析与检测系统设计与实现
机器学习·pyqt5·检测系统·恶意软件行为检测