Skip to content

feat(plotly): add reactive box plot selection support#9010

Merged
Light2Dark merged 24 commits intomarimo-team:mainfrom
axsseldz:feat/reactive-plotly-box
Apr 12, 2026
Merged

feat(plotly): add reactive box plot selection support#9010
Light2Dark merged 24 commits intomarimo-team:mainfrom
axsseldz:feat/reactive-plotly-box

Conversation

@axsseldz
Copy link
Copy Markdown
Contributor

@axsseldz axsseldz commented Apr 3, 2026

## 📝 Summary

Makes go.Box (and px.box) plots fully selection-reactive in mo.ui.plotly. Users can now drag a box/lasso, click a box body, or click individual jittered points to get row-level data in Python.

🔍 Description of Changes

  • Frontend: added type === "box" to shouldHandleClickSelection so box click events are forwarded to Python.
  • Python: added _append_box_points_to_selection which handles three cases: range/lasso with individual points already sent by Plotly, range/lasso without points (extract from figure data), and click events (expand pointNumbers into individual rows). Supports vertical/horizontal orientation and categorical axes.
  • Tests: 12 Python tests + 1 frontend test covering all selection modes.
  • Example: examples/third_party/plotly/box_chart.py — three chart variants (single-trace, grouped, horizontal) each with a live stats summary and mo.ui.table.

Selection

box1

Click Selection

box2

📋 Pre-Review Checklist

  • For large changes, or changes that affect the public API: this change was discussed or approved through an issue, on Discord, or the community discussions (Please provide a link if applicable).
  • Any AI generated code has been reviewed line-by-line by the human PR author, who stands by it.
  • Video or media evidence is provided for any visual changes (optional).

✅ Merge Checklist

  • I have read the contributor guidelines.
  • Documentation has been updated where applicable, including docstrings for API changes.
  • Tests have been added for the changes made.

@mscolnick @nojaf

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment Apr 11, 2026 2:52am

Request Review

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Apr 3, 2026
@axsseldz axsseldz marked this pull request as ready for review April 3, 2026 13:51
@axsseldz axsseldz requested a review from akshayka as a code owner April 3, 2026 13:51
Copilot AI review requested due to automatic review settings April 3, 2026 13:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds selection reactivity for Plotly box plots in mo.ui.plotly, enabling click and drag selections to produce row-level selection payloads in Python.

Changes:

  • Frontend: forward click events for type === "box" traces so selections reach Python.
  • Backend: expand box click pointNumbers into per-sample rows and add range-based extraction for box traces when Plotly doesn’t send individual points.
  • Tests/docs/examples: add box selection tests, update plotting docs, and add a new box selection example.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
marimo/_plugins/ui/_impl/plotly.py Implements box selection expansion and range-based extraction, and wires it into _convert_value.
tests/_plugins/ui/_impl/test_plotly.py Adds extensive Python tests for box selection behavior (click/range/orientation/multi-trace).
frontend/src/plugins/impl/plotly/selection.ts Treats box trace clicks as selection events to forward to Python.
frontend/src/plugins/impl/plotly/__tests__/selection.test.ts Adds a unit test asserting box clicks are accepted.
frontend/src/plugins/impl/plotly/__tests__/PlotlyPlugin.test.tsx Adds an integration-style test that a box click triggers setValue.
examples/third_party/plotly/box_chart.py New example showcasing reactive box selection patterns.
docs/api/plotting.md Documents that box plots now support reactive selections.

Comment thread marimo/_plugins/ui/_impl/plotly.py Outdated
Comment thread marimo/_plugins/ui/_impl/plotly.py Outdated
Comment thread tests/_plugins/ui/_impl/test_plotly.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Comment thread marimo/_plugins/ui/_impl/plotly.py Outdated
Comment thread marimo/_plugins/ui/_impl/plotly.py Outdated
Comment thread marimo/_plugins/ui/_impl/plotly.py
Comment thread examples/third_party/plotly/box_chart.py
@Light2Dark
Copy link
Copy Markdown
Collaborator

happy to merge the violin plot PR once ready, thanks for working on these

axsseldz and others added 4 commits April 7, 2026 23:10
Resolves conflicts between waterfall (merged to main) and strip/box/violin
additions. Both feature sets are now present: waterfall handlers are
inserted before the box/violin handlers in _convert_value, and all
function definitions are included.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolves conflicts between waterfall (merged to main) and funnel additions.
Both feature sets included: waterfall handlers inserted before funnel handlers
in _convert_value, all function definitions and tests from both branches kept.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@axsseldz
Copy link
Copy Markdown
Contributor Author

axsseldz commented Apr 8, 2026

happy to merge the violin plot PR once ready, thanks for working on these

hey @Light2Dark, just updated the violin plot PR (#9011), should be fine now, also, i'll take care of the merge conflicts in this PR once the other gets merged 🫡

axsseldz and others added 3 commits April 8, 2026 01:31
- Fix unsafe np.asarray(val_data, dtype=np.float64) call: wrap in
  try/except and fall back to element-wise extraction when val_data
  contains None or non-numeric entries (comment 1)
- Fix off-by-one in overlap check: use >= val_min (inclusive lower
  bound) in both the numpy fast path and the pure-Python fallback,
  consistent with bar selection behavior (comment 2)
- Correct docstring: click path strips empty placeholders and re-syncs
  indices; it does not deduplicate (comment 3)
- Update docs to mention funnelarea support explicitly (comment 4)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
axsseldz and others added 11 commits April 8, 2026 01:51
Merges violin plot and area chart support from main while preserving
box/strip plot additions. `hasAreaTrace` added to TS, both
`_append_box_points_to_selection` and `_append_violin_points_to_selection`
coexist in Python with their full helper function hierarchies.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Syncs strip chart support into box branch so both can merge into main
independently without conflicts. Adds strip chart example, strip test
section, and updated supported-charts documentation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Light2Dark
Copy link
Copy Markdown
Collaborator

Light2Dark commented Apr 8, 2026

happy to merge the violin plot PR once ready, thanks for working on these

hey @Light2Dark, just updated the violin plot PR (#9011), should be fine now, also, i'll take care of the merge conflicts in this PR once the other gets merged 🫡

Thanks! For merge path, probably this one and then the strip chart one #9012?

They look to share a lot of logic, maybe with different names and some differences. Also left a comment on #9011, which can be addressed in a separate PR.

@axsseldz
Copy link
Copy Markdown
Contributor Author

axsseldz commented Apr 8, 2026

Collaborator

yeap, i was checking this morning the three of them, i believe now all there should be in sync, this PR and (#9044), (#9012), or at least minimal differences, also, yeah i'll def take a look at your comment on (#9011) thanks!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Comment thread marimo/_plugins/ui/_impl/plotly.py
Comment thread marimo/_plugins/ui/_impl/plotly.py Outdated
Comment thread marimo/_plugins/ui/_impl/plotly.py Outdated
Comment thread marimo/_plugins/ui/_impl/plotly.py
Comment thread examples/third_party/plotly/funnel_chart.py
@Light2Dark
Copy link
Copy Markdown
Collaborator

@axsseldz happy to get this merged in once copilot comments are resolved

@axsseldz
Copy link
Copy Markdown
Contributor Author

@axsseldz happy to get this merged in once copilot comments are resolved

thanks!, ill make the changes later today(:

@axsseldz
Copy link
Copy Markdown
Contributor Author

@Light2Dark the comments should be resolved, also, i'm planning to address these type of behaviors [ i spotted some similar behaviors in other plotly charts] (#9011 (review)) in another PR, after this PR, (#9044), and (#9012) get merged, so i can sync all plotly charts ive worked on and behave properly, pls lmk if the other two PRs need any changes so i can address them(:

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 11, 2026

Bundle Report

Changes will increase total bundle size by 12.8kB (0.05%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
marimo-esm 24.84MB 12.8kB (0.05%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: marimo-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/cells-*.js 384 bytes 703.39kB 0.05%
assets/index-*.js 683 bytes 602.15kB 0.11%
assets/index-*.css 290 bytes 362.29kB 0.08%
assets/dist-*.js -32 bytes 137 bytes -18.93%
assets/dist-*.js -40 bytes 137 bytes -22.6%
assets/dist-*.js 122 bytes 259 bytes 89.05% ⚠️
assets/dist-*.js -19 bytes 164 bytes -10.38%
assets/dist-*.js 79 bytes 183 bytes 75.96% ⚠️
assets/dist-*.js 233 bytes 335 bytes 228.43% ⚠️
assets/dist-*.js 218 bytes 387 bytes 128.99% ⚠️
assets/dist-*.js -227 bytes 176 bytes -56.33%
assets/dist-*.js -7 bytes 169 bytes -3.98%
assets/dist-*.js -56 bytes 104 bytes -35.0%
assets/dist-*.js 220 bytes 403 bytes 120.22% ⚠️
assets/dist-*.js -2 bytes 102 bytes -1.92%
assets/dist-*.js 13 bytes 177 bytes 7.93% ⚠️
assets/dist-*.js -283 bytes 104 bytes -73.13%
assets/dist-*.js 32 bytes 169 bytes 23.36% ⚠️
assets/dist-*.js -99 bytes 160 bytes -38.22%
assets/dist-*.js -152 bytes 183 bytes -45.37%
assets/JsonOutput-*.js -1 bytes 336.29kB -0.0%
assets/edit-*.js -42.36kB 329.61kB -11.39%
assets/layout-*.js 56.26kB 185.91kB 43.39% ⚠️
assets/slides-*.js 360 bytes 116.37kB 0.31%
assets/panels-*.js -3.15kB 45.36kB -6.5%
assets/state-*.js 192 bytes 24.05kB 0.8%
assets/RenderHTML-*.js 60 bytes 5.01kB 1.21%
assets/button-*.js 93 bytes 3.93kB 2.43%

Files in assets/index-*.js:

  • ./src/plugins/impl/plotly/selection.ts → Total Size: 7.39kB

@Light2Dark Light2Dark merged commit b73a370 into marimo-team:main Apr 12, 2026
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants