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
| Plot | Table |
|---|---|
model.plot.decomposition.contributions_over_time | model.summary.contributions |
model.plot.decomposition.waterfall | model.summary.waterfall |
model.plot.decomposition.channel_share_hdi | model.summary.channel_share_hdi |
model.plot.diagnostics.posterior_predictive | model.summary.posterior_predictive |
model.plot.diagnostics.prior_predictive | model.summary.prior_predictive |
model.plot.diagnostics.residuals_over_time | model.summary.residuals_over_time |
model.plot.transformation.saturation_curves | model.summary.saturation_curves |
model.plot.sensitivity.analysis | model.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.