当前位置: 首页 > news >正文

【使用PyQt6与Matplotlib编写交互式生成一元二次函数图形程序】

目录

一、程序交互界面实现效果

二、如何在PyQt6中集成Matplotlib

三、程序具体代码实现

1. 引入库

2. 创建matplotlib画布类

3. 创建主窗口类

4. 主程序代码

四、总结


一、程序交互界面实现效果

在使用百度搜索引擎查询“一元二次函数”时,发现百度给出的关于一元二次函数的介绍内容中,有一个一元二次函数图形生成的交互式的工具不错。对该图形生成工具,百度网页上的原文如是说:想直观看看抛物线怎么变?试试这个工具。


图1 百度搜索引擎使用的抛物线生成工具

图1所示抛物线生成工具的交互性非常好,不仅可以通过a、b、c来改变抛物线的形状,还可以通过上下平移抛物线来改变常数项c的值。

于是想着自己来尝试实现这个工具。最省事的语言自然是Python语言了。至于使用Python语言的哪些库来绘制界面和图形,这里选择的是使用PyQt6来制作窗体界面,使用Matplotlib来绘制抛物线图形。

几番鼓捣,大部分功能终于实现,即可以通过调整过a、b、c来控制抛物线的形状,但通过上下平移抛物线来改变常数项c的值这项功能没有实现,有兴趣的读者可以自己去尝试实现之。因为本程序重在界面交互,所以下面截取了3个程序界面,见图2、图3、图4所示。

图2

图3

图4

二、如何在PyQt6中集成Matplotlib

在 PyQt6中集成 Matplotlib 的核心在于使用FigureCanvasQTAgg将 Matplotlib的图形对象转换为 Qt 的 Widget对象。以下是核心实现步骤。

核心步骤

  1. 安装依赖:确保安装了PyQt6和matplotlib。

  2. 导入后端:从matplotlib.backends.backend_qtagg导入FigureCanvasQTAgg。

  3. 创建画布类:创建一个继承自FigureCanvasQTAgg的类,在其中初始化Figure和Axes。

  4. 嵌入界面:将该画布实例作为普通 Widget 添加到 PyQt6 的布局中。

  5. 动态更新:通过修改数据并调用draw()或draw_idle()来刷新图表。

三、程序具体代码实现

1. 引入库

代码如下:

import sys from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QLabel, QSlider, QVBoxLayout, QHBoxLayout) from PyQt6.QtCore import Qt from PyQt6.QtGui import QFont from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure import matplotlib as mpl import numpy as np

2. 创建matplotlib画布类

实现代码如下:

# 创建matplotlib画布类 class MplCanvas(FigureCanvas): def __init__(self, parent=None, width=6.4, height=4.5, dpi=100): # figsize以英寸为单位,实际像素 = figsize×dpi‌(默认 dpi=100,则 8×6 英寸 → 800×600 像素) self.figure = Figure(figsize=(width,height), dpi=dpi) self.ax = self.figure.add_subplot(111) # self.add_line() super().__init__(self.figure) def add_line(self, a=1, b=0, c=0): # 初始曲线 mpl.rc('mathtext', fontset = "cm") # global fontset cm: Computer Modern(TeX) if a != 0: symmetry_x = -b/(2*a) # axis of symmetry vertex_y = (4*a*c - b*b)/(4*a) # 顶点的纵坐标 x = np.linspace(symmetry_x-10, symmetry_x+10, 100) y = a*x**2 + b*x + c self.ax.cla() self.ax.plot(x, y, color="blue", label=f"$f(x)={a}x^2+{b}x+{c}$") if a>0: # 抛物线开口向上 self.ax.set_ylim(bottom = vertex_y-10) # (bottom, top) else: self.ax.set_ylim(top = vertex_y+10) else: x = np.linspace(-10, 10, 100) y = b*x + c self.ax.cla() self.ax.plot(x, y, color="blue", label=f"$f(x)={b}x+{c}$") self.ax.grid(ls="--", alpha=0.4) self.ax.legend(framealpha=0) self.figure.tight_layout() # 解决子图重叠问题 # self.figure.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1) # 控制图形与画布边框之间的距离

3. 创建主窗口类

实现代码如下:

class MainWindow(QMainWindow): def __init__(self, parent = None): super().__init__(parent) #调用父类构造函数,创建窗体 self.initUI() def initUI(self): self.setWindowTitle("QSlider Demo") self.resize(640, 800) # slider1 self.labelSlider1Value = QLabel("1") self.labelSlider1Value.setAlignment(Qt.AlignmentFlag.AlignRight) # 设置QLabel内文本右对齐 self.horizontalSlider1 = QSlider() self.horizontalSlider1.setOrientation(Qt.Orientation.Horizontal) self.horizontalSlider1.setObjectName("horizontalSlider1") self.horizontalSlider1.setMinimum(-5) # 设置最小值 self.horizontalSlider1.setMaximum(5) # 设置最大值 self.horizontalSlider1.setSingleStep(1) # 步长 self.horizontalSlider1.setValue(1) # 设置当前值 self.horizontalSlider1.setTickPosition(QSlider.TickPosition.TicksBelow) self.horizontalSlider1.setTickInterval(1) # 设置刻度间距 self.horizontalSlider1.valueChanged.connect(self.valueChanged) # 使用valueChanged信号 hbox_layout1 = QHBoxLayout() # 创建水平排列布局 hbox_layout1.addWidget( QLabel("a (二次项系数)")) # 在布局中插入组件 hbox_layout1.addWidget(self.labelSlider1Value) # slider2 self.labelSlider2Value = QLabel("0") self.labelSlider2Value.setAlignment(Qt.AlignmentFlag.AlignRight) # 设置QLabel内文本右对齐 self.horizontalSlider2 = QSlider() self.horizontalSlider2.setOrientation(Qt.Orientation.Horizontal) self.horizontalSlider2.setObjectName("horizontalSlider2") self.horizontalSlider2.setMinimum(-10) # 设置最小值 self.horizontalSlider2.setMaximum(10) # 设置最大值 self.horizontalSlider2.setSingleStep(1) # 步长 self.horizontalSlider2.setValue(0) # 设置当前值 self.horizontalSlider2.setTickPosition(QSlider.TickPosition.TicksBelow) self.horizontalSlider2.setTickInterval(1) # 设置刻度间距 self.horizontalSlider2.valueChanged.connect(self.valueChanged) hbox_layout2 = QHBoxLayout() # 创建水平排列布局 hbox_layout2.addWidget(QLabel("b (一次项系数)")) # 在布局中插入组件 hbox_layout2.addWidget(self.labelSlider2Value) # slider3 self.labelSlider3Value = QLabel("0") self.labelSlider3Value.setAlignment(Qt.AlignmentFlag.AlignRight) # 设置QLabel内文本右对齐 self.horizontalSlider3 = QSlider() self.horizontalSlider3.setOrientation(Qt.Orientation.Horizontal) self.horizontalSlider3.setObjectName("horizontalSlider3") self.horizontalSlider3.setMinimum(-100) # 设置最小值 self.horizontalSlider3.setMaximum(100) # 设置最大值 self.horizontalSlider3.setSingleStep(5) # 步长 self.horizontalSlider3.setValue(0) # 设置当前值 self.horizontalSlider3.setTickPosition(QSlider.TickPosition.TicksBelow) self.horizontalSlider3.setTickInterval(5) # 设置刻度间距 self.horizontalSlider3.valueChanged.connect(self.valueChanged) hbox_layout3 = QHBoxLayout() # 创建水平排列布局 hbox_layout3.addWidget(QLabel("c (常数项)")) # 在布局中插入组件 hbox_layout3.addWidget(self.labelSlider3Value) hbox_layout4 = QHBoxLayout() hbox_layout4.addWidget(QLabel("提示:拖动滑块进行参数调整")) hbox_layout4.setAlignment(Qt.AlignmentFlag.AlignHCenter) self.canvas = MplCanvas(self, width=6.4, height=4.5, dpi=100) self.canvas.add_line(1, 0, 0) vbox_layout = QVBoxLayout() vbox_layout.addWidget(self.canvas) self.labelPrompt = QLabel("参数控制") self.labelPrompt.setFont(QFont('黑体', 16)) vbox_layout.addWidget(self.labelPrompt) vbox_layout.addWidget(self.horizontalSlider1) vbox_layout.addLayout(hbox_layout1) vbox_layout.addWidget(self.horizontalSlider2) vbox_layout.addLayout(hbox_layout2) vbox_layout.addWidget(self.horizontalSlider3) vbox_layout.addLayout(hbox_layout3) vbox_layout.addLayout(hbox_layout4) # vbox_layout.addStretch(1) # self.setLayout(vbox_layout) # 加入子布局 container = QWidget() container.setLayout(vbox_layout) # 加入子布局 self.setCentralWidget(container) # 设置主窗口的中心部件 def valueChanged(self): current_a = self.horizontalSlider1.value() # print('当前刻度值=%s' % currentValue) self.labelSlider1Value.setText(str(current_a)) current_b = self.horizontalSlider2.value() self.labelSlider2Value.setText(str(current_b)) current_c = self.horizontalSlider3.value() self.labelSlider3Value.setText(str(current_c)) self.canvas.add_line(current_a, current_b, current_c) # self.canvas.ax.relim() # 重置视图界限以适应新数据点 # self.canvas.ax.autoscale_view() # 自动缩放视图以适应新数据点 self.canvas.draw()

4. 主程序代码

主程序实现代码如下:

if __name__ == "__main__": # 用于当前窗体测试 app = QApplication(sys.argv) # 建立application对象 main_form = MainWindow() # 创建窗体 main_form.show() # 显示窗体 sys.exit(app.exec()) # 运行程序

四、总结

以上代码实现了一个包含抛物线绘制和动态更新功能的相对完整 PyQt6 应用程序。

其中自定义的MplCanvas继承自FigureCanvasQTAgg,封装了Matplotlib的Figure和Axes对象,使其能够像普通Qt控件一样被添加到布局中。

http://www.zskr.cn/news/1464468.html

相关文章:

  • ZYNQ7000 PS端IO不够用?试试用AXI GPIO在Vivado里扩展32个引脚(附完整SDK代码)
  • 从零搭建Python数据分析环境:手把手教你用Jupyter Notebook仪表盘管理你的第一个项目
  • 计算机毕业设计之基于Hive的电影推荐系统的设计与实现
  • 企业AI开发工具身份集成实践与安全架构设计
  • 2026年靠谱的九江工厂短视频拍摄/九江短视频/九江本地短视频线索投放热门公司推荐 - 行业平台推荐
  • 别再被CUDNN_STATUS_NOT_INITIALIZED搞懵了!手把手教你排查PyTorch+CUDA环境(附版本对照表)
  • 别再死记硬背了!用一张时序图彻底搞懂Setup和Hold的检查逻辑
  • 如何快速提取Wallpaper Engine资源:RePKG完整工具使用指南
  • PCRE2 10.36源码全集:含构建脚本、API手册、pcre2grep工具及跨平台编译支持
  • CodeRabbit 基于 Claude 构建的智能体编排系统
  • 2026年知名的内蒙古政府资金申报/内蒙古重点群体退税/内蒙古政府补贴申报/内蒙古残疾人招聘热门公司排行 - 行业平台推荐
  • 2026年推荐哈尔滨防火调节阀/黑龙江正压送风口优质公司推荐 - 品牌宣传支持者
  • 告别Keil MDK:在Win10上用VS Code + CMake + gcc-arm-none-eabi搭建STM32开发环境(保姆级避坑指南)
  • 数据科学7大沉默关卡:从问题定义到价值落地的实战校准
  • CARLA多机协同仿真环境:开箱即用的分布式自动驾驶测试平台
  • 5.1 | CSTR厌氧消化工艺详解:中温湿式发酵的设计与运行
  • 6款靠谱AI智能降重工具 改写实力出众
  • 从连线到导出:一文搞懂TwinCAT XML配置背后的EtherCAT网络初始化原理
  • 智能驾驶基石:EPB电子驻车系统深度解析
  • 手把手教你用两个外部中断,在10MHz单片机上实现100K I2C从机通信
  • 基于nx的溢流阀阀体的工艺分析及程序编制(设计源文件+万字报告+讲解)(支持资料、图片参考_降重降ai)_文章底部可以扫码
  • 2026学生降AIGC网站盘点: 学术打磨+逻辑优化哪家强?
  • 智能请假系统落地失败率高达67%?(2023年Gartner实测数据深度复盘)
  • 别再傻傻用DESCRIBE了!ABAP内表行数获取的3种高效写法(附性能对比)
  • 2026年6月有名的牛头三轴供应商推荐,上下料系统/压铸机械手/牛头三轴/自动化上下料核心设备,牛头三轴供应商哪家专业 - 品牌推荐师
  • 别再只盯着MSE了!PyTorch/TensorFlow实战:L1、L2、Smooth L1 Loss到底怎么选?
  • 终极RPA自动化工具taskt:免费开源,5分钟让Windows办公效率提升300%
  • 告别低效!用FD.io VPP的向量包处理技术,让你的网络性能原地起飞
  • 破产管理人正在悄悄升级的AI工作流:从债权智能核验到债权人会议语音实时纪要生成(含实测数据对比)
  • 直觉逻辑与HT逻辑定理证明器核心技术解析