Skip to content

Redraw a figure in JupyterLab when its output is updated - #5865

Merged
KoolADE85 merged 5 commits into
plotly:mainfrom
AllenDowney:mimerenderer-update-display
Nov 6, 2026
Merged

KoolADE85 merged 5 commits into
plotly:mainfrom
AllenDowney:mimerenderer-update-display

Conversation

@AllenDowney

Copy link
Copy Markdown
Contributor

Link to issue

Closes #3053, which was closed as stale in 2024; it still happens with jupyterlab-plotly 7.1.0.

Description of change

When a kernel updates a displayed figure with update_display_data (for example IPython's DisplayHandle.update), JupyterLab calls renderModel again on the existing renderer, and renderModel returned early because it already had a graph, so the figure never changed. Now it redraws (with Plotly.react, through createGraph) when the figure in the new model differs from the one it drew. It still returns early when the figure is the same, which is what happens when createGraph stores the PNG of the figure in the model.

Demo

The example from #3053, in JupyterLab 4 with plotly 7.1.0:

from IPython.display import display
out = {'application/vnd.plotly.v1+json': {'data': [{'x': ['giraffes', 'orangutans', 'monkeys'], 'y': [20, 14, 23], 'type': 'bar'}], 'layout': {}}}
h = display(out, raw=True, display_id=True)
import time
for y0 in [10, 5, 1]:
    out['application/vnd.plotly.v1+json']['data'][0]['y'][0] = y0
    h.update(out, raw=True)
    time.sleep(0.5)

Before: the first bar stays at 20. After: it goes to 10, 5, then 1.

This also fixes animations in the Octave kernel xeus-octave (its issue #2), which draws figures with this renderer and updates them on each drawnow; checked in JupyterLite with an 8-frame loop: before, the plot stays on the first frame; after, it steps through all eight.

Testing strategy

I didn't find tests for the mime renderer to extend, so I tested by hand: the two examples above, before and after, in JupyterLab 4 and in JupyterLite 0.8, checking the plot's data in the page; and a plot with no updates still renders.

Guidelines

AllenDowney and others added 2 commits November 2, 2026 16:37
The mime renderer's renderModel returned early whenever it already had
a graph, so update_display_data (for example IPython's
DisplayHandle.update) never changed the figure. Redraw when the figure
in the new model differs from the one drawn; keep returning early when
it's the same, as when createGraph stores the PNG in the model.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@AllenDowney

Copy link
Copy Markdown
Contributor Author

@KoolADE85 Thanks for the quick action!

@KoolADE85 KoolADE85 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the submission @AllenDowney ! It works well on my end. The only thing missing is committed build artifacts, which I will just do now and push to your branch here.

Cheers!

@KoolADE85
KoolADE85 merged commit 3c1aeba into plotly:main Nov 6, 2026
32 checks passed
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.

Jupyter Plotly JSON mime renderer does not update

2 participants