Abacus Core Mixins: Plotting Contribution (plotting_contribution.py)

This module provides the ContributionPlottingMixin class, designed to be inherited by Marketing Mix Model (MMM) classes in Abacus. It offers methods to visualise the contributions of various model components (channels, control variables, seasonality, intercept) over time and their relative shares. These plots help in understanding the model’s decomposition of the target variable.

ContributionPlottingMixin Class

This mixin assumes the inheriting class provides several attributes and methods, including:

  • X: The original input DataFrame used for training.

  • date_column: Name of the date column in X.

  • fit_result: An ArviZ InferenceData object with the model trace.

  • preprocessed_data: A dictionary containing preprocessed data (including preprocessed_data['y']).

  • output_var: The name of the target variable.

  • _format_model_contributions(): A method to extract and format contributions from fit_result.

  • compute_mean_contributions_over_time(): A method (likely from ContributionMixin) to get mean contributions over time.

  • _get_channel_contributions_share_samples(): A method (likely from ContributionMixin) to get contribution share samples.

Methods

plot_components_contributions

def plot_components_contributions(self, **plt_kwargs) -> plt.Figure:

Plots the time series of contributions for different model components, showing the mean and a 90% Highest Density Interval (HDI).

This visualisation displays the estimated contribution of channels (aggregated), control variables (if present), Fourier seasonality components (if present), and the intercept over the time period covered by the training data (self.X). It also overlays the observed target variable (self.preprocessed_data['y']) for comparison.

Parameters:

  • **plt_kwargs: Additional keyword arguments passed to matplotlib.pyplot.subplots.

Returns:

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

Raises:

  • RuntimeError: If the model hasn’t been fitted with X data yet.


plot_grouped_contribution_breakdown_over_time

def plot_grouped_contribution_breakdown_over_time(
    self,
    stack_groups: Optional[Dict[str, List[str]]] = None,
    original_scale: bool = False,
    area_kwargs: Optional[Dict] = None,
    **plt_kwargs: Any,
) -> plt.Figure:

Creates a stacked area chart showing the breakdown of mean contributions over time, allowing for custom grouping of components.

This plot visualises how the total predicted mean target variable is composed of contributions from different sources over time. Components can be grouped (e.g., grouping all online channels) using the stack_groups dictionary.

Parameters:

  • stack_groups (dict[str, list[str]], optional): A dictionary defining how to group contribution components. Keys are the desired group names (e.g., “Baseline”, “Media”), and values are lists of component names (e.g., ["intercept", "trend"], ["TV", "Radio"]) as they appear in the output of compute_mean_contributions_over_time. Components not included in any group are omitted. If None, each component is plotted as a separate area.

  • original_scale (bool, optional): If True, plots contributions in the original target variable’s scale. Defaults to False.

  • area_kwargs (dict, optional): Additional keyword arguments passed to pandas.DataFrame.plot.area.

  • **plt_kwargs: Additional keyword arguments passed to matplotlib.pyplot.subplots.

Returns:

  • plt.Figure: The matplotlib Figure object containing the stacked area plot.

Raises:

  • ValueError: If stack_groups is provided but no valid groups can be formed (e.g., all specified columns are missing from the contribution data).


plot_channel_contribution_share_hdi

def plot_channel_contribution_share_hdi(
    self, hdi_prob: float = 0.90, **plot_kwargs: Any
) -> plt.Figure:

Plots the posterior distribution of the contribution share for each channel using a forest plot.

This visualisation shows the estimated proportion of the total contribution attributable to each channel, along with its uncertainty represented by a Highest Density Interval (HDI). It uses ArviZ’s plot_forest function.

Parameters:

  • hdi_prob (float, optional): The probability mass to include in the HDI (e.g., 0.90 for 90%). Defaults to 0.90.

  • **plot_kwargs: Additional keyword arguments passed to arviz.plot_forest.

Returns:

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


plot_channel_contribution_stats

def plot_channel_contribution_stats(
    self, stat_type: str = "mean", hdi_prob: float = 0.90
) -> plt.Figure:

Creates a bar chart showing a central tendency statistic (mean or median) of the contribution share for each channel, with error bars representing the Highest Density Interval (HDI).

This provides a summary view of each channel’s overall contribution share and its associated uncertainty.

Parameters:

  • stat_type (str, optional): The central tendency statistic to plot on the bars (‘mean’ or ‘median’). Defaults to "mean".

  • hdi_prob (float, optional): The probability mass for the HDI error bars (e.g., 0.90 for 90%). Defaults to 0.90.

Returns:

  • plt.Figure: The matplotlib Figure object containing the bar chart.

Raises:

  • ValueError: If stat_type is not 'mean' or 'median'.

  • KeyError: If the calculated HDI keys based on hdi_prob are not found in the ArviZ summary output (should generally not happen with valid hdi_prob).