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 天前
Python数据可视化:Matplotlib从入门到精通
python·信息可视化·matplotlib
songyuc3 天前
Matplotlib&seaborn学习笔记
笔记·学习·matplotlib
威尔逊·柏斯科·希伯理3 天前
机器学习第一天(共12天)
人工智能·python·机器学习·conda·numpy·pandas·matplotlib
Cloud_Shy61812 天前
Python 数据分析基础入门:《Excel Python:飞速搞定数据分析与处理》学习笔记系列(第十一章 Python 包跟踪器 上篇)
python·数据分析·excel·pandas·matplotlib
键盘上的猫头鹰13 天前
Matplotlib可视化教程:从入门到精通
数据分析·matplotlib
深兰科技15 天前
深兰科技签约乌兹别克斯坦智慧城市项目,推动中国AI出海规模化
人工智能·beautifulsoup·numpy·智慧城市·fastapi·matplotlib·深兰科技
张人玉20 天前
PyCharm配置PyQt5安装报错详情笔记
笔记·qt·pycharm·pyqt5
byzh_rc1 个月前
[AI工具从入门到入土] 命令行
网络·人工智能·python·深度学习·matplotlib
小何code1 个月前
人工智能【第7篇】数据可视化:Matplotlib与Seaborn实战(万字长文+完整代码)
人工智能·机器学习·信息可视化·matplotlib