[Python]可视化函数绘图计算器
基于matplotlib的可视化函数绘图计算器的实现
前言
这是一次工程实训项目,项目组成员2人,设计时间十天,基于Python tkinter、matplotlib、numpy、sympy完成,功能略菜。
让我感觉唯一能吹的部分,就是为了程序的完美运行,我们修改了matplotlib的部分源代码。。。
源代码链接:下载链接
设计实现
分工设计
这个项目分为图形界面和业务逻辑2部分,由我和队友分工完成,我主要设计图形界面,队友设计业务逻辑,由于都是Python小白,在开发过程中遇了不少坑。
目标功能
- 可视化图形交互界面,实时显示标准数学表达式
- 输入合法的一元或二元函数解析式,绘制二维或三维函数图像
- 同时绘制多个函数图像
- 提供丰富的函数运算功能,包含但不限于三角函数,指数对数幂函数
- 求解线性方程组
- 友好的交互方式,包含但不限于任意拖动,缩放
- 对非法输入识别,并提示错误
- 保存已绘制的图形
- 求通项和,可视化表示
- 一元函数,多元函数求导运算并绘图
- 一元不定积分,二元不定积分运算并绘图
- 一元定积分,二元定积分运算
实现过程
1.用户界面设计
tkinter的按钮和文本框太丑了,我选用了tkinter里面的ttk,然后就是繁琐的代码,画按钮,画文本框,预留绘图区,这个部分没什么技术含量,就简要介绍,画完之后就是这个样子:
- 二维绘图界面,用于绘制二维图形,左边是matplotlib的绘图区,右边是用户操作界面,右上方留出以LaTeX格式显示方程式的位置
- 三维绘图界面,用于绘制三维图形,界面基本同上
- 解方程组,由于时间原因,这个界面做的略low,上方是以LaTeX格式显示的方程组及其解,下方是用户操作区
界面的布局使用了place布局器,三个界面部分的UML如下面3幅图所示:
2.表达式以LaTeX格式显示
这是画的时间最多的部分,由于当时没学过编译原理,又不会Python分析LaTeX的库,所以就暴力考虑了能考虑的情况,代码及其冗杂,不挂出来了,最后的效果就是这样的:
- 常数
- 含未知量的表达式
- 求和式
- 求导式(为适应偏导,于是就写了偏导符号)
- 求极限式
- 求积分式
- 方程组
3.二维绘图
这是最激动人心的时刻了吧,我们构造了plot2D类和polt3D类用于绘制二维和三维图形,调用了Python的eval函数计算表达式,对特别的函数,诸如log的定义域问题做了考虑。
下面举几个二维绘图的例子:
-
多项式函数
-
指数函数、对数函数
-
三角函数
-
复合函数(采样率不高所以画的很迷。。。)
-
求导函数
-
求不定积分
sin(x)的不定积分是-cos(x)+c,这里的c为0 -
求和以及求极限的结果都是常数,就不演示了
4.三维绘图
三维绘图的思路和二维绘图差不多,也是几个例子
- 多项式
- 复合函数
- 求偏导
- 求二重积分
4.求解线性方程组
-
首先需要输入未知数个数,点击OK,将自动生成3个待定方程,这里以3为例
-
依次输入系数和常数,以英文逗号分开,每输入一行,点击OK
-
全部输入完后将自动计算输出结果
特别说明!对matplotlib源代码做的改动
改动1,_backend_tk.py
…\Python_3.7.2\Lib\site-packages\matplotlib\backends_backend_tk.py
613,688行做了改动
613行处,将window = self.canvas.manager.window注释掉,换为window = self.window
def set_cursor(self, cursor):
# window = self.canvas.manager.window
window = self.window
window.configure(cursor=cursord[cursor])
window.update_idletasks()
688行处,将master=self.canvas.manager.window注释掉,换为master=self.window
fname = tkinter.filedialog.asksaveasfilename(
# master=self.canvas.manager.window
master=self.window,
title='Save the figure',
filetypes=tk_filetypes,
defaultextension=defaultextension,
initialdir=initialdir,
initialfile=initialfile,
)
改动2,backend_bases.py
…\Python_3.7.2\Lib\site-packages\matplotlib\backend_bases.py 2640行做了改动,在2634行
self._button_pressed = None # determined by the button pressed
# at start
self.mode = '' # a mode string for the status bar
self.set_history_buttons()
这段代码下面,加上
for i in range(1):
self._active = 'PAN'
self._idPress = self.canvas.mpl_disconnect(self._idPress)
self.mode = ''
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
self._idPress = self.canvas.mpl_connect(
'button_press_event', self.press_pan)
self._idRelease = self.canvas.mpl_connect(
'button_release_event', self.release_pan)
self.mode = 'pan/zoom'
self.canvas.widgetlock(self)
for a in self.canvas.figure.get_axes():
a.set_navigate_mode(self._active)
self.set_message(self.mode)
直至函数结束
由于时间久远,不修改导致的问题我已记不清,请下载源码后研究
总结
在此次专业实训中,我们进行了多功能可视化函数计算器项目的开发,我收获颇丰,极大提高了自己的实践能力,协调能力和沟通能力等,对自己2年以来的学习有了更深的体会和理解。
在此次项目里,我主要负责了软件界面的设计,构造了二维绘图,三维绘图,方程求解3个界面框架,详细研究了Python tkinter图形库各控件的使用,tkinter消息响应,界面布局,界面美化,实现了从0开始学Python,以迭代方式不断优化界面设计,添加新的功能,前后端数据交互,并同队友实现了tkinter Frame组件与matplotlib绘图功能的对接,matplotlib源代码的修改,LaTeX表达式的正确显示等功能。
此次专业实训我受益匪浅,完成了自己对Python编程语言的初步学习,了解了Python基本语法,了解了tkinter和ttk图形库的使用,见识到了sympy,numpy,matplotlib等数学库绘图库的强大功能,领略到了Python语言进行科学计算的无穷魅力,同时也锻炼了自己的实践能力,积累了调试程序,测试优化代码的经验,讲学到的知识应用到实践中去。
上一篇: Linux命令-系统管理
下一篇: Linux管理常用命令