2017-07-12 67 views
3

我想找到并画出一个函数f,它代表一个曲线拟合在我已知的一些设定点上,x和y。python中的非线性曲线拟合程序

经过一番研究,我开始尝试scipy.optimize和curve_fit,但在参考指南中,我发现程序使用函数来拟合数据,并假设ydata = f(xdata,* params)+ eps。

所以我的问题是这样的:我需要改变我的代码以使用curve_fit或任何其他库来使用我的设置点来查找曲线的功能? (注意:我想知道这个函数,所以我可以稍后集成我的项目并绘制它)。我知道它将是一个衰减的指数函数,但不知道确切的参数。这是我在我的程序中试过的:

import numpy as np 
    import matplotlib.pyplot as plt 
    from scipy.optimize import curve_fit 

    def func(x, a, b, c): 
     return a * np.exp(-b * x) + c 

    xdata = np.array([0.2, 0.5, 0.8, 1]) 
    ydata = np.array([6, 1, 0.5, 0.2]) 
    plt.plot(xdata, ydata, 'b-', label='data') 
    popt, pcov = curve_fit(func, xdata, ydata) 
    plt.plot(xdata, func(xdata, *popt), 'r-', label='fit') 

    plt.xlabel('x') 
    plt.ylabel('y') 
    plt.legend() 
    plt.show() 

我目前正在Raspberry Pi上开发此项目,如果它改变了任何东西。因为它非常精确,所以希望使用最小二乘法,但任何其他可行的方法都很受欢迎。 再次,这是基于scipy库的参考指南。另外,我得到如下图,它甚至不是一个曲线:根据设定点

[1]

+2

一切正常,除了你绘制图表和曲线:'X = np.arange(0,1,0.01)'然后是'plt.plot(x,func(x,* popt),'r-',label ='fit')',因为您想要评估您的拟合函数多点,看到一个平稳的结果。关于拟合参数,它们在弹出数组中。 –

+1

实际上你现有的代码有什么问题?编辑:@MauroLacy证实了我的怀疑。 –

回答

3
import numpy as np 
import matplotlib.pyplot as plt 
from scipy.optimize import curve_fit 

def func(x, a, b, c): 
    return a * np.exp(-b * x) + c 

#c is a constant so taking the derivative makes it go to zero 
def deriv(x, a, b, c): 
    return -a * b * np.exp(-b * x) 

#Integrating gives you another c coefficient (offset) let's call it c1 and set it equal to zero by default 
def integ(x, a, b, c, c1 = 0): 
    return -a/b * np.exp(-b * x) + c*x + c1 

#There are only 4 (x,y) points here 
xdata = np.array([0.2, 0.5, 0.8, 1]) 
ydata = np.array([6, 1, 0.5, 0.2]) 

#curve_fit already uses "non-linear least squares to fit a function, f, to data" 
popt, pcov = curve_fit(func, xdata, ydata) 
a,b,c = popt #these are the optimal parameters for fitting your 4 data points 

#Now get more x values to plot the curve along so it looks like a curve 
step = 0.01 
fit_xs = np.arange(min(xdata),max(xdata),step) 

#Plot the results 
plt.plot(xdata, ydata, 'bx', label='data') 
plt.plot(fit_xs, func(fit_xs,a,b,c), 'r-', label='fit') 
plt.plot(fit_xs, deriv(fit_xs,a,b,c), 'g-', label='deriv') 
plt.plot(fit_xs, integ(fit_xs,a,b,c), 'm-', label='integ') 
plt.xlabel('x') 
plt.ylabel('y') 
plt.legend() 
plt.show() 

deriv and integ

+1

您应该以“bx”而不是曲线的形式显示数据(虽然这是一个相当一般的评论,但不要打扰太多) – jadsq

+0

我喜欢这个建议,我认为它更清楚地表明曲线是拟合的点 – mitoRibo

+0

嗯,这是有道理的,我需要步骤更好地适应曲线。那么为了清楚起见,func给了我曲线的方程?如果是这样,稍后我可以通过集成,派生等操作函数“func”? – Cmylife