Roc*_*cky 6 python numpy scipy
我只是想知道是否有一种简单的方法来实现高斯/洛伦兹拟合到10个峰值并提取fwhm并且还确定fwhm在x值上的位置.复杂的方法是分离峰值并拟合数据并提取fwhm.
数据为[ https://drive.google.com/file/d/0B6sUnnbyNGuOT2RZb2UwYXU4dlE/view?usp=sharing].
任何建议非常感谢.谢谢.
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\test.py", line 33, in <module>
popt, pcov = curve_fit(func, x, y, p0=guess)
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 533, in curve_fit
res = leastsq(func, p0, args=args, full_output=1, **kw)
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 368, in leastsq
shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 19, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 444, in _ general_function
return function(xdata, *params) - ydata
TypeError: unsupported operand type(s) for -: 'NoneType' and 'float'
Run Code Online (Sandbox Code Playgroud)
Joh*_*024 16
这需要非线性拟合.一个很好的工具就是scipy的curve_fit功能.
要使用curve_fit,我们需要一个模型函数,调用它func,将x参数和我们的(猜测的)参数作为参数并返回相应的值y.作为我们的模型,我们使用一个高斯的总和:
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
Run Code Online (Sandbox Code Playgroud)
现在,让我们为我们的参数创建一个初始猜测.这个猜测与峰开始x=0和x=1,000用80幅60,000电子折叠宽度然后,我们在添加候补波峰x=60, 140, 220, ...振幅46000和25宽:
guess = [0, 60000, 80, 1000, 60000, 80]
for i in range(12):
guess += [60+80*i, 46000, 25]
Run Code Online (Sandbox Code Playgroud)
现在,我们已准备好执行拟合:
popt, pcov = curve_fit(func, x, y, p0=guess)
fit = func(x, *popt)
Run Code Online (Sandbox Code Playgroud)
为了看看我们做得多好,让我们绘制实际y值(纯黑色曲线)和fit(虚线红色曲线)对照x:

正如你所看到的,合适性非常好.
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()
Run Code Online (Sandbox Code Playgroud)