尝试对数据进行高斯+直线拟合

Trying to fit a Gaussian+Line fit to data

我对 python 和一般编程还很陌生(我大约一个月前开始学习)。我现在正在做一个项目。如果我对行话的掌握不够,我深表歉意。

我得到了一个 csv 文件,其中包含一个波长,然后是该波长的 30 个观测值。我应该 运行 一些将波长作为自变量的代码,然后将一组观察值作为因变量。由此,我必须对数据拟合一个线+高斯函数,并且我可以将高斯的均值(mu)作为我需要进行更多分析的变量。为了得到一个很好的拟合,我必须找到一种方法来自动对 Gaussian+line 的参数进行初始猜测。我觉得我可能已经以某种方式偶然发现了这一点,因为它为每组观察结果生成的高斯拟合似乎非常适合。对直线的梯度和 y 轴截距进行良好估计的一种方法是绘制数据的线性拟合,并在高斯+直线拟合中使用 m 和 c 的那些值,但我不确定我是否有做对了。

我的问题是,如何从该数据中提取高斯均值 (mu) 的值? 现在,我的控制台显示 0 +/- 0意思是,即使那肯定不是真的。我将要展示的代码是针对第二组观察的,尽管我希望一旦我获得一组观察的代码,我可以简单地复制并粘贴所有其他观察集的代码,并简单地调整读入的数据.

x=spectral_data[:,0] #selecting column 0 to be x-axis data
y2=spectral_data[:,2] #selecting column 1 to be y-axis data
plt.scatter(x,y2) #produce scatter plot
plt.title('Observation 2')
plt.ylabel('Intensity (arbitrary units)')
plt.xlabel('Wavelength (m)')

m,c=np.polyfit(x,y2,deg=1) #fits a linear model to the data, with m = slope and c = intercept
plt.plot(x,y2,'*')
plt.plot(x,c+m*x,'-') #plots the fit
print('The slope and intercept of the regression is,', m,c)
m_best=m
c_best=c
def fit_gauss(x,a,mu,sig,m,c): #defining a function for the gaussian+line fit
    gaus = a*sp.exp(-(x-mu)**2/(2*sig**2))
    line = m*x+c
    return gaus + line

initial_guess=[160,7.1*10**-7,0.2*10**-7,m_best,c_best]
po,po_cov=sp.optimize.curve_fit(fit_gauss,x,y2,initial_guess)

#print("The parameters")
#print(po)
#print('The covariance matrix')
#print(po_cov)

print("The signal parameters are")
print(" Gaussian amplitude = %.1f +/- %.1f" %(po[0],sp.sqrt(po_cov[0,0])))
print(" mu = %.1f +/- %.1f"%(po[1],sp.sqrt(po_cov[1,1])))
print(" Gaussian width (sigma) = %.1f +/- %.1f"%(po[2],sp.sqrt(po_cov[2,2])))
print("and the background estimate is")
print(" m = %.2f +/- %.2f"%(po[3],sp.sqrt(po_cov[3,3])))
print(" c = %.0f +/- %.0f"%(po[4],sp.sqrt(po_cov[4,4])))

plt.plot(x,fit_gauss(x,po[0],po[1],po[2],po[3],po[4]),label='Fit results')
plt.legend()

plt.show()

控制台响应

The slope and intercept of the regression is, 699564146.8510102 -314.0882660868497
The signal parameters are
 Gaussian amplitude = 26.7 +/- 0.6
 mu = 0.0 +/- 0.0
 Gaussian width (sigma) = 0.0 +/- 0.0
and the background estimate is
 m = 595726198.94 +/- 7933451.82
 c = -247 +/- 6

控制台响应

数据图

在代码底部出现打印之前,您所做的一切都是正确的。所以你写:

print(" mu = %.1f +/- %.1f"%(po[1],sp.sqrt(po_cov[1,1])))

您使用 %.1f 指定精度,这意味着您的位数将被限制为点后的一位数。例如。 1294.423 变为 1294.4 但 0.001 将变为 0.0!有关更多信息,请查看示例:
https://pyformat.info/
查看您的绘图,您可以看到数据的大小为 1e-7,因此字符串的格式按预期工作。您可以改用指数格式,即 %.1e 或者通过预先缩放数据来获得正确的幅度!