Python Spinmob curve_fit 工作,但适配器不工作

2024-04-28 11:47:13 发布

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

我想用高斯函数拟合数据。你知道吗

原始数据本身显示了一个非常明显的峰值。 当我尝试使用“曲线拟合”进行拟合时,拟合会标识峰值,但它没有曲线顶部。 我现在也在尝试用spinmob的fitter来拟合数据。然而,这个拟合只是给出了一条直线。你知道吗

我试过修改fitter的几个参数,高斯函数定义,以及fit的初始参数,但似乎没有任何效果。你知道吗

代码如下:

from scipy.optimize import curve_fit
from scipy import asarray as ar,exp
import spinmob as s

x = x30
y = ydata

def gaussian(x, A, mu, sig): # See http://mathworld.wolfram.com/GaussianFunction.html
    return A/(sig * np.sqrt(2*np.pi)) * np.exp(-np.power(x-mu, 2) / (2 * np.power(sig, 2)))

popt,pcov = curve_fit(gaussian,x,y,p0=[1,7.688,0.005])

FWHM = 2*np.sqrt(2*np.log(2))*popt[2]
print("FWHM: {}".format(FWHM))

plt.plot(x,y,'bo',label='data')
plt.plot(x,gaussian(x,*popt),'r+-',label='fit')
plt.legend()

fitter = s.data.fitter()
fitter.set(subtract_bg=True, plot_guess_zoom=True)
fitter.set_functions(f=gaussian, p='A=1,mu=8.688,sig=0.001')
fitter.set_data(x, y, eydata = 0.03)
fitter.fit()

曲线拟合返回此图: Curve_fit plot

spinmob fitter图给出: Spinmob Fitter Plot


Tags: 函数importdataplotnppltgaussianfit
1条回答
网友
1楼 · 发布于 2024-04-28 11:47:13

假设spinmob实际上使用了scipy.curve_fit,我会猜测(抱歉)问题是,您给它的初始值太远了,它不可能找到解决方案。你知道吗

当然,A=1scipy.curve_fit()spinmob.fitter()都不是一个很好的猜测。峰值肯定是负数,你应该猜一个更像-0.1而不是+1的值。实际上,您可以断言A必须是<;0。你知道吗

您给curve_fit()mu的初始值7.688非常好,它将允许一个解决方案。我不知道这是否是一个输入错误,但是您给spinmob.fitter()mu的初始值8.688是非常遥远的(也就是说,远远超出了数据范围),拟合永远无法从那里优化到正确的解决方案。你知道吗

初始值对曲线拟合很重要,初始值不好会导致不好的结果。你知道吗

它可能被一些人视为一个无耻的插头,但请允许我鼓励您尝试lmfithttps://lmfit.github.io/lmfit-py/)(我是主要作者)解决这类问题。Lmfit将参数值数组替换为命名的参数对象,以便更好地组织拟合。它还有一个内置的高斯模型(它也计算半高宽,包括不确定性)。也就是说,使用Lmfit,您的脚本可能如下所示:

import numpy as np
import matplotlib.pyplot as plt

from lmfit.models import GaussianModel
from lmfit.lineshapes import gaussian

# create fake data that looks like yours
xdata = 7.670 + np.arange(41)*0.0010
ydata = gaussian(xdata, amplitude=-0.196, center=7.6881, sigma=0.001)
ydata += np.random.normal(size=41, scale=10.0)

# create gaussian model
gmodel = GaussianModel()

# fit data, giving initial values for amplitude, center, and sigma
result = gmodel.fit(ydata, x=xdata, amplitude=-0.1, center=7.688, sigma=0.005)

# show results
print(result.fit_report())
plt.plot(xdata, ydata, 'bo', label='data')
plt.plot(xdata, result.best_fit, 'r+-', label='fit')
plt.legend()
plt.show()

这将打印出一份报告,如

[Model]]
    Model(gaussian)
[[Fit Statistics]]
    # fitting method   = leastsq
    # function evals   = 21
    # data points      = 41
    # variables        = 3
    chi-square         = 5114.87632
    reduced chi-square = 134.602009
    Akaike info crit   = 203.879794
    Bayesian info crit = 209.020510
[[Variables]]
    sigma:      9.7713e-04 +/- 1.5456e-04 (15.82%) (init = 0.005)
    center:     7.68822727 +/- 1.5484e-04 (0.00%) (init = 7.688)
    amplitude: -0.19273945 +/- 0.02643400 (13.71%) (init = -0.1)
    fwhm:       0.00230096 +/- 3.6396e-04 (15.82%) == '2.3548200*sigma'
    height:    -78.6917624 +/- 10.7894236 (13.71%) == '0.3989423*amplitude/max(1.e-15, sigma)'
[[Correlations]] (unreported correlations are < 0.100)
    C(sigma, amplitude) = -0.577

并生成一个数据图和最佳拟合 enter image description here

应该和你想做的很接近。你知道吗

相关问题 更多 >