upload fitt project

master
bettleChen 1 year ago
parent c390d2dffe
commit 61e620d19d

29
X1.py

@ -0,0 +1,29 @@
import random
import numpy as np
def random_points():
x=[]
y=[]
for i in range(20):
x_= random.uniform(0, 1000) # 生成随机浮点数
y_= random.uniform(0, 1000) # 生成随机浮点数
x.append(x_) # 加入列表
y.append(y_)
x=np.array(x) # 列表转数组
y=np.array(y)
arr = np.array(list(zip(x, y))) # 将两个一维数组拼接成二维数组
return arr
# if __name__ == '__main__':
# arr = random_points()
# print(arr)
def compute_curveData(num, step, coefficient): # coefficient代表二次函数系数数组形式
def quadratic_function(x): # 构造二次函数y = a * X^2 + b * X + C
return coefficient[0] * x ** 2 + coefficient[1] * x + coefficient[2]
x_values = np.arange(0, num, step)
y_values = quadratic_function(x_values) # 调用quadratic_function(x)函数得到y值
curve_data = np.column_stack((x_values, y_values)) # 将两个一维数组堆叠成二维数组,形成(x,y)的形式
return curve_data
if __name__ == '__main__':
coefficient = [1, 2, 3]
ans = compute_curveData(1000, 250, coefficient)
print(ans)

113
X2.py

@ -0,0 +1,113 @@
from tkinter import *
import tkinter as tk
import mpl_toolkits.axisartist as axisartist
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import data as gl_data
import numpy as np
from X1 import random_points
def window():
root_window = Tk()
root_window.title('函数拟合')
root_window.geometry('900x600') # 设置窗口大小:宽x高,注,此处不能为 "*",必须使用 "x"
# 设置主窗口的背景颜色,颜色值可以是英文单词或者颜色值的16进制数,除此之外还可以使用Tk内置的颜色常量
root_window["background"] = "white"
root_window.resizable(0, 0) # 防止用户调整尺寸
label1 = tk.Label(root_window, text="样本数据\n集文件", font=('Times', 8), bg="white",
width=13, height=3, # 设置标签内容区大小
padx=0, pady=0, borderwidth=0, )
label1.place(x=10, y=4) # 设置填充区距离、边框宽度和其样式(凹陷式)
label3 = tk.Label(root_window, text="", font=('Times', 8), bg="white", fg="black",
width=39, height=2, padx=0, pady=0, borderwidth=0, relief="ridge", highlightcolor="blue")
label3.place(x=122, y=10)
return root_window
# if __name__ == '__main__':
# root_window = window()
# root_window.mainloop()
def draw_axis(low, high, step=250):
fig = plt.figure(figsize=(4.4, 3.2)) # 设置显示大小
ax = axisartist.Subplot(fig, 111) # 使用axisartist.Subplot方法创建一个绘图区对象ax
fig.add_axes(ax) # 将绘图区对象添加到画布中
ax.axis[:].set_visible(False)# 通过set_visible方法设置绘图区所有坐标轴隐藏
ax.axis["x"] = ax.new_floating_axis(0, 0) # 添加新的x坐标轴
ax.axis["x"].set_axisline_style("-|>", size=1.0) # 给x坐标轴加上箭头
ax.axis["y"] = ax.new_floating_axis(1, 0) # 添加新的y坐标轴
ax.axis["y"].set_axisline_style("-|>", size=1.0) # y坐标轴加上箭头
ax.axis["x"].set_axis_direction("bottom") # 设置x、y轴上刻度显示方向
ax.axis["y"].set_axis_direction("left") # 设置x、y轴上刻度显示方向
plt.xlim(low, high) # 把x轴的刻度范围设置
plt.ylim(low, high) # 把y轴的刻度范围设置
ax.set_xticks(np.arange(low, high + 5, step)) # 把x轴的刻度间隔设置
ax.set_yticks(np.arange(low, high + 5, step)) # 把y轴的刻度间隔设置
# plt.show()
# if __name__ == '__main__':
# draw_axis(-1000, 1000)
def selfdata_show(sampleData):
num_points = len(sampleData) # 样本数据点的数量
colors = np.random.rand(num_points, 3) # 生成随机颜色
draw_axis(0, 1000)
plt.scatter(sampleData[:, 0], sampleData[:, 1], c=colors) # 绘制样本数据点
plt.show() #显示图片
# if __name__ == '__main__':
# sampleData = random_points() # 生成样本点
# selfdata_show(sampleData) # 绘制样本数据点
def quadratic_function(x, a, b, c, d): #构造三次函数y = a * X^3 + b * X^2 + C * x + d
return a * x ** 3 + b * x **2 + c * x + d
def draw_line(low, high, sx, sy):
draw_axis(low, high) #绘制坐标轴
popt = [] #初始化curve_fit
pcov = [] #初始化curve_fit
gl_data.yvals_pow = [] #初始化curve_fit
popt, pcov = curve_fit(quadratic_function, sx, sy) # 用curve_fit来对点进行拟合
curve_x = np.arange(low, high) #按照步长生成的一串数字
curve_y = [quadratic_function (i, *popt) for i in curve_x] # 根据x0(按照步长生成的一串数字)来计算y1值
plt.plot(curve_x, curve_y, color='blue', label='Fitted Curve') #绘制拟合曲线
plt.legend()
plt.show() #显示函数图像
if __name__ == '__main__':
curve_data = [[-375,250],[-750,0],[-1000,-500],[0,0],[375,-250],[750,0],[1000,500]]
x = np.array([point[0] for point in curve_data]) # 为二次函数.txt
y = np.array([point[1] for point in curve_data])
draw_line(-1000, 1000, x, y)
# 下面是一个用于拟合曲线的最小二乘法的Python代码示例
# import numpy as np
# import matplotlib.pyplot as plt
#
# # 定义x和y坐标数据
# x = np.array([1, 2, 3, 4, 5])
# y = np.array([2, 3, 4, 5, 6])
#
# # 定义多项式阶数m
# m = 2
#
# # 构造A矩阵
# A = np.vander(x, m + 1, increasing=True)
#
# # 计算拟合系数theta
# theta = np.linalg.lstsq(A, y, rcond=None)[0]
#
# # 使用theta和x的幂次计算拟合曲线
# x_fit = np.linspace(x.min(), x.max(), 100)
# y_fit = np.polyval(theta[::-1], x_fit)
#
# # 创建图形对象并绘制拟合曲线和样本点
# fig, ax = plt.subplots()
# ax.plot(x_fit, y_fit, label='Fitted curve')
# ax.scatter(x, y, label='Data points')
#
# # 添加标签
# ax.set_xlabel('x')
# ax.set_ylabel('y')
# ax.set_title('Curve fitting using Least Squares')
#
# # 显示图形
# plt.legend()
# plt.show()

343
X3.py

@ -0,0 +1,343 @@
# -*- coding: utf-8 -*-
# Time : 2023/8/9 10:20
# Author : lirunsheng
# User : l'r's
# Software: PyCharm
# File : X3.py
import mpl_toolkits.axisartist as axisartist
from scipy.optimize import curve_fit
from pandas import DataFrame
import matplotlib.pyplot as plt
import numpy as np
import pylab as mpl
from tkinter import *
import data as gl_data
import pandas as pd
import tkinter
import sys
import tkinter as tk
from tkinter import filedialog
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 解决matplotlib中文不显示问题
plt.rcParams['axes.unicode_minus'] = False # 解决matplotlib负数坐标显示问题
# 创建一个二维数组sampleData用于存储样本数据
sampleData = []
def askfile():# 从本地选择一个文件,并返回文件的路径
global sampleData
# 弹出文件选择对话框,选择要打开的文本文件
file_path = filedialog.askopenfilename(filetypes=[('Text Files', '*.txt')])
# 如果没有选择文件,直接返回
if not file_path:
return
# 步骤1打开样本数据集文件并读取每行数据
with open(file_path, 'r') as file:
lines = file.readlines()
# 步骤2遍历所有行将每行数据解析为sx和sy值转换为浮点数并存储到sampleData中
for line in lines:
sx, sy = line.strip().split(' ')
sx = float(sx)
sy = float(sy)
sampleData.append([sx, sy])
# # 步骤3使用循环遍历样本数据并打印出来
# for data in sampleData:
# print(data)
# if __name__ == '__main__':
# askfile()
def draw_axis(low, high, step=250):
fig = plt.figure(figsize=(4.4, 3.2)) # 设置显示大小
ax = axisartist.Subplot(fig, 111) # 使用axisartist.Subplot方法创建一个绘图区对象ax
fig.add_axes(ax) # 将绘图区对象添加到画布中
ax.axis[:].set_visible(False)# 通过set_visible方法设置绘图区所有坐标轴隐藏
ax.axis["x"] = ax.new_floating_axis(0, 0) # 添加新的x坐标轴
ax.axis["x"].set_axisline_style("-|>", size=1.0) # 给x坐标轴加上箭头
ax.axis["y"] = ax.new_floating_axis(1, 0) # 添加新的y坐标轴
ax.axis["y"].set_axisline_style("-|>", size=1.0) # y坐标轴加上箭头
ax.axis["x"].set_axis_direction("bottom") # 设置x、y轴上刻度显示方向
ax.axis["y"].set_axis_direction("left") # 设置x、y轴上刻度显示方向
plt.xlim(low, high) # 把x轴的刻度范围设置
plt.ylim(low, high) # 把y轴的刻度范围设置
ax.set_xticks(np.arange(low, high + 5, step)) # 把x轴的刻度间隔设置
ax.set_yticks(np.arange(low, high + 5, step)) # 把y轴的刻度间隔设置
def generate_and_plot_sample_data(low, high):
num_samples = 25 #设置样本点数量
gl_data.X = np.random.randint(low=low, high=high, size=num_samples)#随机生成x值
print(gl_data.X)
gl_data.Y = np.random.randint(low=low, high=high, size=num_samples)#随机生成y值
# 提取样本数据的x坐标和y坐标
# x_values = [point[0] for point in sampleData]
# print(x_values)
# y_values = [point[1] for point in sampleData]
draw_axis(low, high) #绘制坐标轴
plt.scatter(gl_data.X,gl_data.Y, color='red') # 绘制样本数据点
plt.savefig(r"dot2.png", facecolor='w') # 保存到本地
plt.close() # 清除内存
# set_phtot(1) #显示到主界面
# if __name__ == '__main__':
# askfile()
# # generate_and_plot_sample_data(gl_data.LOW, gl_data.HIGH)
def quadratic_function(x, a, b, c):#构造二次函数y = a * X^2 + b * X + C
return a * x ** 2 + b * x + c
def draw_dots_and_line(low, high, sx, sy):
draw_axis(low, high)
popt, pcov = curve_fit(quadratic_function, sx, sy)# 用curve_fit来对点进行拟合
positive_mask = sy >= 0.0#给样本点分类
negative_mask = sy < 0.0#给样本点分类
positive_colors = ['red' if x >= 0.0 else 'blue' for x in sx]#给样本点分类
negative_colors = ['green' if x >= 0.0 else 'purple' for x in sx]#给样本点分类
#根据样本点类型决定样本点颜色
plt.scatter(gl_data.X[positive_mask], gl_data.Y[positive_mask], color=np.array(positive_colors)[positive_mask], lw=1)
plt.scatter(gl_data.X[negative_mask], gl_data.Y[negative_mask], color=np.array(negative_colors)[negative_mask], lw=1)
curve_x = np.arange(low, high)#按照步长生成的一串数字
curve_y = [quadratic_function (i, * popt) for i in curve_x]# 根据x来计算y1值
plt.plot(curve_x, curve_y, color='blue', label='Fitted Curve')#绘制拟合曲线
plt.savefig(r"dot5.png", facecolor='w') # 保存到本地
plt.legend()
plt.show()
return popt
# if __name__ == '__main__':
# askfile()
# gl_data.x = np.array([point[0] for point in sampleData]) # 为二次函数.txt
# gl_data.y = np.array([point[1] for point in sampleData])
# popt = draw_dots_and_line(gl_data.low, gl_data.high, gl_data.x, gl_data.y)
# a,b,c = popt
# print(a,b,c)
def input_num(root_tk):
global top
top = tk.Toplevel(root_tk)
top.geometry("300x50")
top.title('坐标点个数')
label1 = Label(top, text="坐标点个数")
label1.grid(row=0) # 这里的side可以赋值为LEFT RTGHT TOP BOTTOM
num1 = IntVar()
entry1 = Entry(top, textvariable=num1)
num1.set(0)
entry1.grid(row=0, column=1)
Label(top, text=" ").grid(row=0, column=3)
Button(top, text="确定", command=lambda: input_data(root_tk, int(entry1.get()))).grid(row=0, column=3)
top.mainloop()
def add_sample_data():
global sample_x, sample_y, sample_data
global entry_x,entry_y,label_status, numx
try:
x = float(entry_x.get())
y = float(entry_y.get())
except:
label_status.config(text="输入不合法")
return
entry_x.delete(0, tk.END)
entry_y.delete(0, tk.END)
if min(x, y) < gl_data.LOW or max(x, y) > gl_data.HIGH:
label_status.config(text="输入超过范围")
return
elif len(sample_data) < numx:
label_status.config(text="点对已添加")
sample_data.append((x, y))
sample_x.append(x)
sample_y.append(y)
else:
label_status.config(text="已达到最大数量")
def check_sample_data():
global label_status,numx,sample_x,sample_y,sample_data
if len(sample_data) == numx:
label_status.config(text="已达到最大数量")
gl_data.X = np.array(sample_x)
gl_data.Y = np.array(sample_y)
print('已添加', sample_data)
sys.exit()
else:
label_status.config(text="还需输入{}个点对".format(numx - len(sample_data)))
print(sample_data)
def input_data(root_tk, num):
global top
global sample_x,sample_y,sample_data
global numx
numx = num
sample_x = []
sample_y = []
sample_data = []
top.destroy()
top = tk.Toplevel(root_tk)
top.geometry("300x200")
top.title('坐标')
global entry_x, entry_y, label_status
label_x = tk.Label(top, text="X 值:")
label_x.pack()
entry_x = tk.Entry(top)
entry_x.pack()
label_y = tk.Label(top, text="Y 值:")
label_y.pack()
entry_y = tk.Entry(top)
entry_y.pack()
button_add = tk.Button(top, text="添加", command=add_sample_data)
button_add.pack()
button_check = tk.Button(top, text="检查", command=check_sample_data)
button_check.pack()
label_status = tk.Label(top, text="")
label_status.pack()
top.mainloop()
# if __name__ == '__main__':
# root = tk.Tk()
# root.withdraw()
# input_num(root)
# 定义误差函数
def error_func(x_data, y_data, a, b, c):
y_pred = exponential_function(x_data, a, b, c)
error = np.sum((y_data - y_pred) ** 2)
residual = y_data - y_pred
ss_res = np.sum(residual ** 2)
ss_tot = np.sum((y_data - np.mean(y_data)) ** 2)
r_squared = 1 - (ss_res / ss_tot)
return error,r_squared
# 给出一个二次函数拟合的例子,读者可自己写拟合函数
def exponential_function(x, a, b, c):
return a * x ** 2 + b * x + c
def fit(sample_data): # 随机生成样本数据
x_data = np.array([data[0] for data in sample_data])
y_data = np.array([data[1] for data in sample_data]) # 拟合样本数据
popt, pcov = curve_fit(exponential_function, x_data, y_data) # 计算拟合结果
# 计算拟合误差
error,r_squared = error_func(x_data, y_data, *popt)
fit_function_name = exponential_function.__name__# 打印拟合函数的形式、系数、误差和优度
print("拟合函数形式:{}".format(fit_function_name))
print("拟合系数:{}".format(popt))
print("误差:{:.4f}".format(error))
print("拟合优度R^2{:.4f}".format(r_squared))
# if __name__ == '__main__':
# askfile()
# fit(sampleData) # 对当前x、y值进行拟合
# # 给出一个指数函数拟合的例子,读者可自己写拟合函数
# def fit_function(x,a,b,c):
# return a * np.exp(b * x) + c
#
# def fit(sample_data): # 随机生成样本数据
# x_data = np.array([data[0] for data in sample_data])
# y_data = np.array([data[1] for data in sample_data]) # 拟合样本数据
# popt, pcov = curve_fit(fit_function, x_data, y_data) # 计算拟合结果
# y_fit = fit_function(x_data, *popt)
# residuals = y_data - y_fit
# ss_res = np.sum(residuals**2)
# ss_tot = np.sum((y_data - np.mean(y_data))**2)
# r_squared = 1 - (ss_res / ss_tot)
# fit_function_name = fit_function.__name__# 打印拟合函数的形式、系数、误差和优度
# print("拟合函数形式:{}".format(fit_function_name))
# print("拟合系数:{}".format(popt))
# print("误差:{:.4f}".format(np.sqrt(np.mean(residuals**2))))
# print("拟合优度R^2{:.4f}".format(r_squared))
# if __name__ == '__main__':
# askfile()
# fit(sampleData) # 对当前x、y值进行拟合
def change_Q(no):
gl_data.Quadrant = no #更改全局变量的象限显示
if no: #若为一象限则修改显示下限为0
gl_data.LOW = 0
else: #若为四象限,则修改显示下限为-gl_data.MAXV
gl_data.LOW = -gl_data.MAXV
q_button() #更新象限显示面板
def q_button():
r = 7.5
rr = 2.5
for widget in q_root.winfo_children():
widget.destroy()
q_cv = tk.Canvas(q_root, width=450, height=500)
q_cv.place(x=0, y=0)
l = tk.Label(q_root, text='坐标轴', bd=0, font=("微软雅黑", 16) , anchor=W)
l.place(x=20, y=0, width=80, height=50,)
# 四象b限按钮
b1 = tk.Button(q_root, text='四象限', bd=0, font=("微软雅黑", 16)
, command=lambda: change_Q(0), anchor=W)
b1.place(x=170, y=0, width=80, height=50,)
# 一象限按钮
b2 = tk.Button(q_root, text='一象限', bd=0, font=("微软雅黑", 16)
, command=lambda: change_Q(1), anchor=W)
b2.place(x=320, y=0, width=80, height=50,)
# 绘制标记框
q_cv.create_oval(140 - r, 25 - r, 140 + r, 25 + r, fill="white", width=1, outline="black")
q_cv.create_oval(290 - r, 25 - r, 290 + r, 25 + r , fill="white", width=1, outline="black")
# 根据当前的象限选择值来填充标记框
if gl_data.Quadrant == 0:
q_cv.create_oval(140 - rr, 25 - rr, 140 + rr, 25 + rr, fill="black", width=1, outline="black")# 绘制象限
# Q_cv.create_rectangle(80, 80, 270, 270, fill="white") # 第一象限
# Q_cv.create_rectangle(270, 80, 500, 270, fill="red") # 第二象限
# Q_cv.create_rectangle(80, 270, 270, 480, fill="blue") # 第三象限
# Q_cv.create_rectangle(270, 270, 500, 480, fill="green") # 第四象限
else:
q_cv.create_oval(290 - rr, 25 - rr, 290 + rr, 25 + rr, fill="black", width=1, outline="black")
# if __name__ == '__main__':
# # 象限选择相关界面
# q_root = tk.Tk()
# q_root.geometry("500x550") # 设置窗口的大小和位置
# q_button()
# q_root.mainloop()
# 定义模型为y=ax+b
def model(x, a, b):
return a*x + b
# 定义误差函数error_function()
def error_function(x,y,a, b):
y_pred = model(x, a, b)
error = np.mean((y - y_pred)**2)
return error
# 定义梯度函数gradient()
def gradient(a, b,x,y):
y_pred = model(x, a, b)
gradient_a = 2*np.mean((y_pred - y)*x)
gradient_b = 2*np.mean(y_pred - y)
return gradient_a, gradient_b
if __name__ == '__main__':
# 读取sampledata值
sampledata = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
x = np.array(sampledata)
y = np.array([-2, 1, 0, 1, 2, 3, 4, 5, 6, 8])
# 初始化参数
a = 0
b = 0
learning_rate = 0.01
num_iterations = 1000
# 梯度下降算法
for i in range(num_iterations):
grad_a, grad_b = gradient(a, b,x,y)
a -= learning_rate * grad_a
b -= learning_rate * grad_b
# 输出最终拟合结果
final_error = error_function(x,y,a, b)
# gl_data.X = x # 为二次函数.txt
# gl_data.Y = y
# draw_axis(-100, 100)
# positive_mask = x >= 0.0 # 给样本点分类
# negative_mask = y < 0.0 # 给样本点分类
# positive_colors = ['red' if x >= 0.0 else 'blue' for x in x] # 给样本点分类
# negative_colors = ['green' if x >= 0.0 else 'purple' for x in x] # 给样本点分类
# # 根据样本点类型决定样本点颜色
# plt.scatter(gl_data.X[positive_mask], gl_data.Y[positive_mask], color=np.array(positive_colors)[positive_mask],
# lw=1)
# plt.scatter(gl_data.X[negative_mask], gl_data.Y[negative_mask], color=np.array(negative_colors)[negative_mask],
# lw=1)
# curve_x = np.arange(-1000, 1000) # 按照步长生成的一串数字
# curve_y = [model(i, a, b) for i in curve_x] # 根据x来计算y1值
# plt.plot(curve_x, curve_y, color='blue', label='Fitted Curve') # 绘制拟合曲线
# plt.legend()
# plt.show()
print("拟合函数形式: y = ax + b")
print("系数 a:{:.2f}".format(a))
print("系数 b:{:.2f}".format( b))
print("误差计算方法: 均方误差")
print("最终误差:{:.2f}".format(final_error))

225
X4.py

@ -0,0 +1,225 @@
# -*- coding: utf-8 -*-
# Time : 2023/8/9 10:20
# Author : lirunsheng
# User : l'r's
# Software: PyCharm
# File : X4.py
# -*- encoding: utf-8 -*-
"""
@Author: packy945
@FileName: main.py
@DateTime: 2023/5/30 15:29
@SoftWare: PyCharm
"""
import sys
from fitting import *
import numpy as np
import data as gl_data
import input
import tkinter as tk
from tkinter import *
import tkinter.filedialog # 注意次数要将文件对话框导入
global Q_root,F_root
global root_window
global label1,label2,label3
def window():
global root_window
global label1, label2, label3
root_window = Tk()
root_window.title('函数拟合')
root_window.geometry('900x600') # 设置窗口大小:宽x高,注,此处不能为 "*",必须使用 "x"
# 设置主窗口的背景颜色,颜色值可以是英文单词或者颜色值的16进制数,除此之外还可以使用Tk内置的颜色常量
root_window["background"] = "white"
root_window.resizable(0, 0) # 防止用户调整尺寸
label1 = tk.Label(root_window, text="样本数据\n集文件", font=('Times', 8), bg="white",
width=13, height=3, # 设置标签内容区大小
padx=0, pady=0, borderwidth=0, )
label1.place(x=10, y=4) # 设置填充区距离、边框宽度和其样式(凹陷式)
label3 = tk.Label(root_window, text="", font=('Times', 8), bg="white", fg="black",
width=39, height=2, padx=0, pady=0, borderwidth=0, relief="ridge", highlightcolor="blue")
label3.place(x=122, y=10)
# 使用按钮控件调用函数
tk.Button(root_window, text="装载", relief=RAISED, command=lambda: askfile()).place(x=370, y=12)
label2 = tk.Label(root_window, text="拟合曲线类型", font=('Times', 12), bg="white",
width=20, height=3, # 设置标签内容区大小
padx=0, pady=0, borderwidth=0, )
# 设置填充区距离、边框宽度和其样式(凹陷式)
label2.place(x=450, y=4)
gl_data.Canvas2 = tk.Canvas(root_window, bg='white', width=450, height=330)
gl_data.Canvas2.place(x=4, y=60)
# 定义一个处理文件的相关函数
def askfile():
# 从本地选择一个文件,并返回文件的路径
filename = tkinter.filedialog.askopenfilename()
if filename != '':#若选中了一个文件,则对文件进行读取
label3.config(text=filename)#显示文件路径
read_sample_data(filename)#将文件读取并存到sampleData中
# print_sample_data(filename)#将文件读取并逐行输出
selfdata_show(gl_data.X, gl_data.Y, gl_data.LOW, gl_data.HIGH)
else:#若未选择文件,则显示为空
label3.config(text='')
def print_sample_data(file_path):#打开对应文件
with open(file_path, 'r') as file:
for line in file:#逐行读取文件
line = line.strip('\n')#移除换行符
sx, sy = line.split(' ')#以空格分割xy
print(f'sx: {float(sx)}, sy: {float(sy)}')#将sx、sy转换为浮点数并打印
def read_sample_data(file_path):
x, y = [], []#初始化xy
with open(file_path, 'r') as file:
for line in file:#逐行读文件
line = line.strip('\n')#移除换行符
sx, sy = line.split(' ')#以空格分割xy
x.append(float(sx))#将sx转换为浮点数并加入数组
y.append(float(sy))#将sy转换为浮点数并加入数组
gl_data.X, gl_data.Y = np.array(x), np.array(y)#xy数组转为array并赋值给全局变量
def buttons():
# 随机生成样本点并显示
b_dot = tk.Button(root_window, text="生成\n数据集", relief=RAISED, bd=4, bg="white", font=("微软雅黑", 10),
command=lambda: generate_and_plot_sample_data(gl_data.LOW, gl_data.HIGH))
b_dot.place(x=455, y=410)
# 显示当前样本点
b_show = tk.Button(root_window, text="显示\n数据集", relief=RAISED, bd=4, bg="white", font=("微软雅黑", 10),
command=lambda: selfdata_show(gl_data.X, gl_data.Y, gl_data.LOW, gl_data.HIGH))
b_show.place(x=510, y=410)
# 显示数据集与曲线
b_line = tk.Button(root_window, text="显示数据\n集与曲线", relief=RAISED, bd=4, bg="white", font=("微软雅黑", 10),
command=lambda: draw_dots_and_line(gl_data.Xian_index, gl_data.LOW, gl_data.HIGH, gl_data.X, gl_data.Y))
b_line.place(x=565, y=410)
# 手动输入数据集
b_input = tk.Button(root_window, text="手动输入数据集", relief=RAISED, bd=4, bg="white", pady=7, font=("微软雅黑", 13),
command=lambda: input.input_num(root_window))
b_input.place(x=633, y=410)
# 拟合并输出拟合结果
b_fit = tk.Button(root_window, text="拟合", relief=RAISED, bd=4, bg="white", pady=7, font=("微软雅黑", 13),
command=lambda: fit_data(gl_data.Xian_index, gl_data.X, gl_data.Y))
b_fit.place(x=771, y=410)
def show_fit():
L = tk.Label(root_window, text='结果输出:', bg='white', font=("微软雅黑", 16)
, anchor=W)
L.place(x=20, y=480, width=100, height=30)
ans = tk.Label(root_window, text=gl_data.Out, font=("微软雅黑", 14)
, anchor=W, justify='left')
ans.place(x=120, y=480, width=760, height=100)
print(gl_data.Out)
def fit_data(xian_index, sx, sy):
# gl_data.yvals_pow = []
cur = function.Fun[xian_index] # 装载正在选择的函数
func = cur.get_fun()#获取当前函数func
popt, pcov = curve_fit(func, sx, sy)# 用curve_fit来对点进行拟合
yvals_pow = func(gl_data.X, *popt)
rr = gl_data.goodness_of_fit(yvals_pow, gl_data.Y)# 计算本次拟合的R*R值用于表示拟合优度
# 输出拟合后的各个参数值
ans = '\n函数系数:'
for i in range(cur.variable):
if i == 4:
ans += '\n'
if i != 0:
ans += ', '
ans += chr(ord('a') + i) + '=' + '{:.2e}'.format(popt[i]) # str(round(gl_data.popt[i], 3))
gl_data.Out = '函数形式:' + cur.name + ' '
gl_data.Out += cur.demo
gl_data.Out += ans
gl_data.Out += '\n拟合优度(R\u00b2)' + str(round(rr, 5))
show_fit()# 显示函数信息到输出框
def change_Q(no):
gl_data.Quadrant = no #更改全局变量的象限显示
if no:#若为一象限则修改显示下限为0
gl_data.LOW = 0
else:#若为四象限,则修改显示下限为-gl_data.maxV
gl_data.LOW = -gl_data.MAXV
q_button()#更新象限显示面板
def q_button():
r = 7.5
rr = 2.5
for widget in Q_root.winfo_children():
widget.destroy()
q_cv = tk.Canvas(Q_root, width=400, height=50)
q_cv.place(x=0, y=0)
l = tk.Label(Q_root, text='坐标轴', bd=0, font=("微软雅黑", 16)
, anchor=W)
l.place(x=20, y=0, width=80, height=50,)
# 四象限按钮
b1 = tk.Button(Q_root, text='四象限', bd=0, font=("微软雅黑", 16)
, command=lambda: change_Q(0), anchor=W)
b1.place(x=170, y=0, width=80, height=50,)
# 一象限按钮
b2 = tk.Button(Q_root, text='一象限', bd=0, font=("微软雅黑", 16)
, command=lambda: change_Q(1), anchor=W)
b2.place(x=320, y=0, width=80, height=50,)
# 绘制标记框
q_cv.create_oval(140 - r, 25 - r, 140 + r, 25 + r
, fill="white", width=1, outline="black")
q_cv.create_oval(290 - r, 25 - r, 290 + r, 25 + r
, fill="white", width=1, outline="black")
# 根据当前的象限选择值来填充标记框
if gl_data.Quadrant == 0:
q_cv.create_oval(140 - rr, 25 - rr, 140 + rr, 25 + rr
, fill="black", width=1, outline="black")
else:
q_cv.create_oval(290 - rr, 25 - rr, 290 + rr, 25 + rr
, fill="black", width=1, outline="black")
def change_f(no):
gl_data.Xian_index = no#设置全局函数编号为该函数
f_button()#重新绘制函数显示界面
def f_button():
r = 7.5#设置按钮大小
rr = 2.5#设置按钮大小
for widget in F_root.winfo_children():
widget.destroy()#清空原有按钮
f_cv = tk.Canvas(F_root, width=400, height=330)#新建画布
f_cv.place(x=0, y=0)#放置画布
f_cv.create_rectangle(2, 2, 398, 328, fill='white', outline="#0099ff")#设置画布边框及底色
cur = 0#函数计数
for fun in function.Fit_type_library:#遍历函数库
f = function.Fit_type_library.get(fun)#获取函数具体信息
if function.Show[f[0]] == 1:# 如果show为1则显示
f_cv.create_oval(20 - r, 20 + 15 + cur * 30 - r, 20 + r, 20 + 15 + cur * 30 + r
, fill="white", width=1, outline="black")# 绘制标记框
if f[0] == gl_data.Xian_index:# 若选择为当前函数则标记
f_cv.create_oval(20 - rr, 20 + 15 + cur * 30 - rr, 20 + rr, 20 + 15 + cur * 30 + rr
, fill="black", width=1, outline="black")
# 绘制切换按钮,单击则将当前使用函数切换为该函数
button = tk.Button(F_root, text=f[2] + ' ' + f[1], bd=0, bg="white", font=("微软雅黑", 12)
, command=lambda x=f[0]: change_f(x), anchor=W)
button.place(x=40, y=20 + cur * 30, width=300, height=30)
cur += 1#计数加一
def close_window():
sys.exit()
def main():
global Q_root, F_root,root_window
gl_data.X = []
gl_data.X = []
window()
function.f_read()
# 函数选择相关界面
F_root = tk.Frame(root_window, width=400, height=330, bg='white', )
F_root.place(x=490, y=60)
# 象限选择相关界面
Q_root = tk.Frame(root_window, width=400, height=50, bg='white', )
Q_root.place(x=20, y=410)
buttons()
f_button()
q_button()
show_fit()
root_window.protocol("WM_DELETE_WINDOW", close_window)
root_window.mainloop()
if __name__ == '__main__':
main()
pass

265
X5.py

@ -0,0 +1,265 @@
# -*- coding: utf-8 -*-
# Time : 2023/8/9 10:20
# Author : lirunsheng
# User : l'r's
# Software: PyCharm
# File : X4.py
# -*- encoding: utf-8 -*-
"""
@Author: packy945
@FileName: main.py
@DateTime: 2023/5/30 15:29
@SoftWare: PyCharm
"""
import sys
from fitting import *
import numpy as np
import data as gl_data
import input
import tkinter as tk
from tkinter import *
import tkinter.filedialog # 注意次数要将文件对话框导入
# from demo1 import Addfunc
global Q_root,F_root
global root_window
global label1,label2,label3
class Addfunc():
def __init__(self):
self.r = 7.5 # 设置按钮大小
self.rr = 2.5# 设置按钮大小
self.window = tk.Tk() # 新建函数增加窗口
self.window.title("新增函数曲线")#设置窗口标题
self.window.geometry('400x300')#设置窗口大小
self.show()#显示按钮
self.window.mainloop()#运行UI界面
def show(self):
for widget in self.window.winfo_children():
widget.destroy()#清空已有组件
self.add_cv = tk.Canvas(self.window, width=400, height=300) # 新建画布
self.add_cv.place(x=0, y=0) # 放置画布
cur = 0#记录已有按钮个数
for f in function.Fun:#遍历已有函数
self.add_cv.create_oval(20 - self.r, 20 + 15 + cur * 30 - self.r, 20 + self.r, 20 + 15 + cur * 30 + self.r
, fill="white", width=1, outline="black")# 绘制圆圈
if f.show == 1:#若为当前选中函数,则标记
self.add_cv.create_oval(20 - self.rr, 20 + 15 + cur * 30 - self.rr, 20 + self.rr, 20 + 15 + cur * 30 + self.rr
, fill="black", width=1, outline="black")
button = tk.Button(self.window, text=f.name + f.demo, bd=0, font=("微软雅黑", 12)
, command=lambda x=f.no: self.change(x), anchor=W)#设置选择按钮
button.place(x=40, y=20 + cur * 30, width=300, height=30)#放置选择按钮
cur += 1#计数加一
def change(self, no):#切换函数显示情况
function.Show[no] = not function.Show[no]
function.Fun[no].show = not function.Fun[no].show
self.show()#更新函数选择面板
f_button()#更新函数显示界面
# class AddFunc(Addfunc):
# def change(self, no):
# # super().change(no)
# function.Show[no] = not function.Show[no]
# function.Fun[no].show = not function.Fun[no].show
# self.show() # 更新函数选择面板
# f_button()
def addfunc():
Addfunc()
# AddFunc()
def window():
global root_window
global label1, label2, label3
root_window = Tk()
root_window.title('函数拟合')
root_window.geometry('900x600') # 设置窗口大小:宽x高,注,此处不能为 "*",必须使用 "x"
# 设置主窗口的背景颜色,颜色值可以是英文单词或者颜色值的16进制数,除此之外还可以使用Tk内置的颜色常量
root_window["background"] = "white"
root_window.resizable(0, 0) # 防止用户调整尺寸
label1 = tk.Label(root_window, text="样本数据\n集文件", font=('Times', 8), bg="white",
width=13, height=3, # 设置标签内容区大小
padx=0, pady=0, borderwidth=0, )
label1.place(x=10, y=4) # 设置填充区距离、边框宽度和其样式(凹陷式)
label3 = tk.Label(root_window, text="", font=('Times', 8), bg="white", fg="black",
width=39, height=2, padx=0, pady=0, borderwidth=0, relief="ridge", highlightcolor="blue")
label3.place(x=122, y=10)
# 使用按钮控件调用函数
tk.Button(root_window, text="装载", relief=RAISED, command=lambda: askfile()).place(x=370, y=12)
label2 = tk.Label(root_window, text="拟合曲线类型", font=('Times', 12), bg="white",
width=20, height=3, # 设置标签内容区大小
padx=0, pady=0, borderwidth=0, )
# 设置填充区距离、边框宽度和其样式(凹陷式)
label2.place(x=450, y=4)
gl_data.Canvas2 = tk.Canvas(root_window, bg='white', width=450, height=330)
gl_data.Canvas2.place(x=4, y=60)
# 定义一个处理文件的相关函数
def askfile():
# 从本地选择一个文件,并返回文件的路径
filename = tkinter.filedialog.askopenfilename()
if filename != '':#若选中了一个文件,则对文件进行读取
label3.config(text=filename)#显示文件路径
read_sample_data(filename)#将文件读取并存到sampleData中
# print_sample_data(filename)#将文件读取并逐行输出
selfdata_show(gl_data.X, gl_data.Y, gl_data.LOW, gl_data.HIGH)
else:#若未选择文件,则显示为空
label3.config(text='')
def print_sample_data(file_path):#打开对应文件
with open(file_path, 'r') as file:
for line in file:#逐行读取文件
line = line.strip('\n')#移除换行符
sx, sy = line.split(' ')#以空格分割xy
print(f'sx: {float(sx)}, sy: {float(sy)}')#将sx、sy转换为浮点数并打印
def read_sample_data(file_path):
x, y = [], []#初始化xy
with open(file_path, 'r') as file:
for line in file:#逐行读文件
line = line.strip('\n')#移除换行符
sx, sy = line.split(' ')#以空格分割xy
x.append(float(sx))#将sx转换为浮点数并加入数组
y.append(float(sy))#将sy转换为浮点数并加入数组
gl_data.X, gl_data.Y = np.array(x), np.array(y)#xy数组转为array并赋值给全局变量
def buttons():
# 随机生成样本点并显示
b_dot = tk.Button(root_window, text="生成\n数据集", relief=RAISED, bd=4, bg="white", font=("微软雅黑", 10),
command=lambda: generate_and_plot_sample_data(gl_data.LOW, gl_data.HIGH))
b_dot.place(x=455, y=410)
# 显示当前样本点
b_show = tk.Button(root_window, text="显示\n数据集", relief=RAISED, bd=4, bg="white", font=("微软雅黑", 10),
command=lambda: selfdata_show(gl_data.X, gl_data.Y, gl_data.LOW, gl_data.HIGH))
b_show.place(x=510, y=410)
# 显示数据集与曲线
b_line = tk.Button(root_window, text="显示数据\n集与曲线", relief=RAISED, bd=4, bg="white", font=("微软雅黑", 10),
command=lambda: draw_dots_and_line(gl_data.Xian_index, gl_data.LOW, gl_data.HIGH, gl_data.X, gl_data.Y))
b_line.place(x=565, y=410)
# 手动输入数据集
b_input = tk.Button(root_window, text="手动输入数据集", relief=RAISED, bd=4, bg="white", pady=7, font=("微软雅黑", 13),
command=lambda: input.input_num(root_window))
b_input.place(x=633, y=410)
# 拟合并输出拟合结果
b_fit = tk.Button(root_window, text="拟合", relief=RAISED, bd=4, bg="white", pady=7, font=("微软雅黑", 13),
command=lambda: fit_data(gl_data.Xian_index, gl_data.X, gl_data.Y))
b_fit.place(x=771, y=410)
def show_fit():
L = tk.Label(root_window, text='结果输出:', bg='white', font=("微软雅黑", 16)
, anchor=W)
L.place(x=20, y=480, width=100, height=30)
sout = str(gl_data.Out)
ans = tk.Label(root_window, text=sout, font=("微软雅黑", 14)
, anchor=W, justify='left')
ans.place(x=120, y=480, width=760, height=100)
print(sout)
def fit_data(xian_index, sx, sy):
# gl_data.yvals_pow = []
cur = function.Fun[xian_index] # 装载正在选择的函数
func = cur.get_fun()#获取当前函数func
popt, pcov = curve_fit(func, sx, sy)# 用curve_fit来对点进行拟合
yvals_pow = func(gl_data.X, *popt)
rr = gl_data.goodness_of_fit(yvals_pow, gl_data.Y)# 计算本次拟合的R*R值用于表示拟合优度
# 输出拟合后的各个参数值
ans = '\n函数系数:'
for i in range(cur.variable):
if i == 4:
ans += '\n'
if i != 0:
ans += ', '
ans += chr(ord('a') + i) + '=' + '{:.2e}'.format(popt[i]) # str(round(gl_data.popt[i], 3))
gl_data.Out = '函数形式:' + cur.name + ' '
gl_data.Out += cur.demo
gl_data.Out += ans
gl_data.Out += '\n拟合优度(R\u00b2)' + str(round(rr, 5))
show_fit()# 显示函数信息到输出框
def change_Q(no):
gl_data.Quadrant = no #更改全局变量的象限显示
if no:#若为一象限则修改显示下限为0
gl_data.LOW = 0
else:#若为四象限,则修改显示下限为-gl_data.maxV
gl_data.LOW = -gl_data.MAXV
q_button()#更新象限显示面板
def q_button():
r = 7.5
rr = 2.5
for widget in Q_root.winfo_children():
widget.destroy()
q_cv = tk.Canvas(Q_root, width=400, height=50)
q_cv.place(x=0, y=0)
l = tk.Label(Q_root, text='坐标轴', bd=0, font=("微软雅黑", 16)
, anchor=W)
l.place(x=20, y=0, width=80, height=50,)
# 四象限按钮
b1 = tk.Button(Q_root, text='四象限', bd=0, font=("微软雅黑", 16)
, command=lambda: change_Q(0), anchor=W)
b1.place(x=170, y=0, width=80, height=50,)
# 一象限按钮
b2 = tk.Button(Q_root, text='一象限', bd=0, font=("微软雅黑", 16)
, command=lambda: change_Q(1), anchor=W)
b2.place(x=320, y=0, width=80, height=50,)
# 绘制标记框
q_cv.create_oval(140 - r, 25 - r, 140 + r, 25 + r
, fill="white", width=1, outline="black")
q_cv.create_oval(290 - r, 25 - r, 290 + r, 25 + r
, fill="white", width=1, outline="black")
# 根据当前的象限选择值来填充标记框
if gl_data.Quadrant == 0:
q_cv.create_oval(140 - rr, 25 - rr, 140 + rr, 25 + rr
, fill="black", width=1, outline="black")
else:
q_cv.create_oval(290 - rr, 25 - rr, 290 + rr, 25 + rr
, fill="black", width=1, outline="black")
def change_f(no):
gl_data.Xian_index = no#设置全局函数编号为该函数
f_button()#重新绘制函数显示界面
def f_button():
r = 7.5#设置按钮大小
rr = 2.5#设置按钮大小
for widget in F_root.winfo_children():
widget.destroy()#清空原有按钮
f_cv = tk.Canvas(F_root, width=400, height=330)#新建画布
f_cv.place(x=0, y=0)#放置画布
f_cv.create_rectangle(2, 2, 398, 328, fill='white', outline="#0099ff")#设置画布边框及底色
cur = 0#函数计数
for fun in function.Fit_type_library:#遍历函数库
f = function.Fit_type_library.get(fun)#获取函数具体信息
if function.Show[f[0]] == 1:# 如果show为1则显示
f_cv.create_oval(20 - r, 20 + 15 + cur * 30 - r, 20 + r, 20 + 15 + cur * 30 + r
, fill="white", width=1, outline="black")# 绘制标记框
if f[0] == gl_data.Xian_index:# 若选择为当前函数则标记
f_cv.create_oval(20 - rr, 20 + 15 + cur * 30 - rr, 20 + rr, 20 + 15 + cur * 30 + rr
, fill="black", width=1, outline="black")
# 绘制切换按钮,单击则将当前使用函数切换为该函数
button = tk.Button(F_root, text=f[2] + ' ' + f[1], bd=0, bg="white", font=("微软雅黑", 12)
, command=lambda x=f[0]: change_f(x), anchor=W)
button.place(x=40, y=20 + cur * 30, width=300, height=30)
cur += 1#计数加一
def close_window():
sys.exit()
def main():
global Q_root, F_root,root_window
gl_data.X = []
gl_data.X = []
window()
# 函数选择相关界面
F_root = tk.Frame(root_window, width=400, height=330, bg='white', )
F_root.place(x=490, y=60)
# 象限选择相关界面
Q_root = tk.Frame(root_window, width=400, height=50, bg='white', )
Q_root.place(x=20, y=410)
function.f_read()
buttons()
f_button()
q_button()
show_fit()
tk.Button(root_window, text="新增拟合曲线类型", bd=4, command=addfunc).place(x=740, y=12)
root_window.protocol("WM_DELETE_WINDOW", close_window)
root_window.mainloop()
if __name__ == '__main__':
main()
pass

@ -0,0 +1,129 @@
# -*- encoding: utf-8 -*-
"""
@Author: packy945
@FileName: data.py
@DateTime: 2023/5/31 11:42
@SoftWare: PyCharm
"""
import tkinter as tk
from tkinter import *
import random
import numpy as np
X = [] # 等待拟合的x值
Y = [] # 等待拟合的y值
global Canvas2 # 用于显示函数的画布
Img1 = None # 绘制的dot.png图像
Img2 = None # 绘制的line.png图像
Xian_index = 0 # 当前选择的函数编号
Quadrant = 0 # 当前选择的象限信息0为四象限1为一象限
MAXV = 1000 # 最大值
Out = '' # 拟合输出信息
LOW = -MAXV # 坐标轴显示上界
HIGH = MAXV # 坐标轴显示下界
def random_points():
x=[]
y=[]
for i in range(20):
x_= random.uniform(0, 1000)#生成随机浮点数
y_= random.uniform(0, 1000)#生成随机浮点数
x.append(x_) #加入列表
y.append(y_)
x=np.array(x) #列表转数组
y=np.array(y)
arr = np.array(list(zip(x, y)))# 将两个一维数组拼接成二维数组
return arr
def compute_curveData(num, step, coefficient):#coefficient代表二次函数系数数组形式
def quadratic_function(x):#构造二次函数y = a * X^2 + b * X + C
return coefficient[0] * x ** 2 + coefficient[1] * x + coefficient[2]
x_values = np.arange(-num, num, step)
y_values = quadratic_function(x_values)#调用quadratic_function(x)函数得到y值
curve_data = np.column_stack((x_values, y_values))#将两个一维数组堆叠成二维数组,形成(x,y)的形式
return curve_data
# #################################拟合优度R^2的计算######################################
def __sst(y_no_fitting):
"""
计算SST(total sum of squares) 总平方和
:param y_no_predicted: List[int] or array[int] 待拟合的y
:return: 总平方和SST
"""
y_mean = sum(y_no_fitting) / len(y_no_fitting)
s_list =[(y - y_mean)**2 for y in y_no_fitting]
sst = sum(s_list)
return sst
def __ssr(y_fitting, y_no_fitting):
"""
计算SSR(regression sum of squares) 回归平方和
:param y_fitting: List[int] or array[int] 拟合好的y值
:param y_no_fitting: List[int] or array[int] 待拟合y值
:return: 回归平方和SSR
"""
y_mean = sum(y_no_fitting) / len(y_no_fitting)
s_list =[(y - y_mean)**2 for y in y_fitting]
ssr = sum(s_list)
return ssr
def __sse(y_fitting, y_no_fitting):
"""
计算SSE(error sum of squares) 残差平方和
:param y_fitting: List[int] or array[int] 拟合好的y值
:param y_no_fitting: List[int] or array[int] 待拟合y值
:return: 残差平方和SSE
"""
s_list = [(y_fitting[i] - y_no_fitting[i])**2 for i in range(len(y_fitting))]
sse = sum(s_list)
return sse
def goodness_of_fit(y_fitting, y_no_fitting):
"""
计算拟合优度R^2
:param y_fitting: List[int] or array[int] 拟合好的y值
:param y_no_fitting: List[int] or array[int] 待拟合y值
:return: 拟合优度R^2
"""
ssr = __ssr(y_fitting, y_no_fitting)
sst = __sst(y_no_fitting)
rr = ssr /sst
return rr
def least_sqaure(x,y):
n = len(x)
sumx, sumy, sumxy, sumxx = 0, 0, 0, 0
for i in range(0, n):
sumx += x[i]
sumy += y[i]
sumxx += x[i] * x[i]
sumxy += x[i] * y[i]
a = (n * sumxy - sumx * sumy) / (n * sumxx - sumx * sumx)
b = (sumxx * sumy - sumx * sumxy) / (n * sumxx - sumx * sumx)
return a, b
import time
def gradient_descent(x, y):
s = time.time()
x = 10000 * np.random.randn(1) # 产生服从正太分布的一个数(均值=0方差=1)扩大10000倍
eta = 0.09
i = 1
while True:
y = x ^ 2 / 2 - 2 * x
x -= eta * 2 * x
if y <= 0.0001:
print('x is %.6f\ny is %.6f\nand steps are %d' % (x, y, i))
break
i += 1
e = time.time()
print('time is %.4f second' % (e - s))
if __name__ == '__main__':
random_points()
pass

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

@ -0,0 +1,117 @@
# -*- encoding: utf-8 -*-
"""
@Author: packy945
@FileName: fitting.py
@DateTime: 2023/5/31 14:16
@SoftWare: PyCharm
"""
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import pylab as mpl
from tkinter import *
import mpl_toolkits.axisartist as axisartist
import data as gl_data
import function
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 解决中文不显示问题
plt.rcParams['axes.unicode_minus'] = False #解决负数坐标显示问题
def draw_axis(low, high, step=250):
fig = plt.figure(figsize=(4.4, 3.2))
ax = axisartist.Subplot(fig, 111)# 使用axisartist.Subplot方法创建一个绘图区对象ax
fig.add_axes(ax)# 将绘图区对象添加到画布中
ax.axis[:].set_visible(False)# 通过set_visible方法设置绘图区所有坐标轴隐藏
ax.axis["x"] = ax.new_floating_axis(0, 0)# 添加新的x坐标轴
ax.axis["x"].set_axisline_style("-|>", size=1.0)# 给x坐标轴加上箭头
ax.axis["y"] = ax.new_floating_axis(1, 0)# 添加新的y坐标轴
ax.axis["y"].set_axisline_style("-|>", size=1.0)# y坐标轴加上箭头
ax.axis["x"].set_axis_direction("bottom")# 设置x、y轴上刻度显示方向
ax.axis["y"].set_axis_direction("left")# 设置x、y轴上刻度显示方向
plt.xlim(low, high) # 把x轴的刻度范围设置
plt.ylim(low, high) # 把y轴的刻度范围设置
ax.set_xticks(np.arange(low, high + 5, step))# 把x轴的刻度间隔设置
ax.set_yticks(np.arange(low, high + 5, step))# 把y轴的刻度间隔设置
def generate_and_plot_sample_data(low, high):
num_samples = 25#设置样本点数量
gl_data.X = np.random.randint(low=low, high=high, size=num_samples)#随机生成x值
gl_data.Y = np.random.randint(low=low, high=high, size=num_samples)#随机生成y值
draw_axis(low, high)#绘制坐标轴
plt.scatter(gl_data.X, gl_data.Y, color='red') # 绘制样本数据点
plt.savefig(r"dot.png", facecolor='w')#保存到本地
plt.close()#清除内存
set_phtot(1)#显示到主界面
# 显示数据集
def selfdata_show(x, y, low, high):# 显示数据集
num_points = len(x) # 样本数据点的数量
colors = np.random.rand(num_points, 3)# 生成随机颜色
draw_axis(low, high)
plt.scatter(x, y, c=colors)# 绘制样本数据点
plt.savefig(r"dot.png", facecolor='w') # 保存为png文件
plt.clf()
set_phtot(1)
def draw_line(xian_index, low, high, sx, sy):
draw_axis(low, high)#绘制坐标轴
popt = []#初始化curve_fit
pcov = []#初始化curve_fit
cur = function.Fun[xian_index] # 装载正在选择的函数
func = cur.get_fun()#获取当前函数func
popt, pcov = curve_fit(func, sx, sy)# 用curve_fit来对点进行拟合
curve_x = np.arange(low, high)#按照步长生成的一串数字
curve_y = [func(i, *popt) for i in curve_x]# 根据x0(按照步长生成的一串数字)来计算y1值
plt.plot(curve_x, curve_y, color='blue', label='Fitted Curve')#绘制拟合曲线
plt.legend()
# plt.show()#显示函数图像
plt.savefig(r"line.png", facecolor='w')#将图片保存到本地
plt.close()#清除内存
set_phtot(2)#将图片显示到程序中
def draw_dots_and_line(xian_index, low, high, sx, sy):
############## begin #####################
draw_axis(low, high)
popt = []
pcov = []
cur = function.Fun[xian_index] # 装载正在选择的函数
func = cur.get_fun()#获取当前函数func
popt, pcov = curve_fit(func, sx, sy)# 用curve_fit来对点进行拟合
positive_mask = sy >= 0.0#给样本点分类
negative_mask = sy < 0.0#给样本点分类
positive_colors = ['red' if x >= 0.0 else 'blue' for x in sx]#给样本点分类
negative_colors = ['green' if x >= 0.0 else 'purple' for x in sx]#给样本点分类
#根据样本点类型决定样本点颜色
plt.scatter(gl_data.X[positive_mask], gl_data.Y[positive_mask], color=np.array(positive_colors)[positive_mask], lw=1)
plt.scatter(gl_data.X[negative_mask], gl_data.Y[negative_mask], color=np.array(negative_colors)[negative_mask], lw=1)
curve_x = np.arange(low, high)#按照步长生成的一串数字
curve_y = [func(i, *popt) for i in curve_x]# 根据x0(按照步长生成的一串数字)来计算y1值
############## end #######################
plt.plot(curve_x, curve_y, color='blue', label='Fitted Curve')#绘制拟合曲线
plt.legend()
plt.savefig(r"line.png", facecolor='w')#将图片保存到本地
plt.close()#清除内存
set_phtot(2)#将图片显示到程序中
def set_phtot(index1):
# 显示图像
Canvas2 = gl_data.Canvas2
if index1 == 1:
gl_data.Img1=PhotoImage(file=r"dot.png")
# print(gl_data.Img1)
set_img1=Canvas2.create_image(2, 10, image=gl_data.Img1, anchor=NW)
Canvas2.update()
print("已输出数据点")
elif index1 == 2:
gl_data.Img2=PhotoImage(file=r"line.png")
# print(gl_data.Img2)
set_img2=Canvas2.create_image(2, 10, image=gl_data.Img2, anchor=NW)
Canvas2.update()
print("已输出数据点和曲线")
if __name__ == '__main__':
# random_points()
pass

@ -0,0 +1,137 @@
# -*- encoding: utf-8 -*-
"""
@Author: packy945
@FileName: function.py
@DateTime: 2023/6/6 14:45
@SoftWare: PyCharm
"""
import numpy as np
import math
import data
import pandas as pd
from pandas import DataFrame
# 函数库
Show = []
Fun = []
Fit_type_library = {}
class Function:
def __init__(self, no, name, v, fun, complete='', demo=''):
# 函数名称
self.name = name
# 变量个数
self.variable = v
self.function = fun
# 函数编号
self.no = no
# 是否显示
self.show = 0
# 完整函数
self.complete = complete
# self.print = ''
self.demo = demo
def get_fun(self):
if self.variable == 2:
return self.fun2
elif self.variable == 3:
return self.fun3
elif self.variable == 4:
return self.fun4
elif self.variable == 5:
return self.fun5
elif self.variable == 6:
return self.fun6
def fun2(self, x, a0, a1):
return eval(self.function)
def fun3(self, x, a0, a1, a2):
return eval(self.function)
def fun4(self, x, a0, a1, a2, a3):
return eval(self.function)
def fun5(self, x, a0, a1, a2, a3, a4):
return eval(self.function)
def fun6(self, x, a0, a1, a2, a3, a4, a5):
return eval(self.function)
def print_f(self, a):
# print('self.show='+self.complete)
exec('self.show='+self.complete)
# print(self.show)
return self.show
def f_init():
cur = 0 # 函数编号
# 一次函数
newfun = Function(cur, '一次函数', 2, 'a0*x+a1', "f'{a[0]}x+{a[1]}'", 'ax+b')
newfun.show = 1
Fun.append(newfun)
cur += 1
# 二次函数
newfun = Function(cur, '二次函数', 3, 'a0*x*x+a1*x+a2', "f'{a[0]}x^2+{a[1]}x+{a[2]}'", 'ax^2+bx+c')
newfun.show = 1
Fun.append(newfun)
cur += 1
# 三次函数
newfun = Function(cur, '三次函数', 4, 'a0*x*x*x+a1*x*x+a2*x+a3', "f'{a[0]}x^3+{a[1]}x^2+{a[2]}x+{a[3]}'", 'ax^3+bx^2+cx+d')
newfun.show = 0
Fun.append(newfun)
cur += 1
# 四次函数
newfun = Function(cur, '四次函数', 5, 'a0*x*x*x*x+a1*x*x*x+a2*x*x+a3*x+a4'
, "f'{a[0]}x^4+{a[1]}x^3+{a[2]}x^2+{a[3]}x+{a[4]}'", 'ax^4+bx^3+cx^2+dx+e')
newfun.show = 0
Fun.append(newfun)
cur += 1
# 指数函数
newfun = Function(cur, '指数函数', 2, 'a0*np.exp(0.01*x)+a1', "f'{a[0]}e^(0.01x)+{a[1]}'", 'a*e^(0.01x)+b')
newfun.show = 0
Fun.append(newfun)
cur += 1
# 对数函数
newfun = Function(cur, '对数函数', 3, 'a0*(np.log(x) + 1e-5) / (np.log(a1) + 1e-5) + a2',
"f'{a[0]}log(x,{a[1]})+{a[2]}'", 'alog(x,b)+c')
newfun.show = 0
Fun.append(newfun)
cur += 1
# 高斯函数
# F_init()
def write():
file_path = 'functions.xlsx'#设置路径
df = pd.read_excel(io=file_path, header=1)#设置表格
print(df)
df.columns = ['no', 'name', 'variable', 'function', 'complete', 'demo', 'show']#设置表格标题
cur = 0#重置计数
for f in Fun:#遍历函数类型
df.loc[cur] = [cur, f.name, f.variable, f.function, f.complete, f.demo, f.show]#写进表格
cur += 1#计数加一
DataFrame(df).to_excel(file_path, sheet_name='Sheet1', index=False, header=True)#保存xlsx
def f_read():
file_path = 'functions.xlsx'#设置路径
df = pd.read_excel(io=file_path, header=0)#设置表格
cur = 0
for i in range(len(df)):#逐行读取excel
newfun = Function(df.loc[i][0], df.loc[i][1], df.loc[i][2], df.loc[i][3], df.loc[i][4], df.loc[i][5])
newfun.show = df.loc[i][6]
Show.append(df.loc[i][6])#读取函数显示信息
Fun.append(newfun)#读取函数信息并添加
cur += 1
for f in Fun:#建立简表fit_type_library
Fit_type_library[f.name] = [f.no, f.demo, f.name]
if __name__ == '__main__':
f_read()
# for f in fun:
# print([f.no, f.demo, f.name])
for f in Fun:
Fit_type_library[f.name] = [f.no, f.demo, f.name]
print(Fit_type_library)
a = [1,2,3,4,5]
x = 2
pass

Binary file not shown.

@ -0,0 +1,83 @@
# -*- encoding: utf-8 -*-
"""
@Author: packy945
@FileName: input.py
@DateTime: 2023/7/19 16:59
@SoftWare: PyCharm
"""
import tkinter as tk
import numpy as np
import data as gl_data
from tkinter import *
global top
def input_num(root_tk):
global top
top = tk.Toplevel(root_tk)
label1 = Label(top, text="坐标点个数")
label1.grid(row=0) # 这里的side可以赋值为LEFT RTGHT TOP BOTTOM
num1 = IntVar()
entry1 = Entry(top, textvariable=num1)
num1.set(0)
entry1.grid(row=0, column=1)
Label(top, text=" ").grid(row=0, column=3)
Button(top, text="确定", command=lambda: input_data(root_tk, int(entry1.get()))).grid(row=0, column=3)
top.mainloop()
def input_data(root_tk, num):
global top
sample_x = []
sample_y = []
sample_data = []
top.destroy()
top = tk.Toplevel(root_tk)
def add_sample_data():
try:
x = float(entry_x.get())
y = float(entry_y.get())
except:
label_status.config(text="输入不合法")
return
entry_x.delete(0, tk.END)
entry_y.delete(0, tk.END)
if min(x, y) < gl_data.low or max(x, y) > gl_data.high:
label_status.config(text="输入超过范围")
return
elif len(sample_data) < num:
label_status.config(text="点对已添加")
sample_data.append((x, y))
sample_x.append(x)
sample_y.append(y)
else:
label_status.config(text="已达到最大数量")
def check_sample_data():
if len(sample_data) == num:
label_status.config(text="已达到最大数量")
gl_data.x = np.array(sample_x)
gl_data.y = np.array(sample_y)
print('已添加', sample_data)
top.destroy()
else:
label_status.config(text="还需输入{}个点对".format(num - len(sample_data)))
print(sample_data)
label_x = tk.Label(top, text="X 值:")
label_x.pack()
entry_x = tk.Entry(top)
entry_x.pack()
label_y = tk.Label(top, text="Y 值:")
label_y.pack()
entry_y = tk.Entry(top)
entry_y.pack()
button_add = tk.Button(top, text="添加", command=add_sample_data)
button_add.pack()
button_check = tk.Button(top, text="检查", command=check_sample_data)
button_check.pack()
label_status = tk.Label(top, text="")
label_status.pack()
top.mainloop()
if __name__ == '__main__':
root = tk.Tk()
input_num(root)

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

@ -0,0 +1,30 @@
-1000.000000 -303.919733
-934.000000 -350.424580
-868.000000 -193.369993
-802.000000 -474.832293
-736.000000 -101.068322
-670.000000 -33.916365
-604.000000 -164.504704
-538.000000 -147.298119
-472.000000 -124.814141
-406.000000 -139.033018
-340.000000 -69.265051
-274.000000 -90.553084
-208.000000 -114.709905
-142.000000 -103.201058
-76.000000 -108.245882
-10.000000 56.710600
56.000000 18.503031
122.000000 185.633626
188.000000 152.615324
254.000000 47.216669
320.000000 256.009421
386.000000 270.790257
452.000000 61.971014
518.000000 121.635726
584.000000 163.906089
650.000000 166.204626
716.000000 315.640621
782.000000 425.649206
848.000000 454.347899
914.000000 289.943295

@ -0,0 +1,30 @@
-1000.000000 -2412.037897
-934.000000 -1906.704565
-868.000000 -1515.407287
-802.000000 -1286.984468
-736.000000 -991.348043
-670.000000 -699.579002
-604.000000 -834.074507
-538.000000 -694.557977
-472.000000 -503.237387
-406.000000 -288.033015
-340.000000 -248.449961
-274.000000 -317.763223
-208.000000 -254.540871
-142.000000 -269.952677
-76.000000 -252.274149
-10.000000 -373.987676
56.000000 -129.655207
122.000000 -325.928443
188.000000 -98.240616
254.000000 -325.921235
320.000000 -161.796895
386.000000 96.648543
452.000000 -245.636986
518.000000 190.848311
584.000000 225.026237
650.000000 317.523583
716.000000 772.606080
782.000000 645.906241
848.000000 1091.495759
914.000000 1225.588183

@ -0,0 +1,30 @@
-1000.000000 1318.415137
-934.000000 971.366429
-868.000000 950.320306
-802.000000 635.325663
-736.000000 774.823634
-670.000000 659.035975
-604.000000 449.284057
-538.000000 262.096521
-472.000000 141.521962
-406.000000 65.441983
-340.000000 162.273141
-274.000000 209.914028
-208.000000 62.504373
-142.000000 -160.439640
-76.000000 -201.140961
-10.000000 -178.764894
56.000000 -194.056288
122.000000 -221.386689
188.000000 -236.245098
254.000000 -317.086262
320.000000 -385.718988
386.000000 -198.736083
452.000000 -256.246461
518.000000 -226.361577
584.000000 -329.214396
650.000000 98.251218
716.000000 -132.314476
782.000000 62.741428
848.000000 120.654860
914.000000 356.397702

@ -0,0 +1,30 @@
-1000.000000 6580.374854
-934.000000 5230.299130
-868.000000 4064.603309
-802.000000 2824.002023
-736.000000 2151.187862
-670.000000 1341.067791
-604.000000 997.401541
-538.000000 512.994167
-472.000000 103.881466
-406.000000 85.927912
-340.000000 -256.482213
-274.000000 -97.197686
-208.000000 -264.665117
-142.000000 -237.702195
-76.000000 -151.105677
-10.000000 -130.269796
56.000000 -102.814456
122.000000 -62.662181
188.000000 -357.518806
254.000000 -149.197016
320.000000 -350.461131
386.000000 -264.914106
452.000000 -94.032078
518.000000 -188.344844
584.000000 -60.854287
650.000000 85.277762
716.000000 413.822510
782.000000 695.033449
848.000000 1169.069640
914.000000 1762.153163

@ -0,0 +1,16 @@
1.000000 -14.349565
67.000000 321.611473
133.000000 375.298867
199.000000 386.511032
265.000000 408.069269
331.000000 423.359694
397.000000 435.982565
463.000000 458.199244
529.000000 451.417416
595.000000 471.376855
661.000000 484.015127
727.000000 489.640132
793.000000 500.047206
859.000000 499.698564
925.000000 492.870266
991.000000 509.779156

@ -0,0 +1,30 @@
-1000.000000 282.188733
-934.000000 -121.080276
-868.000000 89.565718
-802.000000 -36.875112
-736.000000 -2.179209
-670.000000 -33.756961
-604.000000 -199.536348
-538.000000 -50.378169
-472.000000 7.288867
-406.000000 197.918480
-340.000000 18.543165
-274.000000 -80.038062
-208.000000 -0.092604
-142.000000 24.234519
-76.000000 112.628196
-10.000000 57.868872
56.000000 -75.900181
122.000000 53.411782
188.000000 14.463053
254.000000 -157.854773
320.000000 3.419914
386.000000 -95.442953
452.000000 -511.818439
518.000000 -785.633833
584.000000 -1377.367723
650.000000 -2606.119973
716.000000 -5115.078474
782.000000 -9770.399635
848.000000 -19298.079697
914.000000 -37316.681269
Loading…
Cancel
Save