matplotlib嵌入PyQt5
作为一个菜鸡选手,最近突然想用python画个统计图并且嵌入到GUI中,初步查询之后发现PyQt5和matplotlib可以满足需求。正好 matplotlib官网有一个例子,就拿来研究了一下,顺便简化了一下,做个记录。
1.导入相关库
import matplotlib as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from PyQt5 import QtWidgets, QtCore#对于matplotlib嵌入Qt来说,QtCore不是必需的
2.创建一个继承FigureCanvasQTAgg的自定义类
FigureCanvasQTAgg是实现matplotlib嵌入到PyQt5的关键类,用于实现绘图操作。创建一个继承FigureCanvasQTAgg的自定义类,并在__init__()方法中调用绘图操作。axes属性用于实现画图操作。
class MyFigureCanvas(FigureCanvas):
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)#添加子图,配置坐标轴
self.compute_initial_figure()#执行画图操作
FigureCanvas.__init__(self, fig)#调用FigureCanvasQTAgg的初始化方法
self.setParent(parent)#设置父窗口,本例中并没有
#设置控件在布局(layout)里面的大小变化的属性。
FigureCanvas.setSizePolicy(self,
QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Expanding)
#用于告知包含该widget的layout:该widget的size hint已发生变化,layout会自动进行调整。
FigureCanvas.updateGeometry(self)
def compute_initial_figure(self):#画图的操作
y = (3, 2, 5, 6, 4)
x = (1, 2, 3, 4, 5)
self.axes.plot(x, y, 'ro--')
3.创建Qt窗口
创建第2步中的自定义类的对象,并将它加入到窗口的布局中。
class MainWindow2(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)#调用父类QMainWindow的初始化方法
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.main_widget = QtWidgets.QWidget(self)#建立主窗口
ll = QtWidgets.QVBoxLayout(self.main_widget)#为主窗口增加一个布局
mc = MyFigureCanvas(self.main_widget, width=5, height=4, dpi=100)#创建上一步中的自定义类的对象
ll.addWidget(mc)#把该对象加入到布局中
self.setCentralWidget(self.main_widget)#把main_widget设置为主窗口
def fileQuit(self):
self.close()
def closeEvent(self, ce):
self.fileQuit()
4.加入执行代码
创建第3步中窗口类的对象,并调用show()方法
if __name__ == '__main__':
qApp = QtWidgets.QApplication(sys.argv)
ui = MainWindow2()
ui.setWindowTitle("Test")
ui.show()
sys.exit(qApp.exec_())
5.运行结果
完整代码:
import matplotlib as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from PyQt5 import QtWidgets, QtCore
import sys
plt.use('Qt5Agg')
class MyFigureCanvas(FigureCanvas):
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
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):
y = (3, 2, 5, 6, 4)
x = (1, 2, 3, 4, 5)
self.axes.plot(x, y, 'ro--')
class MainWindow2(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.main_widget = QtWidgets.QWidget(self)
ll = QtWidgets.QVBoxLayout(self.main_widget)
mc = MyFigureCanvas(self.main_widget, width=5, height=4, dpi=100)
ll.addWidget(mc)
self.main_widget.setFocus()
self.setCentralWidget(self.main_widget)
def fileQuit(self):
self.close()
def closeEvent(self, ce):
self.fileQuit()
if __name__ == '__main__':
qApp = QtWidgets.QApplication(sys.argv)
ui = MainWindow2()
ui.setWindowTitle("Test")
ui.show()
sys.exit(qApp.exec_())