首页 文章

指数曲线拟合不适合

提问于
浏览
2

尝试将指数曲线绘制为一组数据时:

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

x = np.array([30,40,50,60])
y = np.array([0.027679854,0.055639098,0.114814815,0.240740741])

def exponenial_func(x, a, b, c):
    return a*np.exp(-b*x)+c

popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, 1e-6, 1))

xx = np.linspace(10,60,1000)
yy = exponenial_func(xx, *popt)

plt.plot(x,y,'o', xx, yy)
pylab.title('Exponential Fit')
ax = plt.gca()
fig = plt.gcf()

plt.xlabel(r'Temperature, C')
plt.ylabel(r'1/Time, $s^-$$^1$')

plt.show()

上面代码的图表:

Exponential curve fitting the data points. Click to enlarge.

但是当我添加数据点 20 (x)和 0.015162344 (y)时:

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

x = np.array([20,30,40,50,60])
y = np.array([0.015162344,0.027679854,0.055639098,0.114814815,0.240740741])

def exponenial_func(x, a, b, c):
    return a*np.exp(-b*x)+c

popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, 1e-6, 1))

xx = np.linspace(20,60,1000)
yy = exponenial_func(xx, *popt)

plt.plot(x,y,'o', xx, yy)
pylab.title('Exponential Fit')
ax = plt.gca()
fig = plt.gcf()

plt.xlabel(r'Temperature, C')
plt.ylabel(r'1/Time, $s^-$$^1$')

plt.show()

上面的代码生成错误

'RuntimeError:找不到最佳参数:函数调用次数已达到maxfev = 800 . '

如果 maxfev 设置为 maxfev = 1300

popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, 1e-6, 1),maxfev=1300)

绘制图表但不能正确拟合曲线 . 从上面的代码更改图表, maxfev = 1300

Exponential curve not fitting the data points. Click to enlarge.

我认为这是因为第20和第30点彼此太靠近了?为了比较,excel绘制如下数据:

Exponential curve fitting the data points. Click to enlarge.

如何正确绘制此曲线?

1 回答

  • 3

    从您的数据中可以看出,您需要一个正指数,因此,当您使用 a*np.exp(-b*x) + c 作为基础模型时, b 需要为负数 . 但是,您从 b 的正初始值开始,这很可能导致问题 .

    如果你改变了

    popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, 1e-6, 1))
    

    popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, -1e-6, 1))
    

    它工作正常,并给出了预期的结果 .

    enter image description here

    或者,您也可以将等式更改为

    return a*np.exp(b*x) + c
    

    并以与您相同的初始值开始 .

    这是整个代码:

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.optimize import curve_fit
    
    
    def exponenial_func(x, a, b, c):
        return a*np.exp(b*x)+c
    
    
    x = np.array([20, 30, 40, 50, 60])
    y = np.array([0.015162344, 0.027679854, 0.055639098, 0.114814815, 0.240740741])
    
    
    popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, 1e-6, 1))
    
    xx = np.linspace(20, 60, 1000)
    yy = exponenial_func(xx, *popt)
    
    # please check whether that is correct
    r2 = 1. - sum((exponenial_func(x, *popt) - y) ** 2) / sum((y - np.mean(y)) ** 2)
    
    plt.plot(x, y, 'o', xx, yy)
    plt.title('Exponential Fit')
    plt.xlabel(r'Temperature, C')
    plt.ylabel(r'1/Time, $s^-$$^1$')
    plt.text(30, 0.15, "equation:\n{} exp({} x) + {}".format(round(popt[0], 4), round(popt[1], 4), round(popt[2], 4)))
    plt.text(30, 0.1, "R^2:\n {}".format(r2))
    
    plt.show()
    

相关问题