【PyQt】在PyQt5的界面上集成matplotlib绘制的图像

文章目录

    • 0 前期教程
    • 1 概述
    • 2 matplotlib
      • 2.1 库导入
      • 2.2 图片的各个部分解释
      • 2.3 代码风格
      • 2.4 后端
    • 3 集成matplotlib图像到pyqt界面中
      • 3.1 使用到的模块
      • 3.2 理解Qt Designer中的“控件提升”
      • 3.3 界面与逻辑分离的思路
      • 3.4 扩展

0 前期教程

  • 【PyQt】PyQt5进阶——串口上位机及实时数据显示

1 概述

  在上面的前期教程中,介绍了在PyQt5中如何绘制曲线,是使用PyQt5的一些第三方扩展包来实现的,但是提到python中的画图,matplotlib才是最受欢迎的工具,因此,在PyQt5界面中集成一个matplotlib绘制的图非常有用。

2 matplotlib

  在开始之前,我们先来系统地复习一下matplotlib这个库。学习一个库,首先要参考的肯定是官网——https://matplotlib.org/stable/

  如果使用这个库较多,强烈建议完整看一遍Quick start guide,这样会对这个库有一个整体的认识,也更利于理解他人的代码。以下内容也基本摘自该教程。

2.1 库导入

  首先是库导入,一般采用以下这种方式:

import matplotlib.pyplot as plt
import numpy as npimport matplotlib as mpl

注意:在一些比较老的代码中,可能会看到import matplotlib.pylab as plt这样的代码,这个pylab是已经被弃用的库。

2.2 图片的各个部分解释

  在绘制一些相对复杂的图时,首先要理解一张图片中各个部分分别对应什么,这样更便于使用对应的函数以及查找相关的资料。以下这张图也摘自官网,详细介绍了一张图的各个部分及其对应的类和函数,非常详细,值得反复阅读。

在这里插入图片描述
注意,这里的ax来自以下代码:

fig, ax = plt.subplots()  # Create a figure containing a single axes.
ax.plot([1, 2, 3, 4], [1, 4, 2, 3])  # Plot some data on the axes.

2.3 代码风格

  在绘制图像方面,主要有两种常用的类型。分为显式接口(explicit interfaces)隐式接口(implicit interfaces),其中,所谓显式接口是使用面向对象的方式(object-oriented (OO) style);而隐式接口则是使用pyplot这个模块隐式地创建和管理图像和坐标轴等对象,即只使用pyplot里面的函数即可。

  • 显式接口

    x = np.linspace(0, 2, 100)  # Sample data.# Note that even in the OO-style, we use `.pyplot.figure` to create the Figure.
    fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
    ax.plot(x, x, label='linear')  # Plot some data on the axes.
    ax.plot(x, x**2, label='quadratic')  # Plot more data on the axes...
    ax.plot(x, x**3, label='cubic')  # ... and some more.
    ax.set_xlabel('x label')  # Add an x-label to the axes.
    ax.set_ylabel('y label')  # Add a y-label to the axes.
    ax.set_title("Simple Plot")  # Add a title to the axes.
    ax.legend()  # Add a legend.
    plt.show()   # display
    

在这里插入图片描述

  • 隐式接口

    x = np.linspace(0, 2, 100)  # Sample data.plt.figure(figsize=(5, 2.7), layout='constrained')
    plt.plot(x, x, label='linear')  # Plot some data on the (implicit) axes.
    plt.plot(x, x**2, label='quadratic')  # etc.
    plt.plot(x, x**3, label='cubic')
    plt.xlabel('x label')
    plt.ylabel('y label')
    plt.title("Simple Plot")
    plt.legend()
    plt.show()   # display
    

在这里插入图片描述

图片绘制方面,还有更丰富的一些设置,如设置线的样式(styling),或者在图片上增加标注(labelling)等,具体建议参考官网的教程。

2.4 后端

  所谓后端(backends),和网页的前端后端我认为概念上类似,但又有点区别,简而言之,对画图而言,前端即是画什么样的图,而后端则是在哪画图,即显示在哪

  根据官网的教程,matplotlib内部有多种后端可供选择,如Qt,GTK,wxWidgets,OSX,Tk等,分别对应的代码为:qtagg, GTK4Agg, GTK3Agg, wxAgg, macosx, TkAgg。此外,它还支持非内置的后端。
  指定后端的方式有三种:

  • 在 matplotlibrc 文件中设置 rcParams["backend"],如backend : qtagg
  • 在shell中设置 MPLBACKEND 环境变量,如在Windows端执行这个代码 set MPLBACKEND=qtagg
  • 在python脚本中增加代码:import matplotlib matplotlib.use('qtagg')

  很显然,在Windows上集成图像到Qt界面上最简单的办法就是第三种。

3 集成matplotlib图像到pyqt界面中

3.1 使用到的模块

  在大部分的教程中,一般都会有这样几行代码:

import matplotlib as mpl
mpl.use('Qt5Agg')
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

其中,前两行是指定后端,第三行导入的FigureCanvasQTAgg实际上也是一个Qt的控件,也可以像一般的控件一样添加到Qt的窗口中,它相当于是一个画布,并不直接画图;而第四行导入的figure就是图像本身了,用于画图的各种操作。

3.2 理解Qt Designer中的“控件提升”

  控件提升操作在上面的前期教程中也有使用过,但是当时并没有对此理解很深入,只知道这样做而已。经过对比转换得到的py代码,发现所谓的控件提升,其实就是替换,即将放置的控件替换为其他的Qt控件,比如之前的QChartView和这里的FigureCanvasQTAgg,都是Qt控件,所以可以直接替换。原控件的作用主要设置布局和大小等外部特性。

  可以自行尝试一下,拖动一个widget到窗口,然后将其提升,内容可以随便写,再转换成python代码,观察填写的内容在实际代码中的体现。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

从上面的实践可以看出,实际上被提升的控件是什么类型并不重要,只要可以提升就行。常用的有Qwidget,QFrame等。

3.3 界面与逻辑分离的思路

  之所以要介绍上述的控件提升,就是为在集成matplotlib图像到pyqt界面过程中也保持界面和逻辑分离的状态
  为了实现这一目标,首先建立一个文件,命名为FigureCanvas.py(可以随便取),写入以下代码:

import matplotlib as mpl
mpl.use('Qt5Agg')
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figureclass MyFigure(FigureCanvas):def __init__(self, parent=None):self.fig = Figure()super().__init__(self.fig)self.axes = self.fig.add_subplot(111)def plot(self, *args, **kwargs):self.axes.clear()                 # 清除之前的图像self.axes.plot(*args, **kwargs)   # 画图self.fig.canvas.draw()            # 刷新画布

可以看到,内容非常简单,就是在前面介绍的头文件基础上,新建了一个类而已,这个类除了初始化函数外也就只有一个刷新图像界面的函数。
  然后在Qt Designer中添加一个widget控件,再把它提升一下:由于导入关系是from FigureCanvas import MyFigure,所以类名称为MyFigure,头文件为FigureCanvas

  最后,就是再新建一个py文件编写逻辑和界面显示等内容了,这里可以参考前期教程,此处不再赘述。

3.4 扩展

  在查找资料过程中,还找到一个方法有点不同的教程,它是使用graphicView控件来实现的,是基于该控件自带的一些函数来实现的。而且也做到了界面和逻辑分离,值得记录一下:链接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/474477.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用例是独立的-《软件方法》自测题解析38

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 《软件方法》第5章自测题2 8 [ 多选题 ] 根据以下业务序列图,请问属于“一卡通系统”用例的有:  A) 外来办事人员→登记  B) 一卡通系统→判断黑名单 …

GIS工具maptalks——初始化

GIS工具maptalks开发手册(一)——hello world初始化 为何使用maptalks? ​ Maptalks项目是一个HTML5的地图引擎, 基于原生ES6、Javascript开发的二三维一体化地图。 通过二维地图的旋转、倾斜增加三维视角,通过插件化设计, 能与其他图形库echarts、d3.j…

如何在 Linux 中安装 s3cmd 并管理 Amazon s3 存储桶

S3, – 简单存储服务- 是亚马逊的存储服务,为 IT 团队提供一种安全、可扩展且可靠的方式来存储和检索云上的文件和文件夹。 S3 可确保数据在需要时可用并随着需求的增长而扩展,从而帮助您充分利用数据。 通常,在登录到您的 AWS 账…

Mybatis源码分析

Mybatis源码分析 第一章、回顾 1. 课程中工具的版本 1. JDK8 2. IDEA2018.3 3. Maven3.5.3 4. MySQL 5.1.48 --> MySQL 5Mybatis 3.4.62. Mybatis开发的简单回顾 1. Mybatis做什么?Mybatis是一个ORM类型框架,解决的数据库访问和操作的问题&#xf…

Manifest merger failed with multiple errors, see logs

问题 Manifest merger failed with multiple errors, see logs详细问题 笔者进行Android 项目开发&#xff0c;修改AndroidManifest.xml代码后&#xff0c;控制台报错 AndroidManifest.xml报错核心代码 <manifest><uses-permission android:name"android.perm…

[03] Vue指令(2)

目录 属性绑定指令(v-bind)列表渲染指令(v-for)v-for中的key 双向绑定指令(v-model) 属性绑定指令(v-bind) 作用&#xff1a;动态设置html的标签属性&#xff0c;比如&#xff1a;src、url、title语法&#xff1a;v-bind:属性名“表达式”v-bind:可以简写成 > : 比如&…

C语言函数调用的流程

函数调用时&#xff0c;进程的上下文会切换到被调函数&#xff0c;当被调函数执行完毕之后再切换回去 函数调用时代码的执行流程

电子商务跨境电商大数据的关键技术之—主流电商大数据采集

大数据采集是指通过各种技术手段和工具收集、获取和提取大规模数据的过程。在信息时代&#xff0c;各种互联网、物联网、移动设备等的普及和应用&#xff0c;产生了海量的数据&#xff0c;这些数据被称为大数据。大数据采集就是对这些数据进行收集和抓取&#xff0c;以获得有意…

SpringBoot+Vue项目部署上线

部署前准备 注册京东云 京东云: https://www.jdcloud.com/ 117.72.32.65vue本地部署 新建文件.env.development VUE_APP_BASEURLhttp://localhost:9191新建文件 .env.production VUE_APP_BASEURLhttp://117.72.32.65:9191main.js 设置全局变量$baseUrl Vue.prototype.$baseUrl…

精品springboot基于大数据的电脑主机硬件选购助手-可视化大屏

《[含文档PPT源码等]精品基于springboot基于大数据的电脑主机硬件选购助手[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; Java——涉及技术&#xff1a; 前端使用技术&a…

11.【CPP】模版(深入理解模版的实例化,从编译链接的原理理解模版为何无法分离编译)

非类型模版参数 1.模版参数分为类型模版参数和非类型模版参数&#xff0c;非类型模版参数一般都是整形常量&#xff08;整形&#xff1a;size_t,int,char等&#xff09; 2.浮点数、类对象以及字符串是不允许作为非类型模版参数的。非类型模版的参数必须在编译的时候就能确定结…

从汇编角度解释线程间互斥-mutex互斥锁与lock_guard的使用

多线程并发的竞态问题 我们创建三个线程同时进行购票&#xff0c;代码如下 #include<iostream> #include<thread> #include<list> using namespace std; //总票数 int ticketCount100; //售票线程 void sellTicket(int idx) {while(ticketCount>0){cou…