Skip to content

Remove matplotlib stretch effect in mo.ui.matplotlib #8883

Merged
koaning merged 2 commits intomainfrom
koaning/matplotlib-figsize-stretch
Mar 27, 2026
Merged

Remove matplotlib stretch effect in mo.ui.matplotlib #8883
koaning merged 2 commits intomainfrom
koaning/matplotlib-figsize-stretch

Conversation

@koaning
Copy link
Copy Markdown
Contributor

@koaning koaning commented Mar 26, 2026

📝 Summary

Before:

Notice that we're stretching a bit here:

CleanShot 2026-03-26 at 17 43 06@2x

Extreme example:

CleanShot 2026-03-26 at 17 49 00@2x

Applying CSS rules in hindsight trips up matplotlib. So I figured removing the hardcoded maxWidth.

After:

CleanShot 2026-03-26 at 17 43 16@2x

This feels better but here is a consequence: the resulting widget may not fit the cell output width anymore if the width is set too high. But that feels like a fair thing for this widget.

Copilot AI review requested due to automatic review settings March 26, 2026 16:50
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 26, 2026

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

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment Mar 26, 2026 9:46pm

Request Review

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

This PR adjusts the frontend matplotlib UI renderer to prevent unintended canvas stretching caused by CSS width constraints, improving visual fidelity of mo.ui.matplotlib outputs.

Changes:

  • Removed a hardcoded canvas.style.maxWidth = "100%" from the matplotlib canvas setup to avoid non-uniform scaling/stretching.

Comment on lines 303 to 304
canvas.style.width = `${this.#state.width}px`;
canvas.style.height = `${this.#state.height}px`;
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

Removing canvas.style.maxWidth = "100%" avoids the non-uniform scaling/stretching, but it also means large figures can no longer be constrained to the output width. In particular, .marimo-cell.published .output-area uses overflow: visible (see frontend/src/css/app/Cell.css), so a wide matplotlib canvas can overflow the viewport/layout in published/read modes.

If you still want width-constrained rendering without stretching, consider keeping a width constraint (e.g. max-width: 100%) while making the height scale proportionally (e.g. don’t set a fixed CSS height; use height: auto / an aspect-ratio-based approach) so the canvas is uniformly scaled when it needs to fit smaller containers.

Suggested change
canvas.style.width = `${this.#state.width}px`;
canvas.style.height = `${this.#state.height}px`;
// Use responsive sizing: constrain width to container and preserve aspect ratio
canvas.style.width = `${this.#state.width}px`;
canvas.style.maxWidth = "100%";
canvas.style.height = "auto";
canvas.style.aspectRatio = `${this.#state.width} / ${this.#state.height}`;

Copilot uses AI. Check for mistakes.
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.

this is probably a good suggestion (but would need some manual testing)

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 26, 2026

Bundle Report

Changes will decrease total bundle size by 805.49kB (-3.15%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
marimo-esm 24.78MB -805.49kB (-3.15%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: marimo-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/cells-*.js 5.42kB 688.33kB 0.79%
assets/index-*.js -12.54kB 606.01kB -2.03%
assets/edit-*.js 86 bytes 371.66kB 0.02%
assets/index-*.css -6 bytes 360.53kB -0.0%
assets/JsonOutput-*.js 47 bytes 306.64kB 0.02%
assets/ai-*.js -18.01kB 248.36kB -6.76%
assets/cell-*.js 5 bytes 182.73kB 0.0%
assets/add-*.js -361 bytes 182.09kB -0.2%
assets/add-*.js 88 bytes 55.42kB 0.16%
assets/agent-*.js 38 bytes 158.26kB 0.02%
assets/layout-*.js 55 bytes 129.43kB 0.04%
assets/PTSans-*.woff2 (New) 113.56kB 113.56kB 100.0% 🚀
assets/PTSans-*.woff2 (New) 116.14kB 116.14kB 100.0% 🚀
assets/Lora-*.woff2 (New) 83.69kB 83.69kB 100.0% 🚀
assets/FiraMono-*.woff2 (New) 67.4kB 67.4kB 100.0% 🚀
assets/FiraMono-*.woff2 (New) 62.68kB 62.68kB 100.0% 🚀
assets/FiraMono-*.woff2 (New) 62.3kB 62.3kB 100.0% 🚀
assets/panels-*.js 342 bytes 48.41kB 0.71%
assets/file-*.js 197 bytes 47.07kB 0.42%
assets/textarea-*.js (New) 38.25kB 38.25kB 100.0% 🚀
assets/context-*.js -280 bytes 33.51kB -0.83%
assets/chat-*.js 29 bytes 32.42kB 0.09%
assets/chat-*.js 6.0kB 14.68kB 69.18% ⚠️
assets/chat-*.js (New) 8.68kB 8.68kB 100.0% 🚀
assets/form-*.js 4 bytes 26.27kB 0.02%
assets/react-*.browser.esm-CHZt2sgR.js (New) 25.64kB 25.64kB 100.0% 🚀
assets/vega-*.browser-W8QXhYr5.js (New) 24.8kB 24.8kB 100.0% 🚀
assets/MarimoErrorOutput-*.js 36 bytes 23.57kB 0.15%
assets/useNotebookActions-*.js -26 bytes 22.98kB -0.11%
assets/home-*.js 43 bytes 21.73kB 0.2%
assets/VisuallyHidden-*.js (New) 18.23kB 18.23kB 100.0% 🚀
assets/markdown-*.js -185 bytes 16.83kB -1.09%
assets/app-*.js 45 bytes 11.43kB 0.4%
assets/CellStatus-*.js 1 bytes 11.37kB 0.01%
assets/switch-*.js -239 bytes 11.24kB -2.08%
assets/useCellActionButton-*.js 5 bytes 9.48kB 0.05%
assets/react-*.esm-BJVxNhcA.js (New) 8.37kB 8.37kB 100.0% 🚀
assets/azure-*.js -38.25kB 6.06kB -86.33%
assets/useBoolean-*.js -4 bytes 5.77kB -0.07%
assets/RenderHTML-*.js -32 bytes 4.95kB -0.64%
assets/floating-*.js -32 bytes 4.79kB -0.66%
assets/emotion-*.esm-C7Gs50yh.js (New) 4.37kB 4.37kB 100.0% 🚀
assets/mermaid-*.core-D2CUV57N.js (New) 2.38kB 2.38kB 100.0% 🚀
assets/state-*.js -487 bytes 744 bytes -39.56%
assets/createReducer-*.js 157 bytes 1.04kB 17.68% ⚠️
assets/maps-*.js -8.36kB 793 bytes -91.34%
assets/sparkles-*.js (New) 494 bytes 494 bytes 100.0% 🚀
assets/fileToBase64-*.js (New) 479 bytes 479 bytes 100.0% 🚀
assets/events-*.js (New) 341 bytes 341 bytes 100.0% 🚀
assets/SelectionIndicator-*.js (New) 324 bytes 324 bytes 100.0% 🚀
assets/message-*.js (New) 241 bytes 241 bytes 100.0% 🚀
assets/kiosk-*.js 2 bytes 200 bytes 1.01%
assets/PTSans-*.ttf (Deleted) -278.61kB 0 bytes -100.0% 🗑️
assets/PTSans-*.ttf (Deleted) -288.34kB 0 bytes -100.0% 🗑️
assets/Lora-*.ttf (Deleted) -212.0kB 0 bytes -100.0% 🗑️
assets/FiraMono-*.ttf (Deleted) -169.06kB 0 bytes -100.0% 🗑️
assets/FiraMono-*.ttf (Deleted) -170.2kB 0 bytes -100.0% 🗑️
assets/FiraMono-*.ttf (Deleted) -201.71kB 0 bytes -100.0% 🗑️
assets/react-*.browser.esm-DDRqG5ui.js (Deleted) -25.64kB 0 bytes -100.0% 🗑️
assets/vega-*.browser-BJ9oKrvH.js (Deleted) -24.8kB 0 bytes -100.0% 🗑️
assets/emotion-*.esm-D7FeWASw.js (Deleted) -4.37kB 0 bytes -100.0% 🗑️
assets/mermaid-*.core-CdM8D_p_.js (Deleted) -2.38kB 0 bytes -100.0% 🗑️
assets/mode-*.js (Deleted) -533 bytes 0 bytes -100.0% 🗑️

Files in assets/index-*.js:

  • ./src/plugins/impl/matplotlib/matplotlib-renderer.ts → Total Size: 16.47kB

When maxWidth: 100% constrained a wide canvas (e.g. figsize=(20,6)),
the fixed CSS height caused non-uniform scaling. Use height: auto with
aspect-ratio so the canvas scales proportionally.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@koaning koaning added the javascript Pull requests that update javascript code label Mar 26, 2026
@Light2Dark Light2Dark added the bug Something isn't working label Mar 27, 2026
@koaning koaning merged commit 2c42af8 into main Mar 27, 2026
31 of 33 checks passed
@koaning koaning deleted the koaning/matplotlib-figsize-stretch branch March 27, 2026 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants