I have data that follows a very obvious trend but I am failing to find the right function to fit the data. I've tried a logistic as well as an exponential function. However, both functions do not seem to fit the data very well given how clean they look.
Below is the Python code to reproduce the plot - what kind of function would provide a better fit?
import numpy as np
from matplotlib import pyplot as plt
from scipy.optimize import curve_fit
y = np.array([0.00814809, 0.01093976, 0.01294903, 0.01403736,
0.01579931, 0.0171861 , 0.02268682, 0.02785176,
0.03149701, 0.03315134, 0.03389025, 0.03420652,
0.03465968, 0.03477675, 0.03535143])
x = np.array([10, 20, 30, 40, 50, 60, 150, 300, 600,
900, 1200, 1500, 1800, 2100,3000])
def logistic(x, L, x0, k, b):
y = L / (1 + np.exp(-k * (x - x0))) + b
return y
def exponential(x, a, b, c):
return a * x**b + c
plt.scatter(x, y, color="black")
xrange = np.linspace(x.min(), x.max(), 1000)
# fit a logistic function
popt, pcov = curve_fit(logistic, x, y, method="dogbox", maxfev=20000)
plt.plot(xrange, logistic(xrange, popt[0], popt[1], popt[2], popt[3]), label="logistic")
# fit an exponential function
popt, pcov = curve_fit(exponential, x, y, maxfev=10000)
plt.plot(xrange, exponential(xrange, popt[0], popt[1], popt[2]), label="exponential")
plt.legend()
plt.show()