使用lmfit进行2D高斯拟合

时间:2018-09-03 10:44:42

标签: python curve-fitting lmfit

我需要将二维高斯拟合到读取的数据集。我选择拟合例程是lmfit,因为它可以轻松实现边界条件和参数固定。由于我不是最高效的程序员,因此我在满足自己的需求方面遇到困难。这是我所做的:

from numpy import *
from math import *
from lmfit import Parameters,minimize,report_fit

## fails to run 
# from https://www.w3resource.com/python-exercises/numpy/python-numpy-exercise-79.php
x,y = meshgrid(linspace(-1,1,10),linspace(-1,1,10))
#d = sqrt(x*x+y*y)
#sigma, mu = 1.0, 0.0
#g = exp(-( (d-mu)**2 / ( 2.0 * sigma**2 ) ) )

def gaussian2D(p,x,y):
    height = p["height"].value
    centroid_x = p["centroid_x"].value
    centroid_y = p["centroid_y"].value
    sigma_x = p["sigma_x"].value
    sigma_y = p["sigma_y"].value
    background = p["background"].value
    return height*exp(-(((centroid_x-x)/sigma_x)**2+((centroid_y-y)/sigma_y)**2)/2.0)+background

def residuals(p,x,y,z):
    return z - gaussian2D(p,x,y)

initial = Parameters()
initial.add("height",value=1.)
initial.add("centroid_x",value=0.)
initial.add("centroid_y",value=0.)
initial.add("sigma_x",value=1.)
initial.add("sigma_y",value=3.)
initial.add("background",value=0.)

xx,yy = meshgrid(x,y)

fit = minimize(residuals,initial,args=(array(xx).flatten(),array(yy).flatten(),array(g).flatten()))
popt = fit.params
print report_fit(fit)

首先,用于生成2D高斯函数的示例代码无法运行,并给出d = sqrt(x x + y y)。无论如何,我都在使用文件中的数据,因此我正在使用网站here上给出的示例数据。

有些research told me将2D数组转换为1D数据,以便lmfit能够处理它们。我尝试在我的数组上使用flatten方法来实现该尝试失败,并给出了相同的错误(TypeError:只能将size-1数组转换为Python标量)。我不太了解链接中的代码。

特别感谢您的帮助。因为我更喜欢定义自己的函数以适合数据,而不是依赖于内置模型。

1 个答案:

答案 0 :(得分:1)

我认为您很亲密,只是在什么时候(或多久)打电话给meshgrid时弄混。修改后的版本将是

import numpy as np
from lmfit import Parameters, minimize, report_fit

x, y = np.meshgrid(np.linspace(-1, 1, 10), np.linspace(-1, 1, 10))

def gaussian2D(x, y, cen_x, cen_y, sig_x, sig_y, offset):
    return np.exp(-(((cen_x-x)/sig_x)**2 + ((cen_y-y)/sig_y)**2)/2.0) + offset

def residuals(p, x, y, z):
    height = p["height"].value
    cen_x = p["centroid_x"].value
    cen_y = p["centroid_y"].value
    sigma_x = p["sigma_x"].value
    sigma_y = p["sigma_y"].value
    offset = p["background"].value
    return (z - height*gaussian2D(x,y, cen_x, cen_y, sigma_x, sigma_y, offset))

# test data
g = gaussian2D(x, y, 1.2, 2.1, 0.5, 0.7, 1.1)


initial = Parameters()
initial.add("height",value=1.)
initial.add("centroid_x",value=0.)
initial.add("centroid_y",value=0.)
initial.add("sigma_x",value=1.)
initial.add("sigma_y",value=3.)
initial.add("background",value=0.)


fit = minimize(residuals, initial, args=(x, y, g))
print(report_fit(fit))

也就是说,定义一个gaussian2D()函数,您可以更好地使用和测试它,然后有一个简单的目标函数来调用它。