【问题标题】:Can I fit half a Gaussian to a dataset in Python?我可以将半个高斯拟合到 Python 中的数据集吗?
【发布时间】:2019-11-21 08:30:41
【问题描述】:

我正在尝试自动将高斯拟合到数据中,但 scipy 似乎无法拟合仅显示一半曲线的数据。但是,Scipy 似乎无法做到这一点。

高斯曲线数据右侧的样子: https://i.imgur.com/LwzN2Jd.png

我尝试使用下面的代码来拟合曲线。它非常适合完全曲线。但是对于半曲线,它会变平

'''

plotData = {}

#x = 0,2.5,5
#y = 16766,508,600.6

modelDataDf = df.loc[:,["x","y"]]
modelDataDf.sort_values(by=["x"],inplace=True)
modelData = modelDataDf.to_dict(orient="list")


def _1gaussian(x, amp1,cen1,sigma1):
        return amp1*(1/(sigma1*(np.sqrt(2*np.pi))))*(np.exp(-((x-cen1)**2)/((2*sigma1)**2)))

x_array = np.asarray(modelData["x"])
y_array_gauss = np.asarray(modelData["y"])
amp1 = 29000
sigma1 = 1
cen1 = -1

popt_gauss, pcov_gauss = scipy.optimize.curve_fit(_1gaussian, x_array, y_array_gauss, p0=[amp1, cen1, sigma1])
perr_gauss = np.sqrt(np.diag(pcov_gauss))

plotData["xGaussCurve"] = np.arange(0, 5.05, 0.05)
plotData["yGaussCurve"] = _1gaussian(plotData["xGaussCurve"],*popt_gauss)

'''

合身的样子: https://i.imgur.com/0gfqiRF.png

它卡住的半高斯: https://i.imgur.com/Jsi4fzA.png

蓝点表示数据,粗红线表示我希望它显示的拟合,红色虚线表示拟合失败。

我得到错误:

RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 800.

当试图拟合半高斯时。

【问题讨论】:

  • 不确定它是否会起作用,但您可以尝试修改_1gaussian 函数,使其仅建模一半(通过与0 if x < cen1 else 1 相乘)。
  • 3 个数据点肯定不足以获得良好的拟合......特别是,如果在 0 和最大值之间(在 x=0 处)高度处没有点,则没有什么可以确定高斯的宽度(它可能非常非常薄或“尽可能大”,这也没有很好的定义)

标签: python scipy curve-fitting gaussian


【解决方案1】:

正如评论的那样,您将无法完全拟合只有三个数据点的高斯 - 参数与观测值一样多。

但是,如果您确定它是“一半”高斯,那么这意味着您知道高斯的质心应该在哪里(可能在 x=0 或 x=-1 或其他位置)。如果是这种情况,您可以修复质心并改变高斯的幅度和 sigma。也许像

from lmfit.models import GaussianModel

modelDataDf = df.loc[:,["x","y"]]
modelDataDf.sort_values(by=["x"],inplace=True)
modelData = modelDataDf.to_dict(orient="list")

x_array = np.asarray(modelData["x"])
y_array_gauss = np.asarray(modelData["y"])

model = GaussianModel()
params = model.make_params(amplitude=29000, sigma=1, center=-1)
params['center'].vary = False  # fix the centroid at -1

result = model.fit(y_array_gauss, params, x=x_array)
print(result.fit_report())

xplot = np.linspace(0, 5, 101)
yplot = result.eval(x=xplot)

【讨论】:

  • 什么是lmfit
猜你喜欢
  • 1970-01-01
  • 2019-01-17
  • 1970-01-01
  • 2017-06-11
  • 1970-01-01
  • 2017-08-30
  • 2017-04-02
  • 2017-09-15
  • 1970-01-01
相关资源
最近更新 更多