MMMPlotSuite.saturation_scatterplot#

MMMPlotSuite.saturation_scatterplot(original_scale=False, constant_data=None, posterior_data=None, dims=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.

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 **kwargs for matplotlib customization (use backend-specific methods)

  • 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()