使用 curve_fit 对数据进行高斯拟合时出错

Errors using curve_fit for Guassian fit of data

我正在尝试对一些实验数据进行高斯拟合,但我一直 运行 一个接一个地陷入错误。我在网上关注了几个不同的话题,但不是合适(只是一条水平线)就是代码不合适 运行。我正在从另一个线程关注 this code。下面是我的代码。

如果我的代码看起来有点乱,我深表歉意。当我尝试让它工作时,有一些来自其他尝试的信息。因此,“astropy”导入。

import math as m
import matplotlib.pyplot as plt
import numpy as np
from scipy import optimize as opt
import pandas as pd
import statistics as stats
from astropy import modeling


def gaus(x,a,x0,sigma, offset):
    return a*m.exp(-(x-x0)**2/(2*sigma**2)) + offset

# Python program to get average of a list
def Average(lst):
    return sum(lst) / len(lst)

wavelengths = [391.719, 391.984, 392.248, 392.512, 392.777, 393.041, 393.306, 393.57, 393.835, 394.099, 391.719, 391.455, 391.19, 390.926, 390.661, 390.396]
intensities = [511.85, 1105.85, 1631.85, 1119.85, 213.85, 36.85, 10.85, 6.85, 13.85, 7.85, 511.85, 200.85, 80.85, 53.85, 14.85, 24.85]



n=sum(intensities)
mean = sum(wavelengths*intensities)/n
sigma = m.sqrt(sum(intensities*(wavelengths-mean)**2)/n)


def gaus(x,a,x0,sigma):
    return a*m.exp(-(x-x0)**2/(2*sigma**2))

popt,pcov = opt.curve_fit(gaus,wavelengths,intensities,p0=[1,mean,sigma])
print(popt)


plt.scatter(wavelengths, intensities)

plt.title("Helium Spectral Line Peak 1")
plt.xlabel("Wavelength (nm)")
plt.ylabel("Intensity (a.u.)")

plt.show()

感谢好心的用户,我的曲线似乎运行得更合理了。但是,其中一个点似乎又回到了更早的点?截图如下:

您的代码有两个问题。首先是您在 list 上执行向量运算,这会在行 mean = sum(wavelengths*intensities)/n 中给出第一个错误。因此,您应该改用 np.array。第二个是你在 python list 上取 math.exp ,它再次抛出一个错误,因为它需要一个实数,所以你应该在这里使用 np.exp

以下代码解决了您的问题:

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

wavelengths = [391.719, 391.984, 392.248, 392.512, 392.777, 393.041,
               393.306, 393.57, 393.835, 394.099, 391.719, 391.455,
               391.19, 390.926, 390.661, 390.396]
intensities = [511.85, 1105.85, 1631.85, 1119.85, 213.85, 36.85, 10.85, 6.85,
               13.85, 7.85, 511.85, 200.85, 80.85, 53.85, 14.85, 24.85]

wavelengths_new = np.array(wavelengths)
intensities_new = np.array(intensities)

n=sum(intensities)
mean = sum(wavelengths_new*intensities_new)/n
sigma = np.sqrt(sum(intensities_new*(wavelengths_new-mean)**2)/n)

def gaus(x,a,x0,sigma):
    return a*np.exp(-(x-x0)**2/(2*sigma**2))

popt,pcov = opt.curve_fit(gaus,wavelengths_new,intensities_new,p0=[1,mean,sigma])
print(popt)

plt.scatter(wavelengths_new, intensities_new, label="data")
plt.plot(wavelengths_new, gaus(wavelengths_new, *popt), label="fit")
plt.title("Helium Spectral Line Peak 1")
plt.xlabel("Wavelength (nm)")
plt.ylabel("Intensity (a.u.)")
plt.show()