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.
Functions
Section titled “Functions”all_contributions_plot
Section titled “all_contributions_plot”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 withcompute_mean_contributions_over_timeandcompute_channel_contribution_original_scalemethods.config(dict): Used to identifydate_colandextra_features_colsfor baseline calculation.results_dir(str): Directory where the plot is saved.
Returns:
None: Saves the plot to the specified directory.
Raises:
AttributeError: Ifmodelis 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
plot_channel_contributions
Section titled “plot_channel_contributions”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 thecompute_channel_contribution_original_scalemethod.config(dict): Used to getdate_col.results_dir(str): Directory where the plot is saved.
Returns:
None: Saves the plot to the specified directory.
Raises:
AttributeError: Ifmodelis missing the required contribution method.ValueError: If the date column is not found in the contribution data.
Output:
weekly_media_contribution.png
plot_roi
Section titled “plot_roi”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 thecompute_channel_contribution_original_scalemethod.data(pd.DataFrame): DataFrame containing historical spend data for the channels specified inconfig.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: Ifmodelis missing the required contribution method.ValueError: If required spend columns are missing fromdata.
Outputs:
media_performance_mean.pngmedia_performance_median.png
plot_roi_distribution
Section titled “plot_roi_distribution”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 thecompute_channel_contribution_original_scalemethod.data(pd.DataFrame): DataFrame containing historical spend data for the channels specified inconfig.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: Ifmodelis missing the required contribution method.ValueError: If required spend columns are missing fromdata.
Output:
performance_distribution.png
plot_waterfall_components_decomposition
Section titled “plot_waterfall_components_decomposition”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 thecompute_mean_contributions_over_timemethod. Defaults toNone, but will raise an error if not provided.original_scale(bool, optional): IfTrue(default), plots contributions in the original target variable’s scale.figsize(tuple, optional): Figure size. Defaults to(14, 7).**kwargs: Additional keyword arguments passed tomatplotlib.pyplot.subplots.
Returns:
plt.Figure: The matplotlib Figure object containing the waterfall plot.
Raises:
ValueError: IfmodelisNoneor has not been fitted.AttributeError: Ifmodelis missing thecompute_mean_contributions_over_timemethod.
(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)