You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

是否有Python包可基于多组x、y值拟合高斯线型曲线?

嘿,刚学Python两个月就能琢磨这种谱带展宽的拟合问题,已经很牛啦!我懂你说的那种场景——那些无限细的小柱子就像原始的离散信号,你要给每个柱子“糊上”高斯型的展宽,最后叠加成一条平滑的拟合曲线对吧?

之前你看到的单分布拟合是用一个高斯去套一组数据,但你的需求其实是多高斯峰的叠加拟合(或者说离散信号和高斯函数的卷积):把每个细柱当成一个强度为y_i、位置在x_i的尖峰,每个尖峰用高斯函数展宽后加起来,得到最终的平滑曲线。

下面给你一步步来的实操方案,代码都是新手友好的:

第一步:明确数学模型

假设我们有N个细柱,位置是x_points数组,高度是y_points数组。每个细柱对应的展宽高斯峰公式是:

y_i * np.exp( - (x - x_i)**2 / (2 * sigma**2) )

这里的sigma就是谱带展宽的宽度参数(如果所有峰的展宽一致,那它就是唯一需要拟合的参数;如果每个峰展宽不同,就需要多个sigma参数,不过一般谱学里展宽是统一的)。

最终的拟合曲线就是所有这些展宽峰的总和:

def gaussian_broadening(x, sigma, x_points, y_points):
    total = np.zeros_like(x)
    for xi, yi in zip(x_points, y_points):
        peak = yi * np.exp( - (x - xi)**2 / (2 * sigma**2) )
        total += peak
    return total
第二步:编写完整拟合代码

我们用scipy.optimize.curve_fit来拟合参数,用matplotlib画图看效果:

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

# ---------------------- 替换成你自己的原始细柱数据 ----------------------
x_points = np.array([1, 3, 5, 7, 9])  # 细柱的x位置
y_points = np.array([0.2, 0.8, 1.0, 0.7, 0.3])  # 细柱的高度

# 封装用于拟合的展宽函数(把x_points和y_points作为固定参数传入)
def fit_func(x, sigma):
    return gaussian_broadening(x, sigma, x_points, y_points)

# 准备用来绘制平滑曲线的密集x范围
x_fit = np.linspace(min(x_points)-2, max(x_points)+2, 1000)

# 给sigma一个初始猜测值(可以根据你的数据调整,比如先设0.5)
initial_guess = [0.5]

# 执行拟合:如果是真实实验数据,把第二个参数换成你的实验y数据即可
popt, pcov = curve_fit(fit_func, x_fit, fit_func(x_fit, initial_guess[0]))
best_sigma = popt[0]

# ---------------------- 画图展示结果 ----------------------
plt.figure(figsize=(8, 5))
# 画原始细柱
plt.stem(x_points, y_points, basefmt=" ", linefmt="k-", markerfmt="ko", label="原始细柱")
# 画拟合后的展宽曲线
plt.plot(x_fit, fit_func(x_fit, best_sigma), "r-", linewidth=2, label=f"拟合曲线 (sigma={best_sigma:.2f})")
plt.xlabel("X值")
plt.ylabel("强度")
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
一些进阶小提示
  • 如果你的目标是拟合真实实验曲线,只需要把curve_fit里的第二个参数替换成你的实验y数据(注意x_fit要和实验数据的x范围对应)。
  • 如果需要每个峰的展宽不同,可以修改拟合函数,把sigma改成数组参数(比如sigma1, sigma2, ...),但参数变多后需要更合理的初始猜测,避免拟合发散。
  • 如果原始细柱的x位置也有误差,需要把x_points也作为拟合参数,但要注意添加参数约束,防止拟合结果不合理。

放心,这个思路完全没问题,和单分布拟合的核心区别就是把多个高斯峰叠加起来,本质上是离散信号和高斯核的卷积操作——刚开始学就能摸到这个点,已经很到位啦!

内容的提问来源于stack exchange,提问作者ninth_account

火山引擎 最新活动