Skip to content

Show posterior uncertainty in plot_model_cartoon as graded bands; declutter samples mode - #1130

Closed
AlexanderFengler wants to merge 9 commits into
1122-improve-ppc-plotsfrom
1122-improve-model-cartoon
Closed

Show posterior uncertainty in plot_model_cartoon as graded bands; declutter samples mode#1130
AlexanderFengler wants to merge 9 commits into
1122-improve-ppc-plotsfrom
1122-improve-model-cartoon

Conversation

@AlexanderFengler

Copy link
Copy Markdown
Member

Closes #1124. Stacked on #1123 (reuses its helpers and uncertainty= vocabulary); retarget to main when #1123 merges.

What changed

  • uncertainty="band" | "samples" | "both" | None on plot_model_cartoon, default "band" — same vocabulary as plot_predictive. None reproduces the old mean-only look (test-pinned).
  • RT histograms: per-draw defective-density matrices on shared bin edges → graded pointwise quantile bands + mean, replacing N overlaid ax.hist calls (~0.98 accumulated opacity at defaults). Makes the previously dead bins/step/colors/linestyles/linewidths parameters real; adds hist_height.
  • Geometry: boundary fan-chart ribbons, dashed drift-quantile cone (truncated at first absorption — no survivor-biased tails), graded NDT axvspans + rug replacing the per-draw axvline smear, starting-point whisker. Geometry stays neutral black (color_model); predictions/data keep the predictive palette.
  • samples mode: auto per-curve alpha clip(4/n_draws, .02, .25) instead of fixed 0.05.
  • 2-choice renderer: per-choice bands in trajectory colors, boundary ribbon, NDT spans; removes a latent NameError on data-only calls.

  • Deprecation shim: plot_predictive_mean/plot_predictive_samplesFutureWarning; both spellings together error.
  • Legends harvested from labeled artists (1D + FacetGrid), replacing hard-coded proxies.
  • New fixture-driven tutorial: docs/tutorials/cartoon_gallery.ipynb (sibling of ppc_gallery.ipynb, executed, 9 figures). Changelog entry included.
  • Tests: 30 new fast artist-structure tests (tests/unit/plotting/test_model_cartoon.py); slow suite converted to the new vocabulary + one shim-coverage case.

Scope notes

Commands run

  • uv run pytest tests/unit/plotting/ → 74/74
  • targeted slow cases (prior-predictive band, boolean shim) → pass
  • uv run mypy src/hssm (CI's gate) → clean; uv run ruff check . → clean except a pre-existing unused import in ppc_gallery.ipynb on the base branch
  • Visual acceptance: all four modes + facets rendered from the cavanagh fixture and eyeballed

🤖 Generated with Claude Code

Both the predictive and model-cartoon plot families need the bandable
step-curve geometry and the graded-band opacity ladder. Move _curve_xy out
of predictive.py and extract the inline alpha linspace into _band_alphas,
so the cartoon redesign consumes the same helpers instead of copying them.

No behavior change: 44/44 fast plotting tests pass unchanged.
…#1124)

plot_func_model gains the #1123 uncertainty vocabulary. RT histograms are
now drawn from precomputed per-draw defective-density matrices (shared bin
edges, _curve_xy geometry) instead of N overlaid ax.hist calls, enabling
graded pointwise quantile bands, auto-alpha spaghetti, a real step/bins
story, and a hist_height normalizer. Geometry uncertainty renders as
boundary fan ribbons, a dashed drift cone (decision-time aligned,
NaN-masked past absorption, truncated at <50% survival), graded ndt
axvspans + rug replacing the per-draw axvline smear, and a start-point
whisker. uncertainty=None preserves the legacy rendering for GUI-heritage
callers; add_histograms_to_twin_axes is deleted; legend is assembled from
labeled artists instead of hardcoded proxies.
Public signature adopts the #1123 vocabulary: uncertainty='band' default,
hdi, alpha_mean/alpha_uncertainty, hist_height, legend, live bins/step/
colors/linestyles/linewidths (previously documented but silently dead).
The deprecated plot_predictive_mean/plot_predictive_samples booleans map
through a FutureWarning shim; passing both spellings errors.

Geometry gets its own color_model (neutral black) so the figure encodes
structure=neutral, predictions=predicted color, data=observed color. The
drift cone truncates at the first absorption across draws — the >=50%
survival rule showed selection-biased tails. Histogram baselines anchor to
the same no-noise sim that draws the reference boundary, so histograms sit
exactly on the drawn bound. Hard-coded proxy legends replaced by harvested,
deduped, _legend_order-ranked legends on both the 1D and FacetGrid paths.
…#1124)

plot_func_model_n adopts the same machinery: per-choice defective-density
matrices (jointly integrating to 1 across choices) rendered as graded bands
in the per-choice trajectory colors from the single shared baseline, plus a
boundary ribbon and ndt spans/rug on the geometry. uncertainty=None keeps
the legacy per-draw overlays. The rewrite removes the latent NameError when
only observed data was passed (bottom now always defined), anchors the
baseline to the reference no-noise boundary like the 2-choice renderer, and
gives the legacy legend's dashed ndt proxy its missing label.
…ng (#1124)

tests/unit/plotting/test_model_cartoon.py: 30 unmarked tests in the #1123
style — pure math pins (defective-density mass identities incl. -999
exclusion and non-uniform edges, per-choice masses, geometry matrices,
band-alpha ladder, shim mappings) plus artist-census assertions per mode
(collection/line counts, alpha values, zorders, legend labels, live
bins/step/hist_height/styles, seeded reproducibility, legacy-census parity
for uncertainty=None, and the n-choice data-only NameError regression).

The slow structural suite converts to the uncertainty vocabulary, keeps one
boolean case covering the shim end-to-end (FutureWarning + ValueError), and
adds a facet-level PolyCollection check. tests/test_model_cartoon_colors.py
is kept, deviating from the original plan: _add_trajectories and its colors
support survived the redesign, so the test still covers live code.
docs/tutorials/cartoon_gallery.ipynb mirrors ppc_gallery.ipynb: fixture-
driven (runs in seconds, no sampling), one option per section — default
graded bands, samples, both, mean-only, custom hdi, hist_height, styling,
facets, the deprecated-boolean shim, and the regression-model trial-
provenance caveat. Executed end-to-end: 9 figures, zero errors. Wired into
mkdocs nav + execute_ignore beside its sibling.

Also fixes the plotting.ipynb cell that passed long-removed kwargs
(plot_pp_mean/plot_pp_samples/alpha_pp, silently swallowed since their
removal) and adds the changelog entry. Full re-execution of the cartoon
sections in plotting.ipynb / scientific_workflow_hssm.ipynb is deferred to
merge time to avoid double churn against the #1123 notebook regeneration.
end-of-file/whitespace auto-fixes in the two gallery notebooks, and the
legend dedup rewritten as an explicit loop — mypy rejects the
set.add()-in-boolean-context idiom. CI's gate (mypy src/hssm) is clean;
the 14 remaining local-hook findings are pre-existing in tests/addm and
tests/rl on the base branch.
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3ab3493f-38b7-4de3-b56b-b8a1afc3d06e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…#1124)

Three fixes from first review of the gallery:

1. Warnings: attach_trialwise_params_to_df now sorts the (chain, draw,
   obs_n) MultiIndex once before its per-draw assignments — previously every
   assignment emitted a pandas lexsort PerformanceWarning (1236 per gallery
   run). The remaining numba object-mode notices trace to the fixture
   shipping no predictive groups (#1080); filtered in the gallery setup cell
   with a comment naming the cause.

2. Legend: the combined histogram + geometry legend is too tall to float
   inside the axes; it now sits outside on the right (center-left anchor at
   x=1.02).

3. Geometry coherence: all four no-noise geometry sims (reference and
   per-draw, both renderers) now use the trial-0 row as a single-row theta.
   Previously the reference simulated an unseeded RANDOM trial while the
   per-draw curves inherited the simulator's last-trial boundary scratch
   buffer — for hierarchical models the ribbons and the drawn mean bound sat
   at visibly different levels. One consistent trial also makes every
   metadata element (boundary/trajectory/ndt/z) describe the same trial and
   the reference deterministic. #1125 narrows to the reduction convention
   (trial-mean, obs=), seeded trajectories, and max_t.

4. NDT display: the graded axvspan envelope now renders in every uncertainty
   mode, replacing the bottom-edge rug in samples mode — an envelope hugging
   the dashed reference line is the natural reading; the rug read as a
   stray artifact.

Gallery re-executed: zero warnings, 9 figures, no errors. 74/74 fast tests.
#1124)

- _render_drift_band now draws fill_between quantile bands per HDI
  interval (widest first, _band_alphas ladder), matching the boundary
  ribbons and histogram bands; dashed linestyle is reserved for the
  non-decision-time reference line
- band census test distinguishes boundary ribbons (zorder 1010) from
  drift bands (zorder 1012) and asserts no dashed non-vertical lines
- gallery, changelog, and docstring wording updated; changelog note on
  trial provenance refreshed to the trial-0 convention
@AlexanderFengler

Copy link
Copy Markdown
Member Author

Superseded by #1133: this PR was auto-closed when the 1122-improve-ppc-plots base branch was deleted after the #1123 squash-merge, and GitHub cannot reopen a closed PR whose base is gone (nor after the branch was rebased onto main). #1133 carries the identical commits, rebased past the squash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant