Skip to content

feat: decouple Matplotlib render resolution (DPI) from display size#9144

Merged
Light2Dark merged 2 commits intomarimo-team:mainfrom
daizutabi:feat-matplotlib-dpi
Apr 13, 2026
Merged

feat: decouple Matplotlib render resolution (DPI) from display size#9144
Light2Dark merged 2 commits intomarimo-team:mainfrom
daizutabi:feat-matplotlib-dpi

Conversation

@daizutabi
Copy link
Copy Markdown
Contributor

📝 Summary

Closes #9124

This PR decouples the internal rendering resolution (DPI) of Matplotlib figures from their display size in the marimo notebook.

The fundamental principle is that DPI should control image quality (sharpness), not the physical display size.

Previously, increasing fig.dpi to achieve a sharper image caused the plot to expand linearly, often breaking the notebook layout. This change ensures that figures maintain a consistent display size based on a 100 DPI reference (Matplotlib's default), regardless of the rendering DPI.

Changes

  • Simplified Rendering Logic: Removed the hardcoded "retina" logic (*2 DPI and //2 dimensions).
  • Dynamic Scaling: The rendering now respects the figure's actual DPI setting.
  • Metadata Normalization: Display dimensions (width/height) sent to the frontend are now scaled by dpi / 100. This ensures that a figure with a given figsize occupies the same space in the notebook even if the DPI is increased for higher quality.
  • Enhanced Testing: Added parameterized tests in tests/_output/formatters/test_matplotlib.py to verify that:
    1. The actual PNG pixel count increases with DPI.
    2. The metadata display size remains consistent regardless of DPI.

Verification

The following image demonstrates the fix:

  • Top: fig.dpi = 20 (Low resolution, correct display size)
  • Middle: fig.dpi = 300 (High resolution, same display size)
  • Bottom: savefig.format = "svg" (Consistent behavior with SVG)

As shown, the display size remains stable even when the DPI is changed significantly, allowing users to control image quality without affecting the notebook layout.

📋 Pre-Review Checklist

  • For large changes, or changes that affect the public API: this change was discussed or approved through an issue, on Discord, or the community discussions (Please provide a link if applicable).
  • Any AI generated code has been reviewed line-by-line by the human PR author, who stands by it.
  • Video or media evidence is provided for any visual changes (optional).

✅ Merge Checklist

  • I have read the contributor guidelines.
  • Documentation has been updated where applicable, including docstrings for API changes.
  • Tests have been added for the changes made.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 11, 2026

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

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment Apr 13, 2026 9:46am

Request Review

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 11, 2026

Bundle Report

Bundle size has no change ✅

@akshayka akshayka added the enhancement New feature or request label Apr 11, 2026
Light2Dark
Light2Dark previously approved these changes Apr 13, 2026
Comment thread marimo/_output/mpl.py Outdated
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

Decouples Matplotlib PNG render resolution (DPI) from the notebook display size so users can increase sharpness without expanding plot layout (closes #9124).

Changes:

  • Remove “retina” hardcoding and render PNGs at the figure’s actual DPI.
  • Normalize PNG display metadata (width/height) to a fixed 100-DPI reference so on-screen size stays stable.
  • Update/expand tests to validate DPI affects pixel resolution while display sizing metadata remains constant.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
marimo/_output/mpl.py Render PNG at fig.dpi and scale width/height metadata by dpi/100 to keep display size constant.
tests/_output/formatters/test_matplotlib.py Replace retina-specific assertions with DPI-parameterized checks for pixel resolution and display-size metadata.
frontend/src/components/editor/Output.tsx Update comment to reflect metadata’s new purpose (constant display size across DPI/PPI).

Comment thread marimo/_output/mpl.py
Comment thread marimo/_output/mpl.py Outdated
Comment thread tests/_output/formatters/test_matplotlib.py
Comment thread tests/_output/formatters/test_matplotlib.py Outdated
Comment thread marimo/_output/mpl.py Outdated
@Light2Dark Light2Dark merged commit 8fc591d into marimo-team:main Apr 13, 2026
40 checks passed
@daizutabi daizutabi deleted the feat-matplotlib-dpi branch April 13, 2026 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Decouple Matplotlib render resolution (DPI) from display size

4 participants