这篇文章的由来:前几天在做大学物理居家实验水滴法测量声速 的时候需要使用phyphox软件导出的数据拟合y=1/(a+b*x)曲线。虽然老师要求使用Origin软件拟合,但是在使用还是有点用不明白(太懒),所以想用python来拟合。
给出具体的函数形式(任意),用最小二乘法去拟合。可以在func
定义要拟合的曲线下面给出具体的代码
点击下载数据(我把我做大物实验的数据放在这里)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def func(x, a, b):
return 1 / (a + b * x)
def compute_voice_speed(a, b):
L0 = 0.08
L1 = 0.065
t1 = 15.48
bb = L1 / t1
v1 = (4 * L0) / a
v2 = (-4 * bb) / b
if __name__ == '__main__':
data = './data.xls'
df = pd.read_excel(data)
x = np.array(df[df.columns[0]])
y = np.array(df[df.columns[1]])
plt.scatter(x, y)
popt, pcov = curve_fit(func, x, y)
a = popt[0]
b = popt[1]
print('a:{}, b:{}'.format(a, b))
y_pre = func(x, a, b)
plt.plot(x, y_pre, 'r')
compute_voice_speed(a, b)
plt.show()
曲线拟合结果如下图所示
数学上可以证明,任何函数都可以拟合成多项式函数,这里做一个演示,依旧使用刚刚的数据。
使用numpy的polyfit函数(最小二乘法逼近)
numpy.polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False)
x:要拟合点的横坐标
y:要拟合点的纵坐标
deg:自由度.例如:自由度为2,那么拟合出来的曲线就是二次函数,自由度是3,拟合出来的曲线就是3次函数
def polyfit_func(x, y):
para = np.polyfit(x, y, deg=2)
print(para)
A, B, C = para[0], para[1], para[2]
Y = A * (x**2) + B * x + C
plt.plot(x, Y, 'g')
plt.show()