我正在尝试为我的数据拟合高斯(这已经是粗糙的高斯).我已经接受了这里的建议并尝试了curve_fit,leastsq但我认为我错过了一些更基本的东西(因为我不知道如何使用命令).这是我到目前为止的脚本
import pylab as plb
import matplotlib.pyplot as plt
# Read in data -- first 2 rows are header in this example.
data = plb.loadtxt('part 2.csv', skiprows=2, delimiter=',')
x = data[:,2]
y = data[:,3]
mean = sum(x*y)
sigma = sum(y*(x - mean)**2)
def gauss_function(x, a, x0, sigma):
return a*np.exp(-(x-x0)**2/(2*sigma**2))
popt, pcov = curve_fit(gauss_function, x, y, p0 = [1, mean, sigma])
plt.plot(x, gauss_function(x, *popt), label='fit')
# plot data
plt.plot(x, y,'b')
# Add some axis labels
plt.legend()
plt.title('Fig. 3 - Fit for Time Constant')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.show()
Run Code Online (Sandbox Code Playgroud)
我从中得到的是高斯形状,这是我的原始数据和直线水平线.
此外,我想使用点绘制我的图形,而不是连接它们.任何输入都表示赞赏!
Dev*_*per 23
这是更正后的代码:
import pylab as plb
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy import asarray as ar,exp
x = ar(range(10))
y = ar([0,1,2,3,4,5,4,3,2,1])
n = len(x) #the number of data
mean = sum(x*y)/n #note this correction
sigma = sum(y*(x-mean)**2)/n #note this correction
def gaus(x,a,x0,sigma):
return a*exp(-(x-x0)**2/(2*sigma**2))
popt,pcov = curve_fit(gaus,x,y,p0=[1,mean,sigma])
plt.plot(x,y,'b+:',label='data')
plt.plot(x,gaus(x,*popt),'ro:',label='fit')
plt.legend()
plt.title('Fig. 3 - Fit for Time Constant')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.show()
Run Code Online (Sandbox Code Playgroud)
结果:

str*_*ter 12
您需要良好的起始值,以使curve_fit函数收敛于"良好"值.我真的不能说为什么你的拟合没有收敛(即使你的意思的定义很奇怪 - 请看下面)但我会给你一个适用于非标准化高斯函数的策略.
估计的参数应该接近最终值(使用加权算术平均值 - 除以所有值的总和):
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import numpy as np
x = np.arange(10)
y = np.array([0, 1, 2, 3, 4, 5, 4, 3, 2, 1])
# weighted arithmetic mean (corrected - check the section below)
mean = sum(x * y) / sum(y)
sigma = np.sqrt(sum(y * (x - mean)**2) / sum(y))
def Gauss(x, a, x0, sigma):
return a * np.exp(-(x - x0)**2 / (2 * sigma**2))
popt,pcov = curve_fit(Gauss, x, y, p0=[max(y), mean, sigma])
plt.plot(x, y, 'b+:', label='data')
plt.plot(x, Gauss(x, *popt), 'r-', label='fit')
plt.legend()
plt.title('Fig. 3 - Fit for Time Constant')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.show()
Run Code Online (Sandbox Code Playgroud)
我个人更喜欢使用numpy.
由于评论者不喜欢我对#Developer代码的编辑,我将解释我建议改进代码的情况.开发人员的平均值不符合平均值的正常定义之一.
您的定义返回:
>>> sum(x * y)
125
Run Code Online (Sandbox Code Playgroud)
开发人员的定义返回:
>>> sum(x * y) / len(x)
12.5 #for Python 3.x
Run Code Online (Sandbox Code Playgroud)
加权算术平均值:
>>> sum(x * y) / sum(y)
5.0
Run Code Online (Sandbox Code Playgroud)
同样,您可以比较标准偏差(sigma)的定义.与得到的拟合的数字比较:
在Python 2.x中,您还应该使用新的分区,以避免遇到奇怪的结果或明确转换分区前的数字:
from __future__ import division
Run Code Online (Sandbox Code Playgroud)
或者例如
sum(x * y) * 1. / sum(y)
Run Code Online (Sandbox Code Playgroud)