python曲线拟合不能给出合理的拟合结果

2024-05-15 22:10:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着把高斯拟合到一个光谱中,y值是10^(-19)的数量级。曲线拟合给我的拟合结果很差,在我将整个数据乘以10^(-19)之前和之后。附件是我的代码,它是一组相当简单的数据,只是值很小。如果我想保持我的原始值,我如何得到一个合理的高斯拟合,给我正确的参数?在

#get fits data
aaa=pyfits.getdata('p1.cal.fits')

aaa=np.matrix(aaa)
nrow=np.shape(aaa)[0]
ncol=np.shape(aaa)[1]

ylo=79
yhi=90
xlo=0
xhi=1023
glo=430
ghi=470

#sum all the rows to get spectrum
ysum=[]
for x in range(xlo,xhi):
sum=np.sum(aaa[ylo:yhi,x])
ysum.append(sum)

wavelen_pix=range(xhi-xlo)
max=np.max(ysum)
print "maximum is at x=", np.where(ysum==max)

##fit gaussian
#fit only part of my data in the chosen range [glo:ghi]
x=wavelen_pix[glo:ghi]
y=ysum[glo:ghi]
def func(x, a, x0, sigma):
    return a*np.exp(-(x-x0)**2/float((2*sigma**2)))

sig=np.std(ysum[500:1000]) #std of background noise

popt, pcov = curve_fit(func, x, sig)
print popt  
#this gives me [1.,1.,1.], which is obviously wrong
gaus=func(x,popt[0],popt[1],popt[2])

aaa是一个153×1024的图像矩阵,部分如下所示:

^{pr2}$

Tags: 数据getnprangemaxfitfuncsum
1条回答
网友
1楼 · 发布于 2024-05-15 22:10:03

您错误地调用了curve_fit,下面是用法

curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False, check_finite=True, **kw)
  • f是您的函数,它的第一个参数是一组自变量,其后续参数是函数参数(如振幅、中心等)
  • 扩展数据是自变量
  • ydata是依赖变量
  • p0是对函数参数的初始猜测(对于Guassian,这是振幅、宽度和中心)

默认情况下,p0被设置为一个1的列表[1,1,…],这可能就是为什么您得到的结果是,fit永远不会执行,因为您调用不正确。在

尝试从数据中估计振幅、中心和宽度,然后制作一个p0对象(详见下文)

^{pr2}$

下面是一个简短的例子

xdata = np.linspace(0, 4, 50)
mygauss = ( 10,2,0.5) #( amp, center, width)
y     = func(xdata, *mygauss  ) # using your func defined above    
ydata = y + 2*(np.random.random(50)- 0.5) # add some noise to create fake data

现在我能猜出合适的参数了

ai    = np.max( ydata) # guess the amplitude
xi    = xdata[ np.argmax( ydata)] # guess the position of center

猜测宽度是很棘手的,我首先会找到半最大值的位置(有两个,但您只需要找到一个,因为高斯是对称的):

pos_half = argmin( np.abs( ydata-ao/2 ) ) # subtract half the amplitude and find the minimum

现在评估这是从高斯中心(席)的距离:

sig_i = np.abs( xi - xdata[ pos_half] ) # estimate the width

现在你可以做出初步的猜测了

init_guess = (ai, xi sig_i)

合身

params, variance = curve_fit( func, xdata=xdata, ydata=ydata, p0=init_guess)
print params
#array([ 9.99457443,  2.01992858,  0.49599629])

非常接近mygauss。希望有帮助。在

相关问题 更多 >