El ajuste exponencial de la curva no se ajustará

Al intentar trazar una curva exponencial a un conjunto de datos:

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

Gráfico para el código anterior:

Curva exponencial ajustada a los puntos de datos. Click para agrandar.

Sin embargo, cuando agrego el punto de datos 20 (x) y 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() 

El código anterior genera el error.

‘RuntimeError: Parámetros óptimos no encontrados: el número de llamadas a la función ha alcanzado maxfev = 800.’

Si maxfev se establece en maxfev = 1300

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

El gráfico está trazado pero no se ajusta a la curva correctamente. Gráfico del cambio de código anterior, maxfev = 1300 :

Curva exponencial que no se ajusta a los puntos de datos. Click para agrandar.

Creo que esto se debe a que los puntos 20 y 30 son demasiado cercanos entre sí. Para comparación, Excel traza los datos de esta manera:

Curva exponencial ajustada a los puntos de datos. Click para agrandar.

¿Cómo puedo trazar esta curva correctamente?

A partir de sus datos, es obvio que necesita un exponente positivo, por lo tanto, b debe ser negativo al usar a*np.exp(-b*x) + c como modelo subyacente. Sin embargo, comienza con un valor inicial positivo para b que probablemente cause los problemas.

Si cambias

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

a

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

Funciona bien y da el resultado esperado.

introduzca la descripción de la imagen aquí

Alternativamente, también podría cambiar su ecuación a

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

y comienza con los mismos valores iniciales que tenías.

Aquí está el código completo:

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