You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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()

额外的细节优化

  1. 我把参数名从wid改成了gamma,更符合标准洛伦兹的参数命名习惯,避免混淆。
  2. 计算半高值时,直接用拟合得到的amp和offset,而不是依赖max(y_fit)和min(y_fit)——这样更准确,尤其是当拟合曲线的端点值不是基线的时候。
  3. 初始参数猜测调整得更贴近你的数据,能提升拟合的稳定性。

运行这段代码后,你会看到半高横线正好和拟合曲线的半高处对齐,FWHM的计算也符合预期了。

备注:内容来源于stack exchange,提问作者nico.wagner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 07:53:04