Export tables and plots

Use model.summary for tabular summaries and model.plot for the grouped plot API. Requirements differ by method: predictive summaries need retained predictive draws, while response curves and incrementality need a suitable fitted model.

Continue the Python quickstart:

import json
from ammm.mmm.summary import dataframe_to_json_records

contributions = model.summary.contributions(hdi_probs=[0.80, 0.94])
records = dataframe_to_json_records(contributions)
json_text = json.dumps(records)
predictive = model.summary.posterior_predictive(hdi_probs=[0.94])
model.plot.decomposition.contributions_over_time(
    include=["channels", "baseline"], original_scale=True, hdi_prob=0.94,
)

dataframe_to_json_records converts supported dates and scalar types for JSON. Pandas is the default; supported methods also accept output_format="polars" when Polars is installed. Methods do not share every argument: for example, dims filtering is available on selected summaries, not on contributions() or posterior_predictive(). Check their signatures before passing plot arguments into a table method.

The default contribution table includes channels. Request other components explicitly. The default interval probability is 0.94; state it in user-facing charts instead of labelling every band simply as uncertainty.

Plot / summary mapping

PlotTable
model.plot.decomposition.contributions_over_timemodel.summary.contributions
model.plot.decomposition.waterfallmodel.summary.waterfall
model.plot.decomposition.channel_share_hdimodel.summary.channel_share_hdi
model.plot.diagnostics.posterior_predictivemodel.summary.posterior_predictive
model.plot.diagnostics.prior_predictivemodel.summary.prior_predictive
model.plot.diagnostics.residuals_over_timemodel.summary.residuals_over_time
model.plot.transformation.saturation_curvesmodel.summary.saturation_curves
model.plot.sensitivity.analysismodel.summary.sensitivity_analysis
optimizer.plot.allocation_roas(samples=...)optimizer.summary.allocation_roas(samples=...)
cv.plot.predictions(cv_results)cv.summary.predictions()

Optimisation summaries consume response samples, not a solver result. The optimisation example shows how to generate those samples. Cross-validation summaries are bound to the validator’s retained results. Interactive model.plot_interactive uses the optional Plotly path.

Preserve dimensions, aggregation periods, currency and estimand in exported metadata. Do not aggregate interval endpoints or describe a conditional model contribution as experimentally established incremental revenue.

Preserve the exported interval contract

Join by the retained coordinate columns and carry units, interval probability and method alongside any JSON/table export. In the summary facade, abs_error_94_lower and abs_error_94_upper are endpoints, not error-bar lengths; separate chain/draw axes select an HDI, while a single sample axis selects equal-tailed quantiles (src/ammm/mmm/summary/factory.py:240). The runner’s curve summaries instead explicitly name 94% equal-tailed intervals as eti_94_lower and eti_94_upper (src/ammm/pipeline/stages/_core_metrics.py:139).

Use the retained output schemas for downstream ingestion. Keep the fitted model and original draw arrays when future users may need different aggregation or uncertainty summaries; marginal interval endpoints alone cannot reconstruct joint posterior uncertainty.

Implementation reference at 7cb7f20: src/ammm/mmm/summary/factory.py:60, src/ammm/mmm/plotting/suite.py:1.