如何计算直方图拟合高斯曲线的半高全宽(FWHM)?
计算拟合高斯曲线的半高全宽(FWHM)
我有一个带有拟合Gaussian曲线的直方图,希望计算该曲线的半高全宽(FWHM)。代码使用的数据来自DataFrame的单列,附上绘图图片。我是Python新手,不知道如何实现。

现有代码
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit def gaussian(n, mean, amplitude, standard_deviation): return amplitude * np.exp( - (n - mean)**2 / (2*standard_deviation ** 2)) n = df_OI_CMC['Area_1_Micrometers'] # 绘制直方图 bin_heights, bin_borders, _ = plt.hist(n, bins = (0,1,5,10,25,50,75,100,125,150,200,250,500,750,1000,2500,5000,7500,10000), label='histogram', edgecolor ='white') bin_widths = np.diff(bin_borders) bin_centers = bin_borders[:-1] + np.diff(bin_borders) / 2 # 生成平滑曲线所需的x值 n_interval_for_fit = np.linspace(bin_borders[0], bin_borders[-1], 10000) # 曲线拟合 popt, _ = curve_fit(gaussian, bin_centers, bin_heights, p0=[-44.0543433, 1480.64682738,68.86641026]) plt.rcParams["figure.figsize"] = [12,12] plt.plot(n_interval_for_fit, gaussian(n_interval_for_fit, *popt), label='fit') plt.ylim([0, 1500]) plt.xlim([-10,1000]) plt.legend() plt.show()
解决方案
方法一:利用高斯参数直接计算(推荐)
高斯曲线的半高全宽(FWHM)和标准差(σ)有固定数学关系:FWHM = 2 * σ * √(2ln2) ≈ 2.3548 * σ
你的popt变量存储了拟合得到的三个参数:[均值, 峰值振幅, 标准差],直接提取标准差代入公式即可。在现有代码末尾添加以下代码:
# 提取拟合得到的标准差 sigma = popt[2] # 计算FWHM fwhm = 2 * sigma * np.sqrt(2 * np.log(2)) print(f"半高全宽(FWHM):{fwhm:.2f}")
方法二:数值方法验证(直观理解)
如果想通过拟合曲线的数值点找到半高处的x值再计算差值,可使用以下代码:
# 获取拟合曲线的峰值 peak_height = gaussian(popt[0], *popt) half_height = peak_height / 2 # 获取拟合曲线的x和y值 fit_x = n_interval_for_fit fit_y = gaussian(fit_x, *popt) # 找到曲线穿过半高值的两个x点 cross_indices = np.where(np.diff(np.sign(fit_y - half_height)))[0] x_left = fit_x[cross_indices[0]] x_right = fit_x[cross_indices[1]] # 计算FWHM fwhm_numeric = x_right - x_left print(f"数值计算的半高全宽:{fwhm_numeric:.2f}")
两种方法结果会非常接近,方法一基于数学推导更准确,方法二则适合直观理解FWHM的含义。
内容的提问来源于stack exchange,提问作者Chirag Patel
相关产品推荐
相关产品推荐

