简体   繁体   English

将高斯曲线拟合到python中的数据

[英]Fitting Gaussian curve to data in python

I'm trying to fit and plot a Gaussian curve to some given data. 我正在尝试拟合并绘制一些给定数据的高斯曲线。 This is what I have so far: 这是我到目前为止:

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

# Generate data
mu, sigma = 0, 0.1
y, xe  = np.histogram(np.random.normal(mu, sigma, 1000))
x = .5 * (xe[:-1] + xe[1:])

def gauss (x, y):
    p = [x0, y0, sigma]
    return p[0] * np.exp(-(x-p[1])**2 / (2 * p[2]**2))

p0 = [1., 1., 1.]

fit = curve_fit(gauss, x, y, p0=p0)
plt.plot(gauss(x, y))
plt.show()

When I run the code I get this error: 当我运行代码时,我收到此错误:

TypeError: gauss() takes exactly 2 arguments (4 given)

I don't understand where I have given my function 4 arguments. 我不明白我在哪里给了我的函数4个参数。 I'm also not convinced I'm using the curve function correctly, but I'm not sure exactly what I'm doing wrong. 我也不相信我正在使用曲线功能,但我不确定我做错了什么。 Any help would be appreciated. 任何帮助,将不胜感激。

Edit 编辑

Here's the Traceback: 这是追溯:

Traceback (most recent call last):
  File "F:\Numerical methods\rw893  final assignment.py", line 21, in <module>
    fitE, fitI = curve_fit(gauss, x, y, p0=p0)
  File "F:\Portable Python 2.7.5.1\App\lib\site-packages\scipy\optimize\minpack.py", line 515, in curve_fit
    res = leastsq(func, p0, args=args, full_output=1, **kw)
  File "F:\Portable Python 2.7.5.1\App\lib\site-packages\scipy\optimize\minpack.py", line 354, in leastsq
    shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
  File "F:\Portable Python 2.7.5.1\App\lib\site-packages\scipy\optimize\minpack.py", line 17, in _check_func
    res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
  File "F:\Portable Python 2.7.5.1\App\lib\site-packages\scipy\optimize\minpack.py", line 427, in _general_function
    return function(xdata, *params) - ydata
TypeError: gauss() takes exactly 2 arguments (4 given)

Check the first scipy documentation docs.scipy.org/doc/scipy-0.13.0/reference/generated/scipy.optimize.curve_fit.html : 检查第一个scipy文档docs.scipy.org/doc/scipy-0.13.0/reference/generated/scipy.optimize.curve_fit.html

scipy.optimize.curve_fit scipy.optimize.curve_fit

scipy.optimize.curve_fit(f, xdata, ydata, p0=None, sigma=None, **kw) scipy.optimize.curve_fit(f,xdata,ydata,p0 = None,sigma = None,** kw)

 Use non-linear least squares to fit a function, f, to data. Assumes ydata = f(xdata, *params) + eps 

Explaining the idea 解释这个想法

The function to be fitted should take only scalars ( not : *p0 ). 要安装的功能应该只采用标量不是*p0 )。 I want to remind you that you hand over the initialization parameters x0 , y0 , sigma to the function gauss during the call of curve_fit . 我想提醒您,在调用curve_fit期间,您将初始化参数x0y0sigma curve_fit给函数gauss You call the initialization p0 = [x0, y0, sigma] . 你调用初始化p0 = [x0, y0, sigma]

The function gauss returns the value y = y0 * np.exp(-((x - x0) / sigma)**2) . 函数gauss返回值y = y0 * np.exp(-((x - x0) / sigma)**2) Therefore the input values need to be x , x0 , y0 , sigma . 因此,输入值必须是xx0y0sigma The first parameter x is the data you know together with the result of the function y . 第一个参数x是您知道的数据以及函数y的结果。 The later three parameters will be fitted - you hand over them as initialization parameters. 后面的三个参数将被拟合 - 您将它们作为初始化参数交给它们。

Working example 工作实例

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

# Create data:
x0, sigma = 0, 0.1
y, xe  = np.histogram(np.random.normal(x0, sigma, 1000))
x = .5 * (xe[:-1] + xe[1:])

# Function to be fitted
def gauss(x, x0, y0, sigma):
    p = [x0, y0, sigma]
    return p[1]* np.exp(-((x-p[0])/p[2])**2)

# Initialization parameters
p0 = [1., 1., 1.]
# Fit the data with the function
fit, tmp = curve_fit(gauss, x, y, p0=p0)

# Plot the results
plt.title('Fit parameters:\n x0=%.2e y0=%.2e sigma=%.2e' % (fit[0], fit[1], fit[2]))
# Data
plt.plot(x, y, 'r--')
# Fitted function
x_fine = np.linspace(xe[0], xe[-1], 100)
plt.plot(x_fine, gauss(x_fine, fit[0], fit[1], fit[2]), 'b-')
plt.savefig('Gaussian_fit.png')
plt.show()

拟合的结果显示在图中。

Probably your callback is called in curve_fit with a different number of parameters. 可能你的回调是在curve_fit中用不同数量的参数调用的。 Have a look at the documentation where it says: 看一下它所说的文档

The model function, f(x, ...). 模型函数f(x,...)。 It must take the independent variable as the first argument and the parameters to fit as separate remaining arguments. 它必须将自变量作为第一个参数,并将参数作为单独的剩余参数。

To make sure this works out you might want to take *args after the first argument and have a look at what you get. 为了确保这一点,你可能想在第一个参数之后取*args并查看你得到的结果。

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

def func(x, a, b, c, d, x0):
    return a*np.exp(-(x-x0)**2/(2*d**2)) + c

x = np.linspace(0,4,50)
y = func(x, 2.5, 1.3, 0.5, 1.0, 2.0)
yn = y + 0.2*np.random.normal(size=len(x))

p = [1,1,1,1,1]

popt, pcov = curve_fit(func, x, yn, p0=p)


plt.plot(x,func(x,popt[0],popt[1],popt[2],popt[3],popt[4]))
plt.plot(x,yn,'r+')
plt.show()

This should help. 这应该有所帮助。 This can also be extended to a 3d Gaussian, then the input array 'x' should be a k-dimensional array for the (x,y) values and 'yn' should be the z-values. 这也可以扩展到3d高斯,然后输入数组'x'应该是(x,y)值的k维数组,'yn'应该是z值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM