MMMPlotSuite.saturation_scatterplot#

MMMPlotSuite.saturation_scatterplot(original_scale=False, constant_data=None, posterior_data=None, dims=None, colors=None, plot_collection=None, backend=None)[source]#

Plot saturation scatter plot showing channel spend vs contributions.

Creates scatter plots of actual channel spend (X-axis) against channel contributions (Y-axis), one subplot per channel. Useful for understanding the saturation behavior and diminishing returns of each marketing channel.

Parameters:
original_scalebool, default False

Whether to plot in original scale (True) or scaled space (False). If True, requires channel_contribution_original_scale in posterior.

constant_dataxr.Dataset, optional

Dataset containing constant_data group with required variables: - ‘channel_data’: Channel spend data (dims include “date”, “channel”) - ‘channel_scale’: Scaling factor per channel (if original_scale=True) - ‘target_scale’: Target scaling factor (if original_scale=True)

If None, uses self.idata.constant_data. This parameter allows: - Testing with mock constant data - Plotting with alternative scaling factors - Comparing different data scenarios

posterior_dataxr.Dataset, optional

Dataset containing posterior group with channel contribution variables. Must contain ‘channel_contribution’ or ‘channel_contribution_original_scale’. If None, uses self.idata.posterior. This parameter allows: - Testing with mock posterior samples - Plotting external inference results - Comparing different model fits

dimsdict[str, str | int | list], optional

Dimension filters to apply. Examples: - {“geo”: “US”} - Single value - {“geo”: [“US”, “UK”]} - Multiple values

If provided, only the selected slice(s) will be plotted.

colorslist of str, optional

List of colors for each channel, in the same order as the channel dimension. If None, uses the default color cycle. Examples: [“#1f77b4”, “#ff7f0e”, “#2ca02c”]

plot_collectionPlotCollection, optional

Existing PlotCollection to add plots to. If None, creates a new one. This allows building composite visualizations by calling multiple plot methods on the same PlotCollection.

backendstr, optional

Plotting backend to use. Options: “matplotlib”, “plotly”, “bokeh”. If None, uses global config via mmm_plot_config[“plot.backend”]. Default is “matplotlib”.

Returns:
PlotCollection

arviz_plots PlotCollection object containing the plot.

Use .show() to display or .save("filename") to save. Unlike the legacy suite which returned (Figure, Axes), this provides a unified interface across all backends.

Raises:
ValueError

If required data not found in self.idata and not provided explicitly.

ValueError

If ‘channel_data’ not found in constant_data.

ValueError

If original_scale=True but channel_contribution_original_scale not in posterior.

See also

saturation_curves

Add posterior predictive curves to this scatter plot

LegacyMMMPlotSuite.saturation_scatterplot

Legacy matplotlib-only implementation

Notes

Breaking changes from legacy implementation:

  • Returns PlotCollection instead of (Figure, Axes)

  • Lost width_per_col / height_per_row kwargs for figure sizing. For matplotlib, resize after creation: pc.viz["chart"].item().figure.set_size_inches(12, 8)

  • Different grid layout algorithm

Examples

Basic usage (scaled space):

mmm.fit(X, y)
pc = mmm.plot.saturation_scatterplot()
pc.show()

Plot in original scale:

mmm.add_original_scale_contribution_variable(var=["channel_contribution"])
pc = mmm.plot.saturation_scatterplot(original_scale=True)
pc.show()

Filter by dimension:

pc = mmm.plot.saturation_scatterplot(dims={"geo": "US"})
pc.show()

Use different backend:

pc = mmm.plot.saturation_scatterplot(backend="plotly")
pc.show()

Provide explicit data:

custom_constant = xr.Dataset(...)
custom_posterior = xr.Dataset(...)
pc = mmm.plot.saturation_scatterplot(
    constant_data=custom_constant, posterior_data=custom_posterior
)
pc.show()

Use custom colors for each channel:

pc = mmm.plot.saturation_scatterplot(
    colors=["#1f77b4", "#ff7f0e", "#2ca02c"]
)
pc.show()