玉宅女玉宅女03-15 17:58

郑连虎:用Python写函数绘图软件exe

 郑连虎:用Python写函数绘图软件exe

作者: 郑连虎

来源:阿虎定量笔记 

昨天(3月14日)是国际数学日,想着写篇推文庆祝一下,没找到好的题目。正好今天早餐时间,想起前两期写过绘制函数图像(点击阅读)的方法,觉得每画一次函数图像都要敲代码,还挺麻烦。

干脆点儿,我写款exe软件好了。

两三个小时后,就有了下面这款软件:

· 设置取值范围和函数解析式,即可绘图

· 为方便使用,提供帮助文档

我写的这款函数绘图器,设计思路简单粗暴:简洁好用,拷贝复制到任何一台Windows电脑上都能用。我手头上没有苹果电脑,暂时没做跨平台测试,感兴趣的Mac用户可以自行打包。

吹牛时间结束,下面来点干货,讲讲这款软件的技术实现。

我使用的脚本语言是Python 3.6,调用Matplotlib库绘制二维图像,使用NumPy系统进行数值计算,使用Tkinter模块开发图形用户界面GUI。

对于GUI编程(点击阅读)及使用pyinstaller打包Python脚本到exe程序(点击阅读)的基础知识,我在之前写“英汉词典exe”软件时已经有过介绍,这里不再赘述。

本期我只介绍核心代码,不会给出全部脚本文件。

首先,我们抛开GUI,先来看看如何实现绘图功能的简单交互:

import tkinter 

from tkinter import messagebox

import matplotlib.pyplot as plt

import numpy as np

start = float(input('请输入取值范围的起始值:'))

stop = float(input('请输入取值范围的终止值:'))

step = float(input('请输入步长:'))

num=(stop-start)/step

x = np.linspace(start,stop,num)

y = eval(input('请输入函数解析式:')) 

fig=plt.figure(figsize=(6,6))

plt.plot(x, y,label='f(x)')

plt.grid(True)

plt.axis("equal")

plt.xlim((-10, 10))

plt.ylim((-10, 10))

plt.plot([1.05*min(x),1.05*max(x)], [0,0],label='x-axis')

plt.plot([0,0],[1.05*min(y),1.05*max(y)],label='y-axis')

plt.legend()

plt.show(fig)

需要注意的细节是,对取值范围的起始值、终止值及步长的键盘输入,使用float()做浮点型转换。我这里用定义域和值域最长距离的1.05倍标出x轴和y轴,读者可以根据个人需要修改。另外,步长决定了数组取值的单位间隔,影响图像的精度。

由此得到,接受键盘输入的简单交互:

接下来的工作,就是将上述过程结合图形用户界面GUI设计,完成exe软件作品。

这里面主要有两个关键代码块:一是布局,得让输入框、按钮的位置显得好看:

    def __init__(self): 

        self.root = tkinter.Tk() 

        self.root.title("函数绘图器exe") 

        self.root.geometry('400x300') 

        self.label_start = tkinter.Label(self.root, text='起始值:') 

        self.label_stop = tkinter.Label(self.root, text='终止值:') 

        self.label_step = tkinter.Label(self.root, text='步长:') 

        self.label_y = tkinter.Label(self.root, text='解析式: ')

        self.label_name = tkinter.Label(self.root, text='Python脚本:郑连虎 (中国人民大学) ')

        self.label_name2 = tkinter.Label(self.root, text='个人微信公众号:阿虎定量笔记 ')

        self.label_name3 = tkinter.Label(self.root, text='常用运算符,请参考帮助文档 ')

        self.input_start = tkinter.Entry(self.root, width=30) 

        self.input_stop = tkinter.Entry(self.root, width=30)

        self.input_step = tkinter.Entry(self.root, width=30) 

        self.input_y = tkinter.Entry(self.root, width=30)

        self.plot_button = tkinter.Button(self.root, command = self.plot_interface, text = "绘图 ", width=10) 

        self.help_button = tkinter.Button(self.root, command = self.help_interface, text = "帮助", width=10) 

    def gui_arrang(self): 

        self.label_start.place(x=60, y= 20) 

        self.label_stop.place(x=60, y= 45)

        self.label_step.place(x=60, y= 70) 

        self.label_y.place(x=60, y= 95)

        self.label_name.place(x=60, y= 145)

        self.label_name2.place(x=60, y= 170)

        self.label_name3.place(x=60, y= 195)

        self.input_start.place(x=135, y=20) 

        self.input_stop.place(x=135, y=45) 

        self.input_step.place(x=135, y=70) 

        self.input_y.place(x=135, y=95)

        self.plot_button.place(x=140, y=250) 

        self.help_button.place(x=240, y=250)

自卖自夸,我在里面植入了广告 [捂脸]

这一部分,通过标记文本和坐标位置就可以实现。第二个关键部分是定义按钮的响应事件。也就是说,使用软件时,点击按钮,软件要能够做出相对应的反应:

    def help_interface(self): 

        # self.root.destroy() 

        tkinter.messagebox.showinfo(title='常用运算符', message='加法 + \n\r减法 - \n\r乘法 * \n\r除法 / \n\r绝对值 abs \n\r乘方 ** \n\r平方根 sqrt \n\r指数 exp \n\r自然对数 log \n\r以10为底的对数 log10 \n\r三角函数(以正弦函数为例) sin \n\r\n\r例如:\n\rf(x)=|x|表示为abs(x)') 

    def plot_interface(self): 

        start = float(self.input_start.get().ljust(10," "))

        stop = float(self.input_stop.get().ljust(10," "))

        step = float(self.input_step.get().ljust(10," "))

        num=(stop-start)/step

        x = np.linspace(start,stop,num)

        y = eval(self.input_y.get().ljust(10," "))

        fig=plt.figure(figsize=(6,6))

        plt.plot(x, y,label='f(x)')

        plt.grid(True)

        plt.axis("equal")

        plt.xlim((-10, 10))

        plt.ylim((-10, 10))

        plt.plot([1.05*min(x),1.05*max(x)], [0,0],label='x-axis')

        plt.plot([0,0],[1.05*min(y),1.05*max(y)],label='y-axis')

        plt.legend()

        plt.show(fig)

我定义了两个按钮:一是帮助文档,点击后可以查看常用运算符的说明;二是绘图指令,设置好参数后点击即可输出绘图结果。

最后一步,使用pyinstaller打包Python脚本到exe程序,用户就可以在任何一台Windows电脑上使用制作好的软件,而不用关心电脑是否已经安装Python语言。

图片输出后,本软件还给出后续操作所需的功能菜单:

· 工具列表:

1 重置原始视图/主页

2 回到前一张视图/前进

3 转到下一张视图/后退

4 用鼠标左键拖动平移坐标轴,用鼠标右键缩放/平移

5 用鼠标左键拖动放大图像,用鼠标右键缩小图像/缩放

6 配置子图

7 编辑坐标轴、曲线和图像参数

8 保存图片

 郑连虎:用Python写函数绘图软件exe

010
评论