使用SciPy curve_fit拟合洛伦兹曲线时的半高全宽(FWHM)计算异常问题
使用SciPy curve_fit拟合洛伦兹曲线时的半高全宽(FWHM)计算异常问题
嘿,我看了你的问题和代码,问题出在你定义的洛伦兹函数不是标准形式,导致你对wid参数和FWHM的对应关系理解错了。咱们一步步来拆解:
核心问题:非标准的洛伦兹函数形式
你写的Lorentzian函数是平方根形式的:
def Lorentzian(f, amp, cen, wid, Offset): return np.sqrt(amp/((f - cen)**2 + wid**2 / 4)) + Offset
这和我们通常用的标准洛伦兹分布不一样。标准洛伦兹的形式是:
def standard_lorentz(f, amp, cen, gamma, offset): return amp / (1 + ((f - cen)/gamma)**2) + offset
在标准形式里,gamma是半高半宽(即峰值到半高处的水平距离),所以FWHM(半高全宽)就是2*gamma,这和你熟悉的高斯分布FWHM计算逻辑是对应的。
而你的平方根形式函数,wid参数和FWHM的关系完全不同——我简单推导了下,这种形式下FWHM≈1.732*wid(也就是wid*np.sqrt(3)),这显然和你预期的2*wid不符,自然绘图时会出现偏差。
修正方案:改用标准洛伦兹函数
我把你的代码修改成用标准洛伦兹拟合,同时修正了FWHM的计算和绘图逻辑,这样结果就会符合预期了:
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 Lorentzian(f, amp, cen, gamma, offset): return amp / (1 + ((f - cen)/gamma)**2) + offset def fit_Lorenz(x, y, init_vals): popt, cov = curve_fit(Lorentzian, x, y, p0=init_vals, maxfev=10000) amp, cen, gamma, offset = popt # 生成拟合曲线 x_fit = np.linspace(min(x), max(x), 1000) y_fit = Lorentzian(x_fit, amp, cen, gamma, offset) return x_fit, y_fit, gamma, cen, amp, offset # 初始参数猜测:[振幅, 中心位置, 半高半宽, 基线] init_vals = [0.8, 2.5, 0.5, 0.0] x_fit, y_fit, gamma, x0, amp, offset = fit_Lorenz(x, y, init_vals) # 计算FWHM:标准洛伦兹下FWHM=2*gamma FWHM = 2 * gamma # 计算半高对应的y值:(峰值 - 基线)/2 + 基线 peak_val = amp + offset half_peak_val = (peak_val - offset)/2 + offset # 绘图 plt.plot(x, y, '.', label='data', color='blue') plt.plot(x_fit, y_fit, '-', label='Lorentzian fit', color='red') # 绘制半高横线 f1 = x0 - FWHM/2 f2 = x0 + FWHM/2 plt.hlines(half_peak_val, f1, f2, linestyle='solid', color='red', label=f'FWHM = {FWHM:.2f}') plt.xlim(0, 5) plt.legend(loc='upper left', fontsize=13) plt.show()
额外的细节优化
- 我把参数名从
wid改成了gamma,更符合标准洛伦兹的参数命名习惯,避免混淆。 - 计算半高值时,直接用拟合得到的
amp和offset,而不是依赖max(y_fit)和min(y_fit)——这样更准确,尤其是当拟合曲线的端点值不是基线的时候。 - 初始参数猜测调整得更贴近你的数据,能提升拟合的稳定性。
运行这段代码后,你会看到半高横线正好和拟合曲线的半高处对齐,FWHM的计算也符合预期了。
备注:内容来源于stack exchange,提问作者nico.wagner
相关产品推荐
相关产品推荐

