fix: Plotly jump on rerender in filling layouts#236
Merged
Conversation
cpsievert
commented
Apr 13, 2026
cpsievert
commented
Apr 13, 2026
There was a problem hiding this comment.
Pull request overview
This PR addresses a UI “jump” seen with Plotly FigureWidget outputs in filling layouts by keeping Plotly outputs hidden until Plotly’s initial render/resize cycle completes, ensuring the first visible paint is already at the correct size.
Changes:
- Add
widget_pkgto the server render payload so the client can reliably detect Plotly widgets. - Add Plotly-specific client logic to wait for
plotly_afterplot, force a directPlotly.Plots.resize(...), then reveal the output (guarded by a per-render token). - Add Playwright regression coverage for first-visible Plotly paint stability and a resize-failure visibility fallback, plus a unit test for the new payload field.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
shinywidgets/_render_widget_base.py |
Includes widget_pkg in the widget render payload for client-side routing. |
js/src/output.ts |
Implements Plotly-specific hide/settle/reveal flow with render-token guarding; keeps non-Plotly behavior unchanged. |
js/src/plotly.ts |
Adds helper utilities to find Plotly graph divs and await plotly_afterplot/resize before reveal. |
shinywidgets/static/output.js |
Built artifact reflecting the updated output binding and new Plotly helper module. |
tests/unit/test_render_widget_base_lifecycle.py |
Adds a unit test asserting widget_pkg is included in DOMWidget render payloads. |
tests/playwright/example_plotly_afterplot_stable/* |
Adds a self-contained Playwright regression ensuring the first visible Plotly afterplot is already correctly sized. |
tests/playwright/plotly_rerender_cleanup/test_plotly_rerender_cleanup.py |
Adds coverage ensuring a Plotly resize error does not leave the output hidden. |
CHANGELOG.md |
Documents the Plotly jump fix and added coverage. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #208.
Plotly
FigureWidgetcan perform an initial draw at its internal fallback height before resizing to the actual container height. In filling layouts, that allows the output to become visible at the wrong height and then visibly jump to the final size.This PR fixes that by delaying reveal for Plotly outputs until Plotly's own resize cycle has completed.
What changed
widget_pkgfrom the server render payload so the client does not need to infer whether a widget is Plotly.js/src/plotly.ts.Plotly.Plots.resize(...)directly on the graph div,plotly_afterplot,Reviewer context
This is intentionally narrow. It is not a general refactor of widget readiness logic.
The bug is tied to Plotly's render sequence:
plotlywidget-after-render,The fix is to avoid revealing the widget between steps 1 and 4.
Test coverage
examples/plotly/app.pyor extra Python packages.widget_pkgrender payload field.Verification
cd js && yarn builduv run pytest tests/unit/test_render_widget_base_lifecycle.py -quv run pytest -c tests/playwright/playwright-pytest.ini tests/playwright/example_plotly_afterplot_stable/test_example_plotly_afterplot_stable.py tests/playwright/plotly_rerender_cleanup/test_plotly_rerender_cleanup.py tests/playwright/bokeh_rerender_cleanup/test_bokeh_rerender_cleanup.py -quv run ruff check tests/playwright/example_plotly_afterplot_stable