Skip to content

fix: Plotly jump on rerender in filling layouts#236

Merged
cpsievert merged 19 commits intomainfrom
codex/output-ready-investigation
Apr 13, 2026
Merged

fix: Plotly jump on rerender in filling layouts#236
cpsievert merged 19 commits intomainfrom
codex/output-ready-investigation

Conversation

@cpsievert
Copy link
Copy Markdown
Collaborator

@cpsievert cpsievert commented Apr 13, 2026

Closes #208.

Plotly FigureWidget can 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

  • Keep the existing widget implementation flow for non-Plotly widgets.
  • Pass widget_pkg from the server render payload so the client does not need to infer whether a widget is Plotly.
  • Add a small Plotly-specific helper module in js/src/plotly.ts.
  • For Plotly outputs:
    • keep the output hidden,
    • wait for Plotly's initial render/afterplot cycle,
    • call Plotly.Plots.resize(...) directly on the graph div,
    • wait for the post-resize plotly_afterplot,
    • then reveal the output.

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:

  1. initial draw at fallback height,
  2. plotlywidget-after-render,
  3. resize,
  4. repaint at the real container height.

The fix is to avoid revealing the widget between steps 1 and 4.

Test coverage

  • Add a self-contained Playwright regression that reproduces the Plotly reveal/resize issue without depending on examples/plotly/app.py or extra Python packages.
  • Keep the existing Plotly rerender cleanup coverage.
  • Add a unit test covering the new widget_pkg render payload field.

Verification

  • cd js && yarn build
  • uv run pytest tests/unit/test_render_widget_base_lifecycle.py -q
  • uv 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 -q
  • uv run ruff check tests/playwright/example_plotly_afterplot_stable

@cpsievert cpsievert changed the title Avoid showing Plotly FigureWidget before resize settles Settle Plotly FigureWidget before revealing output Apr 13, 2026
@cpsievert cpsievert changed the title Settle Plotly FigureWidget before revealing output Fix Plotly FigureWidget jump on rerender in filling layouts Apr 13, 2026
Comment thread js/src/output.ts Outdated
Comment thread js/src/output.ts

This comment was marked as resolved.

@cpsievert cpsievert changed the title Fix Plotly FigureWidget jump on rerender in filling layouts fix: Plotly jump on rerender in filling layouts Apr 13, 2026

This comment was marked as resolved.

This comment was marked as resolved.

This comment was marked as resolved.

This comment was marked as resolved.

@cpsievert cpsievert requested a review from Copilot April 13, 2026 22:55
@cpsievert cpsievert merged commit 83932fb into main Apr 13, 2026
7 checks passed
@cpsievert cpsievert deleted the codex/output-ready-investigation branch April 13, 2026 22:57
Copy link
Copy Markdown

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

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_pkg to the server render payload so the client can reliably detect Plotly widgets.
  • Add Plotly-specific client logic to wait for plotly_afterplot, force a direct Plotly.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.

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.

[Bug]: plotly plots jump (becomes smaller then larger) when re-rendered

2 participants