Abacus Core Mixins: Plotting Scenario (plotting_scenario.py)¶
This module provides the ScenarioPlottingMixin class, designed to be inherited by Marketing Mix Model (MMM) classes in Abacus. It offers methods for visualising the results of budget optimisation scenarios and plotting the direct response curves for marketing channels based on the fitted model.
ScenarioPlottingMixin Class
This mixin assumes the inheriting class provides attributes and methods like:
X: The original input DataFrame used for training.channel_columns: List of channel names.compute_channel_contribution_original_scale(): A method (likely fromContributionMixin) that returns channel contributions in the original target scale._estimate_budget_contribution_fit(): A method (likely fromOptimizationMixin) to estimate contribution bounds for a given budget.
Methods
plot_budget_scenarios
def plot_budget_scenarios(
self, *, base_data: Dict, method: str = "sigmoid", **kwargs: Any
) -> plt.Figure:
(Experimental) Plots side-by-side bar charts comparing budget allocation and resulting contribution across different scenarios.
This visualisation helps compare the initial budget/contribution (base_data) with one or more alternative scenarios (scenarios_data passed via kwargs). For the contribution plot, it also shows estimated 90% credible intervals based on fitting a specified saturation curve (method) to the posterior contribution quantiles.
Parameters:
base_data(dict, keyword-only): Required. A dictionary representing the baseline scenario. It must contain two keys:'budget': A dictionary mapping channel names to their budget values in this scenario.'contribution': A dictionary mapping channel names to their corresponding contribution values in this scenario. (Both inner dictionaries can optionally include a ‘total’ key, which is ignored in the plot.)
method(str, optional): The saturation function type ("sigmoid"or"michaelis-menten") used to estimate the contribution bounds (passed to internal_estimate_budget_contribution_fit). Defaults to"sigmoid".**kwargs: Additional keyword arguments. Currently accepts:scenarios_data(List[Dict], optional): A list of dictionaries, each structured likebase_data, representing alternative scenarios to plot alongside the base scenario.
Returns:
plt.Figure: The matplotlib Figure object containing two subplots (one for budget, one for contribution).
Notes:
This method is marked as experimental.
It relies on the
_estimate_budget_contribution_fitmethod (likely inherited fromOptimizationMixin) to calculate the contribution bounds shown in the second plot.Helper function
ut.standardize_scenarios_dict_keysis used internally to ensure input dictionaries have the expected keys.
plot_direct_contribution_curves
def plot_direct_contribution_curves(
self,
show_fit: bool = False,
xlim_max: Optional[Union[int, float]] = None,
method: str = "sigmoid",
channels: Optional[List[str]] = None,
same_axes: bool = False,
) -> plt.Figure:
Plots the relationship between historical channel spend and the resulting mean posterior contribution (direct response curve). Optionally overlays a fitted saturation curve.
This plot shows a scatter of actual spend points versus their corresponding mean contribution from the model fit. The term “direct” signifies that it plots immediate contribution against spend, without explicitly visualising the lagged effects captured by adstock transformations within the model. If show_fit is True, it estimates parameters for a chosen saturation function (method) based on this relationship and plots the resulting curve, along with its inflection point.
Parameters:
show_fit(bool, optional): IfTrue, estimates and plots a saturation curve fit (Sigmoid or Michaelis-Menten) over the scatter plot. Defaults toFalse.xlim_max(int | float, optional): Sets the maximum limit for the x-axis (spend). IfNone(default), the limit is determined by the maximum observed spend for the channel(s) being plotted.method(str, optional): The saturation function type ("sigmoid"or"michaelis-menten") to use ifshow_fitisTrue. Defaults to"sigmoid".channels(List[str], optional): A list of specific channel names to plot. IfNone(default), plots curves for all channels defined inself.channel_columns.same_axes(bool, optional): IfTrue, plots all selected channel curves on a single subplot. IfFalse(default), creates a separate subplot for each channel.
Returns:
plt.Figure: The matplotlib Figure object containing the plot(s).
Raises:
ValueError: If any channel specified inchannelsis not found inself.channel_columns, or ifchannelscontains duplicates. Ifmethodis invalid whenshow_fitisTrue.RuntimeError: If the model hasn’t been fitted withXdata yet.
(Private helper methods _plot_scenario and _plot_response_curve_fit are used internally to handle the plotting logic for individual scenarios/bars and the fitted response curves, respectively.)