Skip to content

Sketch: Plot Results (`plot_results.py`)

Utilities for visualising key results from a fitted AMMM model: contribution breakdowns (with/without baseline), ROI/Conversion Efficiency, and component decomposition.

def all_contributions_plot(model, config: dict, results_dir: str) -> None:

Generates a stacked area plot showing the mean contributions of media channels and the combined baseline (intercept + any extra_features_cols) over time.

Parameters:

  • model: A fitted MMM instance with compute_mean_contributions_over_time and compute_channel_contribution_original_scale methods.
  • config (dict): Used to identify date_col and extra_features_cols for baseline calculation.
  • results_dir (str): Directory where the plot is saved.

Returns:

  • None: Saves the plot to the specified directory.

Raises:

  • AttributeError: If model is missing required contribution methods.
  • ValueError: If the date column or required baseline component columns are not found in the contribution data.

Output:

  • weekly_media_and_baseline_contribution.png

def plot_channel_contributions(model, config: dict, results_dir: str) -> None:

Generates a stacked area plot showing the mean contributions of only the media channels over time (no baseline).

Parameters:

  • model: A fitted MMM instance with the compute_channel_contribution_original_scale method.
  • config (dict): Used to get date_col.
  • results_dir (str): Directory where the plot is saved.

Returns:

  • None: Saves the plot to the specified directory.

Raises:

  • AttributeError: If model is missing the required contribution method.
  • ValueError: If the date column is not found in the contribution data.

Output:

  • weekly_media_contribution.png

def plot_roi(model, data: pd.DataFrame, config: dict, results_dir: str) -> None:

Generates two bar plots showing the mean and median Return on Investment (ROI) for each media channel. If config['target_type'] == 'conversion', labels switch to Conversion Efficiency.

ROI is calculated based on the model’s estimated channel contributions and the historical spend data.

Parameters:

  • model: A fitted MMM instance with the compute_channel_contribution_original_scale method.
  • data (pd.DataFrame): DataFrame containing historical spend data for the channels specified in config.
  • config (dict): Configuration dictionary specifying media channel spend columns.
  • results_dir (str): Directory where the plots will be saved.

Returns:

  • None: Saves the plots to the specified directory.

Raises:

  • AttributeError: If model is missing the required contribution method.
  • ValueError: If required spend columns are missing from data.

Outputs:

  • media_performance_mean.png
  • media_performance_median.png

def plot_roi_distribution(model, data: pd.DataFrame, config: dict, results_dir: str) -> None:

Generates histograms with Kernel Density Estimate (KDE) overlays showing the posterior distribution of ROI/Conversion Efficiency for each media channel.

This provides a more detailed view of the uncertainty around the ROI estimates compared to just plotting the mean or median.

Parameters:

  • model: A fitted MMM instance with the compute_channel_contribution_original_scale method.
  • data (pd.DataFrame): DataFrame containing historical spend data for the channels specified in config.
  • config (dict): Configuration dictionary specifying media channel spend columns.
  • results_dir (str): Directory where the plot will be saved.

Returns:

  • None: Saves the plot to the specified directory.

Raises:

  • AttributeError: If model is missing the required contribution method.
  • ValueError: If required spend columns are missing from data.

Output:

  • performance_distribution.png

def plot_waterfall_components_decomposition(
model=None, original_scale: bool = True, figsize: tuple = (14, 7), **kwargs
) -> plt.Figure:

Creates a waterfall chart visualising the decomposition of the total predicted response into contributions from each model component (baseline features, media channels).

The chart shows how each component adds or subtracts from the cumulative total, starting from zero. Bars are coloured based on positive or negative contribution, and annotated with the absolute contribution value and percentage share.

Parameters:

  • model: A fitted MMM instance with the compute_mean_contributions_over_time method. Defaults to None, but will raise an error if not provided.
  • original_scale (bool, optional): If True (default), plots contributions in the original target variable’s scale.
  • figsize (tuple, optional): Figure size. Defaults to (14, 7).
  • **kwargs: Additional keyword arguments passed to matplotlib.pyplot.subplots.

Returns:

  • plt.Figure: The matplotlib Figure object containing the waterfall plot.

Raises:

  • ValueError: If model is None or has not been fitted.
  • AttributeError: If model is missing the compute_mean_contributions_over_time method.

(Private helper function _process_decomposition_components is used internally by plot_waterfall_components_decomposition to aggregate contributions by component and calculate percentages.)

from src.sketch.plot_results import (
all_contributions_plot,
plot_channel_contributions,
plot_roi,
plot_roi_distribution,
plot_waterfall_components_decomposition,
)
all_contributions_plot(mmm, config, results_dir)
plot_channel_contributions(mmm, config, results_dir)
plot_roi(mmm, processed_data, config, results_dir)
plot_roi_distribution(mmm, processed_data, config, results_dir)
fig = plot_waterfall_components_decomposition(mmm, results_dir=results_dir)