【问题标题】:Exponential curve fit will not fit指数曲线拟合不拟合
【发布时间】:2019-03-27 17:52:09
【问题描述】:

当试图为一组数据绘制指数曲线时:

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()

以上代码的图表:

但是,当我添加数据点 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:

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

如何正确绘制这条曲线?

【问题讨论】:

  • 更改初始猜测的最后一个值 p0=(1,1e-6,0) 适合我的数据
  • 谢谢 DavidG,这对我也有效。

标签: python scipy curve-fitting


【解决方案1】:

根据您的数据,很明显您需要一个正指数,因此,b 需要为负,因为您使用 a*np.exp(-b*x) + c 作为基础模型。但是,您从 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))

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

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

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{:.4f} exp({:.4f} x) + {:.4f}".format(*popt))
plt.text(30, 0.1, "R^2:\n {}".format(r2))

plt.show()

【讨论】:

  • 谢谢,请问如何将直线方程和 R^2 值相加?
  • @gravitypulling:你想在哪里添加它?在情节本身?
  • 我想将它添加到情节本身
  • @gravitypulling:请查看更新后的答案。还请检查 r2 计算是否符合您的想法;如果不是,请更改它。由于您相对较新:如果它解决了您的问题,请也接受答案(单击答案旁边的复选标记,然后变为绿色)。
  • 谢谢,非常正确的信息解释
猜你喜欢
  • 2016-02-13
  • 2015-03-22
  • 1970-01-01
  • 2015-06-20
  • 2014-09-08
  • 2023-04-09
  • 2020-05-05
  • 1970-01-01
  • 2013-05-22
相关资源
最近更新 更多