将多个高斯拟合到python中的数据 [英] fit multiple gaussians to the data in python
问题描述
我只是想知道是否有一种简单的方法可以实现对 10 个峰值的高斯/洛伦兹拟合并提取 fwhm 并确定 fwhm 在 x 值上的位置.复杂的方法是分离峰值并拟合数据并提取fwhm.
I am just wondering if there is a easy way to implement gaussian/lorentzian fits to 10 peaks and extract fwhm and also to determine the position of fwhm on the x-values. The complicated way is to separate the peaks and fit the data and extract fwhm.
数据是 [https://drive.google.com/file/d/0B6sUnnbyNGuOT2RZb2UwYXU4dlE/view?usp=sharing].
非常感谢任何建议.谢谢.
Any advise greatly appreciated. Thanks.
from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt('data.txt', delimiter=',')
x, y = data
plt.plot(x,y)
plt.show()
def func(x, *params):
y = np.zeros_like(x)
print len(params)
for i in range(0, len(params), 3):
ctr = params[i]
amp = params[i+1]
wid = params[i+2]
y = y + amp * np.exp( -((x - ctr)/wid)**2)
guess = [0, 60000, 80, 1000, 60000, 80]
for i in range(12):
guess += [60+80*i, 46000, 25]
popt, pcov = curve_fit(func, x, y, p0=guess)
print popt
fit = func(x, *popt)
plt.plot(x, y)
plt.plot(x, fit , 'r-')
plt.show()
Traceback (most recent call last):
File "C:Users est.py", line 33, in <module>
popt, pcov = curve_fit(func, x, y, p0=guess)
File "C:Python27libsite-packagesscipyoptimizeminpack.py", line 533, in curve_fit
res = leastsq(func, p0, args=args, full_output=1, **kw)
File "C:Python27libsite-packagesscipyoptimizeminpack.py", line 368, in leastsq
shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
File "C:Python27libsite-packagesscipyoptimizeminpack.py", line 19, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
File "C:Python27libsite-packagesscipyoptimizeminpack.py", line 444, in _ general_function
return function(xdata, *params) - ydata
TypeError: unsupported operand type(s) for -: 'NoneType' and 'float'
推荐答案
这需要非线性拟合.一个很好的工具是 scipy 的 curve_fit
函数.
This requires a non-linear fit. A good tool for this is scipy's curve_fit
function.
要使用 curve_fit
,我们需要一个模型函数,称为 func
,它接受 x
和我们的(猜测的)参数作为参数和返回 y
的相应值.作为我们的模型,我们使用高斯总和:
To use curve_fit
, we need a model function, call it func
, that takes x
and our (guessed) parameters as arguments and returns the corresponding values for y
. As our model, we use a sum of gaussians:
from scipy.optimize import curve_fit
import numpy as np
def func(x, *params):
y = np.zeros_like(x)
for i in range(0, len(params), 3):
ctr = params[i]
amp = params[i+1]
wid = params[i+2]
y = y + amp * np.exp( -((x - ctr)/wid)**2)
return y
现在,让我们为我们的参数创建一个初始猜测.这个猜测从 x=0
和 x=1,000
处的峰值开始,振幅为 60,000,e 折叠宽度为 80.然后,我们在 x= 处添加候选峰值60, 140, 220, ...
幅度为 46,000,宽度为 25:
Now, let's create an initial guess for our parameters. This guess starts with peaks at x=0
and x=1,000
with amplitude 60,000 and e-folding widths of 80. Then, we add candidate peaks at x=60, 140, 220, ...
with amplitude 46,000 and width of 25:
guess = [0, 60000, 80, 1000, 60000, 80]
for i in range(12):
guess += [60+80*i, 46000, 25]
现在,我们准备执行拟合:
Now, we are ready to perform the fit:
popt, pcov = curve_fit(func, x, y, p0=guess)
fit = func(x, *popt)
为了看看我们做得有多好,让我们绘制实际的 y
值(黑色实线曲线)和 fit
(红色虚线曲线)相对于 x的图代码>:
To see how well we did, let's plot the actual y
values (solid black curve) and the fit
(dashed red curve) against x
:
如您所见,合身度相当不错.
As you can see, the fit is fairly good.
from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt('data.txt', delimiter=',')
x, y = data
plt.plot(x,y)
plt.show()
def func(x, *params):
y = np.zeros_like(x)
for i in range(0, len(params), 3):
ctr = params[i]
amp = params[i+1]
wid = params[i+2]
y = y + amp * np.exp( -((x - ctr)/wid)**2)
return y
guess = [0, 60000, 80, 1000, 60000, 80]
for i in range(12):
guess += [60+80*i, 46000, 25]
popt, pcov = curve_fit(func, x, y, p0=guess)
print popt
fit = func(x, *popt)
plt.plot(x, y)
plt.plot(x, fit , 'r-')
plt.show()
这篇关于将多个高斯拟合到python中的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!