2017-07-12 65 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