fix: refresh mpl interactive plots when browser tab becomes visible#8287
Merged
dmadisetti merged 1 commit intomainfrom Feb 12, 2026
Merged
fix: refresh mpl interactive plots when browser tab becomes visible#8287dmadisetti merged 1 commit intomainfrom
dmadisetti merged 1 commit intomainfrom
Conversation
Closes #2092 ## Problem When `mo.mpl.interactive()` plots are rendered while the browser tab is in the background (minimized or switched to another tab), the plots appear blank. This is because browsers throttle or skip canvas rendering in background tabs, so the image data sent by matplotlib's WebAgg server over WebSocket is effectively lost. ## Fix Added a `visibilitychange` event listener in the matplotlib iframe's HTML template. When the browser tab becomes visible again, it sends a `refresh` message to the matplotlib WebAgg server. This triggers a full figure redraw (`_force_full = True` + `draw_idle()`) that sends fresh canvas data back to the browser, ensuring the plot is always up-to-date when the user returns.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a bug where mo.mpl.interactive() plots appear blank when rendered while the browser tab is in the background. The fix adds a visibilitychange event listener that refreshes the plot when the tab becomes visible again.
Changes:
- Added JavaScript event listener in the matplotlib iframe template to detect when the browser tab becomes visible
- Added test coverage to verify the visibilitychange listener is present in the generated HTML
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| marimo/_plugins/stateless/mpl/_mpl.py | Added visibilitychange event listener to refresh matplotlib figures when browser tab becomes visible |
| tests/_plugins/stateless/test_mpl.py | Added regression test to verify the visibilitychange listener is present in the template |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
dmadisetti
approved these changes
Feb 12, 2026
Collaborator
dmadisetti
left a comment
There was a problem hiding this comment.
Failing test unrelated
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 #2092
Closes #4435
Problem
When
mo.mpl.interactive()plots are rendered while the browser tab is in thebackground (minimized or switched to another tab), the plots appear blank.
This is because browsers throttle or skip canvas rendering in background tabs,
so the image data sent by matplotlib's WebAgg server over WebSocket is
effectively lost.
Fix
Added a
visibilitychangeevent listener in the matplotlib iframe's HTMLtemplate. When the browser tab becomes visible again, it sends a
refreshmessage to the matplotlib WebAgg server. This triggers a full figure redraw
(
_force_full = True+draw_idle()) that sends fresh canvas data back tothe browser, ensuring the plot is always up-to-date when the user returns.