phenotypic.analysis.LogGrowthModel#

class phenotypic.analysis.LogGrowthModel(on: str, groupby: List[str], time_label: str = 'Metadata_Time', agg_func: Callable | str | list | dict | None = 'mean', lam: float = 1.2, beta: float = 2, Kmax_label: str | None = None, loss: Literal['linear'] = 'linear', verbose: bool = False, n_jobs: int = 1)[source]

Bases: ModelFitter

Logistic-growth model fitter with regularized least-squares objective.

Logistic Kinetics Model:

\[N(t) = \frac{K}{1 + \frac{K - N_0}{N_0} e^{-rt}}\]

\(N_t\): population size at time \(t\)

\(N_0\): initial population size at time \(t\)

\(r\): growth rate

\(K\): carrying capacity (maximum population size)

From this we derive:

\[\mu_{\max} = \frac{K r}{4}\]

\(\mu_{\max}\): maximum specific growth rate

Loss Function:

To solve for the parameters, we use the following loss function with the SciPy linear least-squares solver:

\[J(K, N_0, r) = \frac{1}{n}\sum_{i=1}^{n} \frac{1}{2}\left(f_{K,N_0,r}(t^{(i)}) - N_t^{(i)}\right)^2 + \lambda\left(\left(\frac{dN}{dt}\right)^2 + N_0^2\right) + \beta \frac{\lvert K - \max(N_t) \rvert}{N_t}\]

\(\lambda\): regularization term for growth rate and initial population size

\(\beta\): penalty term for deviations in carrying capacity relative to

the largest measurement

Parameters:
lam

The penalty factor applied to growth rates.

Type:

float

beta

The maximum penalty factor applied to the carrying capacity.

Type:

float

Kmax_label

The column name for the maximum carrying capacity values, if provided.

Type:

str | None

Methods

__init__

Initialize the log-growth fitter.

analyze

Fit the model to every group of data and return the results.

dash

Interactive Plotly version of show().

model_func

Logistic growth model evaluated at t.

results

Return the most recent fit results produced by analyze().

show

Plot model predictions alongside measurements with optional filtering.

__init__(on: str, groupby: List[str], time_label: str = 'Metadata_Time', agg_func: Callable | str | list | dict | None = 'mean', lam: float = 1.2, beta: float = 2, Kmax_label: str | None = None, loss: Literal['linear'] = 'linear', verbose: bool = False, n_jobs: int = 1)[source]

Initialize the log-growth fitter.

Parameters:
  • on (str) – Target column (population-size measurement) to fit.

  • groupby (List[str]) – Columns defining the per-fit grouping structure.

  • time_label (str) – Column name representing time. Defaults to "Metadata_Time".

  • agg_func (Callable | str | list | dict | None) – Aggregation function fed to DataFrame.groupby.agg(). Defaults to "mean".

  • lam (float) – Regularization factor applied to the maximum specific growth rate and initial population size. Defaults to 1.2.

  • beta (float) – Penalty factor applied to the relative difference between K and the largest observed measurement. Defaults to 2.

  • Kmax_label (str | None) – Optional column providing a per-group upper bound on K. When omitted, the observed maximum of on is used.

  • loss (Literal['linear']) – Loss method passed through to scipy.optimize.least_squares(). Defaults to "linear".

  • verbose (bool) – If True, enables the optimizer’s verbose output.

  • n_jobs (int) – Number of parallel workers for per-group fits.

static model_func(t: ndarray | float, r: float, K: float, N0: float)[source]

Logistic growth model evaluated at t.

\[N(t) = K / \left(1 + \frac{K - N_0}{N_0} e^{-rt}\right)\]
Parameters:
  • t (ndarray | float) – Time at which the population is evaluated (scalar or array).

  • r (float) – Growth rate.

  • K (float) – Carrying capacity.

  • N0 (float) – Initial population size at t = 0.

Returns:

Population size at t. Scalar when t is scalar, otherwise an array.

analyze(data: pandas.DataFrame) pandas.DataFrame

Fit the model to every group of data and return the results.

Standard template: copy, float-coerce the time column, aggregate to one sample per timepoint, dispatch per-group fits (serial or parallel via joblib.Parallel), concatenate, and append constant hyperparameter columns from _post_fit_columns.

Parameters:

data (pandas.DataFrame)

Return type:

pandas.DataFrame

dash(tmax: int | float | None = None, criteria: Dict[str, Any | List[Any]] | None = None, figsize=(6, 4), cmap: str | None = 'tab20', legend: bool = True, **kwargs) go.Figure

Interactive Plotly version of show().

Hover tooltips are populated from _hover_fields so subclasses can expose whichever fitted parameters and metrics are most meaningful for their model.

Raises:

ImportError – If plotly is not installed.

Parameters:
  • tmax (int | float | None)

  • criteria (Dict[str, Union[Any, List[Any]]] | None)

  • cmap (str | None)

  • legend (bool)

Return type:

go.Figure

results() pandas.DataFrame

Return the most recent fit results produced by analyze().

Return type:

pandas.DataFrame

show(tmax: int | float | None = None, criteria: Dict[str, Any | List[Any]] | None = None, figsize=(6, 4), cmap: str | None = 'tab20', legend: bool = True, ax: plt.Axes | None = None, **kwargs) Tuple[plt.Figure, plt.Axes]

Plot model predictions alongside measurements with optional filtering.

Parameters:
  • tmax (int | float | None) – Upper bound of the prediction curve. If None, uses the maximum observed time.

  • criteria (Dict[str, Union[Any, List[Any]]] | None) – Column/value filter applied to both fitted results and raw measurements before plotting.

  • figsize – Matplotlib figure size. Used only when ax is None.

  • cmap (str | None) – Matplotlib colormap name, a single color string, or None for matplotlib’s default color cycle.

  • legend (bool) – Whether to render a legend (auto-removed if larger than the axes).

  • ax (plt.Axes | None) – Existing axes to draw into. A new figure is created when omitted.

  • **kwargs – Styling overrides — dpi, facecolor, edgecolor, line_width, marker_size, elinewidth, capsize, legend_loc, legend_fontsize, label.

Returns:

A (Figure, Axes) pair.

Return type:

Tuple[plt.Figure, plt.Axes]