如何用python

时间:2018-04-12 01:36:32

标签: python numpy matplotlib scipy curve-fitting

我试图在scipy中使用curve_fit函数在半月形图中拟合一些样本数据。我的最佳拟合曲线看起来没问题我正在遵循的代码,但我遇到了2 sigma曲线的问题,我希望同时显示最佳拟合曲线和灰色曲线。我的代码如下所示:

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

M = np.array([-2, -1, 0, 1, 2, 3,4])
Y_z = np.array([0.05, 0.2, 3, 8, 50, 344, 2400 ])

# curve fit linear function
def line(x, a, b):
    return a*x+b

popt, pcov = curve_fit(line, M, np.log10(Y_z))     # change here

# plotting
plt.semilogy(M , Y_z, 'o')
plt.semilogy(M, 10**line(M, popt[0], popt[1]), ':', label = 'curve-fit')

# plot 1 sigma -error
y1 = 10**(line(M, popt[0] + pcov[0,0]**0.5, popt[1] - pcov[1,1]**0.5))
y2 = 10**(line(M, popt[0] - pcov[0,0]**0.5, popt[1] + pcov[1,1]**0.5))
plt.semilogy(M, y1, ':')
plt.semilogy(M, y2, ':')
plt.fill_between(M, y1, y2, facecolor="gray", alpha=0.15)

plt.xlabel(r"$\log X$")
plt.ylabel('Y')   
plt.legend()
plt.show()

对于方差曲线enter image description here

,我们非常感谢您的帮助

1 个答案:

答案 0 :(得分:2)

原则上,线性拟合根本不需要非线性最小二乘曲线拟合:线性回归应该有效。

那就是说,为了解决你的问题,你可能会发现lmfit(http://lmfit.github.io/lmfit-py/)在这里很有用。它具有稍微更高级别和更多Pythonic曲线拟合方法,并添加了许多功能。其中之一是计算所选西格玛值的结果的不确定性。

为了适应lmfit,它看起来像

import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize as optimization

import lmfit

M = np.array([-2, -1, 0, 1, 2, 3,4])
Y_z = np.array([0.05, 0.2, 3, 8, 50, 344, 2400 ])

# curve fit linear function
def line(x, a, b):
    return a*x+b

# set up model and create parameters from model function
# note that function argument names are used for parameters
model = lmfit.Model(line)
params = model.make_params(a=1, b=0)

result = model.fit(np.log10(Y_z), params, x=M)

print(result.fit_report())

将打印出一份关于合适的报告:

[[Model]]
    Model(line)
[[Fit Statistics]]
    # fitting method   = leastsq
    # function evals   = 8
    # data points      = 7
    # variables        = 2
    chi-square         = 0.10468256
    reduced chi-square = 0.02093651
    Akaike info crit   = -25.4191304
    Bayesian info crit = -25.5273101
[[Variables]]
    a:  0.77630819 +/- 0.02734470 (3.52%) (init = 1)
    b:  0.22311337 +/- 0.06114460 (27.41%) (init = 0)
[[Correlations]] (unreported correlations are < 0.100)
    C(a, b) = -0.447

您可以在最佳拟合结果中计算2-sigma不确定性

# calculate 2-sigma uncertainty in result
del2 = result.eval_uncertainty(sigma=2, x=M)

然后使用它和拟合结果绘制结果(从表单稍微修改):

plt.plot(M, np.log10(Y_z), 'o', label='data')
plt.plot(M, result.best_fit, ':',  label = 'curve-fit')  
plt.fill_between(M, result.best_fit-del2, result.best_fit+del2, facecolor="grey", alpha=0.15)

plt.xlabel(r"$\log X$")
plt.ylabel('Y')
plt.legend()
plt.show()

应该产生类似

的情节

enter image description here

希望有所帮助。