I'm trying to fit a simple logistic growth model to dummy data using Python's Scipy
package. The code is shown below, along with the output that I get. The correct output is shown below it. I'm not quite sure what's going wrong here.
import scipy.optimize as optim
from scipy.integrate import odeint
import numpy as np
import pandas as pd
N0 = 0.37
parsic = [.25, 12.9]
df_yeast = pd.DataFrame({'cd': [9.6, 18.3, 29., 47.2, 71.1, 119.1, 174.6, 257.3, 350.7, 441., 513.3, 559.7, 594.8, 629.4, 640.8, 651.1, 655.9, 659.6], 'td': np.arange(18)})
def logistic_de(t, N, r, K):
return r*N*(1 - N/K)
def logistic_solution(t, r, K):
return odeint(logistic_de, N0, t, (r, K), tfirst=True).ravel()
params, _ = optim.curve_fit(logistic_solution, df_yeast['td'], df_yeast['cd'], p0=parsic)
N1 = odeint(logistic_de, N0, np.linspace(0, 20, 10000), (params[0], params[1]), tfirst=True)
plt.plot(np.linspace(0, 20, 10000), N1)
plt.scatter(df_yeast['td'], df_yeast['cd'])
plt.ylabel('num yeast')
plt.xlabel('time')
This is the edit they're hinting at, maybe this'll help you understand:
# include N0 as an argument
def logistic_solution(t, N0, r, K):
return odeint(logistic_de, N0, t, (r, K), tfirst=True).ravel()
# N0 thus included as parameter to fit
params, _ = optim.curve_fit(logistic_solution, df_yeast['td'], df_yeast['cd'],
p0=[N0, *parsic])
# N1 integral factors in the fitted N0 parameter
# (not the same as the global variable named N0,
# should change global variable to something like N0_guess)
N1 = odeint(logistic_de, params[0], np.linspace(0, 20, 10000),
tuple(params[1:]), tfirst=True)