在PySide2中嵌入matplotlib

 

一、matplotlib简介

    matplotlib是一个Python 2D绘图库,可以生成各种硬拷贝格式和跨平台交互式环境的出版物质量数据。Matplotlib可用于Python脚本,Python和IPython shell,Jupyter笔记本,Web应用程序服务器和四个图形用户界面工具包。

    matplotlib提供了三种不同风格的API供用户使用:

  • pyplot API
  • object-oriented API
  • pylab API(disapproved)

    pyplot API是函数式风格的一组API,借鉴了MATLAB的函数风格,使得matplotlib可以像MATLAB一样工作。

    object-oriented API是面向对象风格的API,如果需要更多自定义绘图及高级使用,建议直接使用这些对象。OOP风格使用到的对象主要有Figure类, Axes类, FigureCanvas类Line2D类

    在matplotlib中,整个图像为一个Figure对象,我们可以开启多个Figure窗口对象。在Figure对象中可以包含一个或者多个Axes对象,每个Axes对象都是一个拥有自己坐标系统的绘图区域,如下图所示。

    绘图区域主要由以下几个元素组成,Title为标题。Axis为坐标轴,Label为坐标轴标注。Tick为刻度线,Tick Label为刻度注释。

    各个对象之间有下面的对象隶属关系:

    了解了OOP风格主要的类元素后,为了实现matplotlib与PySide2的连接,主要对象就是FigureCanvas类, 它代表了具体实现绘图的后端(backend), 之前的分析都是在程序逻辑及OOP层面进行绘图,它必须连接一个后端绘图程序才能真正在屏幕上绘制出图像。可以理解为建房子,我们在设计图纸中设计好了房子的结构,需要施工队来将我们的设计变成现实的建筑。

二、matplotlib布局

    Figure对象有两种添加Axes的方式,第一种就是使用

add_axes([left, bottom, width, height]) #range 0 to 1

    对于这种方式的好处是我们可以自由决定Axes在Figure上的位置及大小,如下图所示

    第二种添加Axes的方式就是使用matplotlib的布局管理器,可以类比PySide2中的layout。

axes = add_subplot(nrows, ncols, position)

    参数一为子图的总行数,参数二为子图的总列数,参数三为子图的位置,返回值为我们添加的Axes对象。

    了解了matplotlib的基本工作原理后,后面对Figure及Axes的具体操作就可以查阅官方文档来获取了。

三、在PySide2中嵌入matplotlib

    之前提到FigureCanvas是连接PySide2与matplotlib的关键,那么为什么FigureCanvas可以连接PySide2与matplotlib呢。

    通过之前的分析我们知道要实现我们的绘图功能,需要一个“施工队”来帮助我们完成这个事情,在matplotlib中也就是backends,关于backends的具体描述可以查阅官方文档,matplotlib有Qt5Agg、TkAgg、WXAgg、GTK3Agg等一系列的backends,这使得我们可以在其他程序中嵌入matplotlib实现我们的绘图功能。     为了便于理解如何通过FigureCanvas连接PySide2与matplotlib,我们从以下两句代码来入手。

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

issubclass(FigureCanvas, QtWidgets.QWidget)

    第一句代码代表FigureCanvas是从backend_qt5agg导入的,那么也就是此时实现绘图的backends为Qt5,即PyQt5与PySide2.     第二句代码的值为True,代表FigureCanvas为QWidget的子类,既然是QWidget的子类,那么我们就可以将其当做QWidget来进行处理,作为我们程序中的小部件来使用。具体的示例可以查阅官方示例Embeddeing in Qt

四、在框架quina中使用matplotlib

    本文最主要的目的是为了在quina中嵌入matplotlib来实现曲线图的绘制功能,quina是在PySide2上封装的一层业务框架,由于涉及公司业务,此处不做详解。一个最简单的嵌入示例程序为

import quina
import numpy as np

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

if __name__ == '__main__':
    # construct MainWindow
    w = quina.widgets.MainWindow()

    # prepare data
    x = np.linspace(1, 10)
    y = x ** 2

    # construct Figure object
    fig = Figure()
    axes = fig.add_subplot(1, 1, 1)
    axes.plot(x, y, 'r')

    # construct FigureCanvas object
    canvas = FigureCanvas(fig)

    # set canvas to center widget in MainWindow
    w.set_central_widget(canvas)

    w.exec()

    程序运行结果如下

参考文献

  1. Little_Rookie的博客-matplotlib绘图总结
  2. Vamei的博客-matplotlib核心剖析
  3. matplotlib官方文档