python中使用scipy curve_fit进行洛伦兹拟合的半参数全宽

ttp71kqs  于 2023-08-05  发布在  Python
关注(0)|答案(1)|浏览(152)

我想确定我的数据的洛伦兹拟合的半参数全宽(FWHM),我使用scipy的curve_fit函数。当我使用高斯拟合时,FWHM由2.35482*sigma计算。一般来说,在这种情况下,洛伦兹(参见MWE)的FWHM必须确定为2*sigma,但这并不适合将其显示在图中(图显示为1*sigma)。我做错了什么?

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

x = np.linspace(0,5,10)
y = [0.0,0.05,0.16,0.3,0.6,0.8,0.6,0.3,0.16,0.0]

def fit_Lorenz(x, y, f0, init):
    
    def Lorentzian(f, amp, cen, wid, Offset):
        return np.sqrt(amp/((f - cen)**2 + wid**2 / 4 )) + Offset
     
    init_vals = init
    popt, cov = curve_fit(Lorentzian, x, y ,p0=init_vals, maxfev= 10000)
    
    Amp = popt[0]
    cen = np.abs(popt[1])
    wid = np.abs(popt[2])
    Offset = popt[3]
    
    x_fit = np.linspace(min(x), max(x), 1000)   
    y_fit = np.zeros(len(x_fit))
    
    for i in range(len(x_fit)):
        y_fit[i] = Lorentzian(x_fit[i],Amp,cen,wid,Offset)
    
    return x_fit, y_fit, wid, cen, Amp

init_vals= [1,2,1,1]
x_fit, y_fit, sigma, x0, Amp = fit_Lorenz(x,y, max(y), init_vals)

FWHM = sigma
FWHM_val = (max(y_fit) - min(y_fit))/2 + min(y_fit)

plt.plot(x, y, '.', label='data', color='blue')
plt.plot(x_fit, y_fit, '-', label='Lorentzian fit', color='red')
plt.xlim(0,5)
f1 = x0-FWHM/2
f2 = x0+FWHM/2
plt.hlines(FWHM_val,f1,f2,linestyle='solid', color='red')
plt.legend(loc='upper left', fontsize=13)

字符串


的数据

cmssoen2

cmssoen21#

我做了一个快速搜索,发现了一个不同的方程洛伦兹。使用this site,我将您的方程更改为它们的形式,计算半高为0.5*Amp/sigma(您称值为sigma,但站点使用gamma),同时考虑偏移,并绘制结果。

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

x = np.linspace(0, 5, 10)
y = [0.0, 0.05, 0.16, 0.3, 0.6, 0.8, 0.6, 0.3, 0.16, 0.0]

def fit_Lorenz(x, y, f0, init):

    def Lorentzian(f, amp, cen, wid, Offset):
        return amp*wid/((f-cen)**2 + wid**2) + Offset

    init_vals = init
    popt, cov = curve_fit(Lorentzian, x, y, p0=init_vals, maxfev=10000)

    Amp = popt[0]
    cen = np.abs(popt[1])
    wid = np.abs(popt[2])
    Offset = popt[3]

    x_fit = np.linspace(min(x), max(x), 1000)
    y_fit = np.zeros(len(x_fit))

    for i in range(len(x_fit)):
        y_fit[i] = Lorentzian(x_fit[i], Amp, cen, wid, Offset)

    return x_fit, y_fit, wid, cen, Amp, Offset

init_vals = [1, 2, 1, 1]
x_fit, y_fit, sigma, x0, Amp, Offset = fit_Lorenz(x, y, max(y), init_vals)

# peak is Amp/sigma high, so half the height is half that
half_height = 0.5*Amp/sigma + Offset
FWHM = 2*sigma
f1 = x0-FWHM/2
f2 = x0+FWHM/2

plt.plot(x, y, '.', label='data', color='blue')
plt.plot(x_fit, y_fit, '-', label='Lorentzian fit', color='red')
plt.xlim(0, 5)
plt.hlines(half_height, f1, f2, linestyle='solid', color='green')
plt.legend(loc='upper left', fontsize=13)

字符串


的数据

相关问题