基于PyQt Canvas Matplotlib图形绘制

关键技术:变量传递, Pyqt Canvas, 信号槽

定义三种不同的绘图样式:第一个是静态图,第二个是动态图,最后一个是变量可控视图。

		sc = MyStaticMplCanvas(self.main_widget, width=5, height=4, dpi=100)
		dc = MyDynamicMplCanvas(self.main_widget, width=5, height=4, dpi=100)
		cc = MyControlMplCanvas(self.main_widget, width=5, height=4, dpi=100)
		self.horizontalLayout.addWidget(sc)
		self.horizontalLayout.addWidget(dc)
		self.horizontalLayout.addWidget(cc)

 变量传递,通过lambda函数实现。

self.horizontalSlide.valueChanged['int'].connect(lambda: cc.update_figure(self.horizontalSlide.value()))

完整程序: 

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file '.\mainwindow.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!
import sys
import random

import matplotlib
matplotlib.use("Qt5Agg")
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageBox, QWidget

from numpy import arange, sin, pi
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure


class MyMplCanvas(FigureCanvas):#画布基类
	"""这是一个窗口部件,即QWidget(当然也是FigureCanvasAgg)"""
	def __init__(self, parent=None, width=50, height=50, dpi=100):
		fig = Figure(figsize=(width, height), dpi=dpi)
		self.axes = fig.add_subplot(111)
		# 每次plot()调用的时候,我们希望原来的坐标轴被清除(所以False)
		self.axes.hold(False)
		self.compute_initial_figure()

		#
		FigureCanvas.__init__(self, fig)
		self.setParent(parent)

		FigureCanvas.setSizePolicy(self,
									QSizePolicy.Expanding,
									QSizePolicy.Expanding)
		self.axes.set_xlabel('x')
		self.axes.set_ylabel('y')
		FigureCanvas.updateGeometry(self)

	def compute_initial_figure(self):
		pass

class MyStaticMplCanvas(MyMplCanvas):#单个画布
	"""静态画布:一条正弦线"""
	def compute_initial_figure(self):
		t = arange(0.0, 3.0, 0.01)
		s = sin(4*pi*t)
		self.axes.plot(t, s)

class MyControlMplCanvas(MyMplCanvas):#单个画布
	"""动态画布:每秒自动更新,更换一条折线。"""
	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, 0, 0, 0], [1, 2, 3, 4], 'r')

	def update_figure(self,x=1):
		# 构建4个随机整数,位于闭区间[0, 10]
		t = arange(0.0, 3.0, 0.01)
		print x
		s = sin(2*pi*t+x/100.*2*pi)
		self.axes.plot(t, s ,'r')
		self.axes.set_xlabel('x')
		self.axes.set_ylabel('y')
		self.draw()

class MyDynamicMplCanvas(MyMplCanvas):#单个画布
	"""动态画布:每秒自动更新,更换一条折线。"""
	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):
		# 构建4个随机整数,位于闭区间
Qt Designer 是一个集成开发环境 (IDE) 中的一部分,专用于设计用户界面(UI) 的可视化工具,它通常与 PyQt 或者 PySide 等 Python GUI 库一起使用。然而,Matplotlib 是一个专门用于数据可视化的库,它并不直接支持在 Qt Designer 中创建图形。 如果你想在 PyQt5 中使用 Matplotlib 并将其集成到应用中,你需要在编写代码阶段完成这个任务。首先,在Qt Designer里创建好UI,然后通过 Python 代码连接信号和槽,或者在运行时动态地加载绘图窗口。以下是一个简单的步骤说明: 1. **设计UI**: 在 Qt Designer 中添加一个 QLabel 或 QWidget 类型的控件作为容器,用于显示matplotlib图表。 2. **编写Python代码**: 导入所需的模块并设置好matplotlib的backend,例如`plt.show()`需要在Qt事件循环内执行。创建matplotlib窗口,并将生成的图像数据传递给该窗口。 ```python from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtCore import pyqtSlot import sys import matplotlib.pyplot as plt class MyWindow(QWidget): def __init__(self): super().__init__() self.init_ui() @pyqtSlot() def init_ui(self): # 在Qt Designer中,将matplotlib图表的控件与此slot关联 self.plot_widget = QLabel(self) self.plot_widget.setAlignment(Qt.AlignCenter) # 当需要更新图表时,可以在这里绘制 @staticmethod def update_chart(): data = ... # 从数据源获取数据 fig, ax = plt.subplots() ax.plot(data) canvas = FigureCanvas(fig) img = QImage(canvas.render()) pixmap = QPixmap.fromImage(img) self.plot_widget.setPixmap(pixmap) # 比如在按钮点击事件中触发更新 btn = QPushButton("Update Chart", self) btn.clicked.connect(update_chart) if __name__ == "__main__": app = QApplication(sys.argv) window = MyWindow() window.show() sys.exit(app.exec_()) ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值