简体   繁体   English

使用 lmfit 进行二维高斯拟合

[英]2D Gaussian fit using lmfit

I need to fit a two dimensional Gaussian to a data set I read in. My choice of fitting routine is lmfit, as it allows easy implementation of boundary conditions and fixing of parameters.我需要将二维高斯拟合到我读入的数据集。我选择的拟合例程是 lmfit,因为它可以轻松实现边界条件和固定参数。 As I am not the most efficient progammer, I have problems implementing my needs.由于我不是最有效率的程序员,我在实现我的需求时遇到了问题。 Here is what I did:这是我所做的:

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)

First of all, the sample code to generate a 2D Gaussian fails to run and gives a "TypeError: only size-1 arrays can be converted to Python scalars" for d = sqrt(x x+y y).首先,生成二维高斯的示例代码无法运行并给出“TypeError: only size-1 arrays can be convert to Python scalars” for d = sqrt(x x+y y)。 As I am using data from a file anyway, I am working with the sample data given on the website here .由于我正在使用文件中的数据,因此我正在使用网站上提供的示例数据here

Some research told me to convert the 2D arrays into 1D data in order for lmfit to be able to process them.一些研究告诉我将二维数组转换为一维数据,以便 lmfit 能够处理它们。 My attempts to implement that using the flatten method on my arrays is unsuccessful, giving the same error (TypeError: only size-1 arrays can be converted to Python scalars).我试图在我的数组上使用 flatten 方法来实现它是不成功的,给出了同样的错误(类型错误:只有大小为 1 的数组可以转换为 Python 标量)。 I am not versed enough to fully understand the code in the link.我不够精通,无法完全理解链接中的代码。

I would appreciate any help, esp.我将不胜感激任何帮助,尤其是。 as I prefer to define my own functions to be fitted to the data instead of relying on in-built models.因为我更喜欢定义自己的函数以适应数据,而不是依赖内置模型。

I think you're close, and just mixing up when (or how often) to call meshgrid .我认为你很接近,只是混淆了何时(或多久)调用meshgrid A modified version would be修改后的版本是

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))

That is, define a gaussian2D() function that you can better use and test, and then have a simple objective function that just calls that.也就是说,定义一个可以更好地使用和测试的gaussian2D()函数,然后有一个简单的目标函数来调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM