Bar*_*nat 4 python numpy matplotlib curve-fitting data-fitting
我收集了一些数据来分析加速度随时间的变化。但是当我编写下面的代码以很好地拟合正弦波时,结果就是这样。这是因为我没有足够的数据还是我在这里做错了什么?
在这里你可以看到我的图表:
直接绘制测量结果(不适合)
适合水平和垂直移动(curve_fit)
linspace 增加数据
手动操纵幅度
编辑:我通过使用 linspace 函数并绘制它来增加数据大小,但我不确定为什么幅度不匹配,是因为需要分析的数据很少吗?(我能够手动操纵幅度,但我不明白为什么它不能做到这一点)
我用于拟合的代码
def model(x, a, b):
return a * np.sin(b * x)
param, parav_cov = cf(model, time, z_values)
array_x = np.linspace(800, 1400, 1000)
fig = plt.figure(figsize = (9, 4))
plt.scatter(time, z_values, color = "#3333cc", label = "Data")
plt.plot(array_x, model(array_x, param[0], param[1], param[2], param[3]), label = "Sin Fit")
Run Code Online (Sandbox Code Playgroud)
我会使用 FFT 来对参数进行初步猜测,因为这种事情是高度非线性的,curve_fit否则不太可能走得太远。使用 FFT 的原因是为了初步了解所涉及的频率,仅此而已。如果您还没有看过, 3Blue1Brown 有一个关于 FFT 的精彩视频
我使用网络绘图数字化仪从绘图中获取数据,然后将其导入 Python 并确保它看起来不错:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('sinfit2.csv')
print(df.head())
Run Code Online (Sandbox Code Playgroud)
给我:
x y
0 809.3 0.3
1 820.0 0.3
2 830.3 19.6
3 839.9 19.6
4 849.6 0.4
Run Code Online (Sandbox Code Playgroud)
我首先使用 NumPy 进行基本的 FFT(SciPy 具有fftpack更完整的完整功能,但这里不需要):
import numpy as np
from numpy.fft import fft
d = fft(df.y)
plt.plot(np.abs(d)[:len(d)//2], '.')
Run Code Online (Sandbox Code Playgroud)
这np.abs(d)是因为您得到一个包含相位和幅度的复数,并且[:len(d)//2]是因为(对于实值输入)输出关于中点对称,即d[5]== d[-5]。
这表示最大的组件是 18,我尝试手动绘制它,看起来不错:
x = np.linspace(0, np.pi * 2, len(df))
plt.plot(df.x, df.y, '.-', lw=1)
plt.plot(df.x, np.sin(x * 18) * 10 + 10)
Run Code Online (Sandbox Code Playgroud)
我乘以 10 再加上 10 是因为正弦的范围是 (-1, +1),我们需要将其变为 (0, 20)。
接下来,我将这些传递给curve_fit一个简化的模型来帮助它:
from scipy.optimize import curve_fit
def model(x, a, b):
return np.sin(x * a + b) * 10 + 10
(a, b), cov = curve_fit(model, x, df.y, [18, 0])
Run Code Online (Sandbox Code Playgroud)
我再次对 进行硬编码* 10 + 10以获得与您的数据相匹配的范围,这给了我a=17.8和b=2.97
最后,我绘制以更高频率采样的函数,以确保一切正常:
plt.plot(df.x, df.y)
plt.plot(
np.linspace(810, 1400, 501),
model(np.linspace(0, np.pi*2, 501), a, b)
)
Run Code Online (Sandbox Code Playgroud)
给我:
看起来不错。请注意,您可能想要更改这些参数,以便它们适合您原来的 X,并注意我df.x从 810 开始,所以我可能错过了第一点。
| 归档时间: |
|
| 查看次数: |
952 次 |
| 最近记录: |