#!/usr/bin/python
# -*- coding:utf-8 -*-
from __future__ import unicode_literals
import sys
import os
import random
import matplotlib
# Make sure that we are using QT5
matplotlib.use('Qt5Agg')
from PyQt5 import QtCore, QtWidgets
from numpy import arange, sin, pi
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
progname = os.path.basename(sys.argv[0])
progversion = "0.1"
class MyMplCanvas(FigureCanvas):
""" 继承FigureCanvasQTAgg的基类,是一个canvas控件。"""
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111) # 1行1列索引1
self.compute_initial_figure() # 画图函数
FigureCanvas.__init__(self, fig) # 调用父类的初始化函数
self.setParent(parent) # 设置上层控件
FigureCanvas.setSizePolicy(self,
QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self) # 刷新布局
def compute_initial_figure(self):
""" 画图操作函数 """
pass
class MyStaticMplCanvas(MyMplCanvas):
"""Simple canvas with a sine plot."""
def compute_initial_figure(self):
t = arange(0.0, 3.0, 0.01)
s = sin(2*pi*t)
self.axes.plot(t, s)
class MyDynamicMplCanvas(MyMplCanvas):
"""A canvas that updates itself every second with a new plot."""
def __init__(self, *args, **kwargs):
MyMplCanvas.__init__(self, *args, **kwargs)
timer = QtCore.QTimer(self)
timer.timeout.connect(self.update_figure)
timer.start(1000)
def compute_initial_figure(self):
self.axes.plot([0, 1, 2, 3], [1, 2, 0, 4], 'r')
def update_figure(self):
# Build a list of 4 random integers between 0 and 10 (both inclusive)
l = [random.randint(0, 10) for i in range(4)]
self.axes.cla() # 清空子图
self.axes.plot([0, 1, 2, 3], l, 'r') # 设置折线点
self.draw() # 重新画图
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setWindowTitle("application main window")
self.file_menu = QtWidgets.QMenu('&File', self)
self.file_menu.addAction('&Quit', self.fileQuit, QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
self.menuBar().addMenu(self.file_menu)
self.help_menu = QtWidgets.QMenu('&Help', self)
self.menuBar().addSeparator()
self.menuBar().addMenu(self.help_menu)
self.help_menu.addAction('&About', self.about)
self.main_widget = QtWidgets.QWidget(self)
l = QtWidgets.QVBoxLayout(self.main_widget)
sc = MyStaticMplCanvas(self.main_widget, width=5, height=4, dpi=100)
dc = MyDynamicMplCanvas(self.main_widget, width=5, height=4, dpi=100)
l.addWidget(sc)
l.addWidget(dc)
self.main_widget.setFocus()
self.setCentralWidget(self.main_widget)
self.statusBar().showMessage("All hail matplotlib!", 2000)
def fileQuit(self):
self.close()
def closeEvent(self, ce):
self.fileQuit()
def about(self):
QtWidgets.QMessageBox.about(self, "About",
"""embedding_in_qt5.py example
Copyright 2005 Florent Rougon, 2006 Darren Dale, 2015 Jens H Nielsen
This program is a simple example of a Qt5 application embedding matplotlib
canvases.
It may be used and modified with no restriction; raw copies as well as
modified versions may be distributed without limitation.
This is modified from the embedding in qt4 example to show the difference
between qt4 and qt5"""
)
qApp = QtWidgets.QApplication(sys.argv)
aw = ApplicationWindow()
aw.setWindowTitle("%s" % progname)
aw.show()
sys.exit(qApp.exec_())
FigureCanvasQTAgg是实现matplotlib嵌入到PyQt5的关键类,用于实现绘图操作。创建一个继承FigureCanvasQTAgg的自定义类,并在__init__()方法中调用绘图操作。axes属性用于实现画图操作。
自定义类实际上就是一个canvas,可以当作一般的控件widget,放到布局Layout中。
l = QtWidgets.QVBoxLayout(self.main_widget) sc = MyStaticMplCanvas(self.main_widget, width=5, height=4, dpi=100) dc = MyDynamicMplCanvas(self.main_widget, width=5, height=4, dpi=100) l.addWidget(sc) l.addWidget(dc)
上面例子中,class MyMplCanvas(FigureCanvas): 是基类,定义了画图类的初始化流程和实现画图的接口
def compute_initial_figure(self): """ 画图操作函数 """ pass
后面定义了两个画图类,实现具体的画图。
第一个是画静态图:
def compute_initial_figure(self): t = arange(0.0, 3.0, 0.01) s = sin(2*pi*t) self.axes.plot(t, s)
第二个是画动态图,每一秒钟清空子图,重新计算曲线参数,再画图:
def __init__(self, *args, **kwargs): MyMplCanvas.__init__(self, *args, **kwargs) timer = QtCore.QTimer(self) timer.timeout.connect(self.update_figure) timer.start(1000) def compute_initial_figure(self): self.axes.plot([0, 1, 2, 3], [1, 2, 0, 4], 'r') def update_figure(self): # Build a list of 4 random integers between 0 and 10 (both inclusive) l = [random.randint(0, 10) for i in range(4)] self.axes.cla() # 清空子图 self.axes.plot([0, 1, 2, 3], l, 'r') # 设置折线点 self.draw() # 重新画图