为一组x,y数据拟合高斯曲线
首先,这是我被布置的作业,所以我只需要一些提示,而且我只能使用以下库:NumPy、SciPy和MatPlotLib。
我们得到了一个文本文件,里面包含了共振实验的x和y数据,我们需要对数据进行高斯拟合和洛伦兹拟合。目前我正在做高斯拟合,尝试按照之前一个问题中提供的代码作为我自己代码的基础。(Python的高斯拟合)
from numpy import *
from matplotlib import *
import matplotlib.pyplot as plt
import pylab
from scipy.optimize import curve_fit
energy, intensity = numpy.loadtxt('resonance_data.txt', unpack=True)
n = size(energy)
mean = 30.7
sigma = 10
intensity0 = 45
def gaus(energy, intensity0, energy0, sigma):
return intensity0 * exp(-(energy - energy0)**2 / (sigma**2))
popt, pcov = curve_fit(gaus, energy, intensity, p0=[45, mean, sigma])
plt.plot(energy, intensity, 'o')
plt.xlabel('Energy/eV')
plt.ylabel('Intensity')
plt.title('Plot of Intensity against Energy')
plt.plot(energy, gaus(energy, *popt))
plt.show()
这段代码返回了以下图表
如果我保持均值和标准差的表达式,就像在链接中那样,曲线拟合结果是一条水平线,所以我猜问题出在曲线拟合没有收敛或者其他什么原因。
1 个回答
1
看起来你的数据分布偏向左边,为什么选择高斯分布呢?而不是玻尔兹曼分布、对数正态分布或者其他的呢?
这些分布大部分已经在 scipy.stats
里实现了。比如可以查看 scipy.stats.cauchy
来了解洛伦兹分布,查看 scipy.stats.normal
来了解高斯分布。这里有个例子:
import scipy.stats as ss
A=ss.norm.rvs(0, 5, size=(100)) #Generate a random variable of 100 elements, with expected mean=0, std=5
ss.norm.fit_loc_scale(A) #fit both the mean and std
(-0.13053732553697531, 5.163322485150271) #your number will vary.
而且我觉得你不需要 intensity0
这个参数,因为它的值其实就是 1/sigma/sqrt(2*pi)
,因为密度函数的总和必须等于1。