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_())

效果图:

相关推荐
留白_6 天前
Matplotlib绘图
信息可视化·数据分析·matplotlib
MATLAB代码顾问6 天前
Python Matplotlib数据可视化实战指南
python·信息可视化·matplotlib
王小王-1237 天前
基于机器学习算法的恶意软件行为分析与检测系统设计与实现
机器学习·pyqt5·检测系统·恶意软件行为检测
星辰徐哥8 天前
Python AI基础:Matplotlib与Seaborn数据可视化
人工智能·python·matplotlib
斐夷所非8 天前
Python Matplotlib | 基础绘图、复杂函数图与三维图
matplotlib
恣艺12 天前
解决 PyCharm 2024.1+ matplotlib 图表显示异常:Plots 工具窗口空白 / tostring_rgb 报错
ide·pycharm·matplotlib
是上好佳佳佳呀13 天前
【数据分析|Day02】Matplotlib 数据可视化笔记
笔记·matplotlib
ice81303318113 天前
【Python】Matplotlib折线图绘制
开发语言·python·matplotlib
北暮城南15 天前
使用 Claude Code 高效实现图像边缘检测:多算法对比与工程实践
python·opencv·numpy·matplotlib·边缘检测·claude code
red2brick17 天前
【使用PyQt6与Matplotlib编写交互式生成一元二次函数图形程序】
matplotlib