2015-11-26 72 views
0

我有一組點在第一象限看起來像高斯,我想在python中使用高斯擬合它,我的代碼如下:在Python中使用matplotlib和scipy只繪製高斯的一邊

import pylab as plb 
import matplotlib.pyplot as plt 
from scipy.optimize import curve_fit 
from scipy import asarray as ar,exp 
import math 


x=ar([37,69,157,238,274,319,391,495,533,626,1366,1855,2821,3615,4130,4374,6453,6863,7021, 
    7951,8646,9656,10464,11400]) 
y=ar([1.77,1.67,1.65,1.17,1.34,1.46,0.75,1,0.8,1.02,0.65,0.69,0.44,0.44,0.55,0.43,0.75,0.27,0.26, 
    0.44,0.04,0.44,0.26,0.04]) 



n = 24       #the number of data 
mean = sum(x*y)/n     #note this correction 
sigma = math.sqrt(sum(y*(x-mean)**2)/n)  #note this correction 

def gaus(x,a,x0,sigma): 
    return a*exp(-(x-x0)**2/(2*sigma**2)) 

popt,pcov = curve_fit(gaus,x,y,p0=None, sigma=None) #'''p0=[1,mean,sigma]''' 

plt.plot(x,y,'b+:',label='data') 
plt.plot(x,gaus(x,*popt),'ro:',label='fit') 
plt.legend() 
plt.title('Fig. 3 - Fit for Time Constant') 
plt.xlabel('Time (s)') 
plt.ylabel('Voltage (V)') 
plt.show() 

,輸出是:圖中: http://s2.postimg.org/wevggkc95/Workspace_1_022.png

爲什麼所有的紅點下方來了,另外請注意,我感興趣的一個半高斯作爲我的數據是這樣的,所以我的ÿ價值首先是大的,然後像高斯鐘的一邊那樣下降。任何人都可以告訴我如何在Python中適合這條曲線,(以防它不適合高斯)。換句話說,我想讓代碼適合我的點的一半(左側)高斯(僅在第一象限中)。請注意,我的分數不能像我早先嚐試的那樣呈指數遞減曲線擬合,並且在較低'x'值時不適合。

回答

0

顯然你的數據不適合或很容易適應高斯函數。您使用p0 = [1,1,1]的默認初始猜測,這與curve_fit在開始之前放棄的任何類型的最佳選擇(檢查popt=[1,1,1]pcov=[inf, inf, inf]的值)相距甚遠。你可以更好的猜測嘗試(例如p0 = [2,0, 2000]),但在我的系統就不會收斂:Optimal parameters not found: Number of calls to function has reached maxfev = 800.

,以適應「半高斯」,不浮動的中心位置x0(只要把它等於0 ):

def gaus(x,a,sigma): 
    return a*exp(-(x)**2/(2*sigma**2)) 

p0 = [1.2, 4000] 
popt,pcov = curve_fit(gaus,x,y,p0=p0) 

enter image description here

除非你有想適應高斯特殊原因,爲什麼不做一個更強大的線性最小二乘法擬合的多項式,例如:

pfit = np.polyfit(x, y, 3) 
poly = np.poly1d(pfit) 
+0

謝謝,我知道它看起來不像高斯,但它肯定就像高斯的正確部分。我想問一下,如果可能的話,是否可以有一種方法僅適用於半高斯分佈的數據集。 – PsJain

+0

@PsJain啊,好的 - 我已經編輯過讓你做到這一點的方法。 – xnx

+0

現在工作得非常好!非常感謝您的快速和準確的響應! – PsJain

相關問題