ENH: Add screen-proportional mutation_aspect to FancyBboxPatch - #32205
ENH: Add screen-proportional mutation_aspect to FancyBboxPatch#32205Muhtasim-Munif-Fahim wants to merge 1 commit into
Conversation
Add opt-in "screen-proportional" mode to FancyBboxPatch.mutation_aspect that resolves the display-space aspect ratio from the axes at draw time. Rounded corners of Round/other boxstyles then render circular on screen regardless of the axes aspect ratio, without requiring the private ax._get_aspect_ratio() workaround. Closes matplotlib#31175.
|
⏰ This pull request might be automatically closed in two weeks from now. Thank you for your contribution to Matplotlib and for the effort you have put into this PR. This pull request does not yet meet the quality and clarity standards needed for an effective review. Project maintainers have limited time for code reviews, and our goal is to prioritize well-prepared contributions to keep Matplotlib maintainable. Matplotlib maintainers cannot provide one-to-one guidance on this PR. However, if you ask focused, well-researched questions, a community member may be willing to help. 💬 To increase the chance of a productive review:
As the author, you are responsible for driving this PR, which entails doing necessary background research as well as presenting its context and your thought process. If you are a new contributor, or do not know how to fulfill these requirements, we recommend that you familiarize yourself with Matplotlib's development conventions or engage with the community via our Discourse or one of our meetings before submitting code. If you substantially improve this PR within two weeks, leave a comment and a team member may remove the |
PR summary
What problem existed
FancyBboxPatchrequires a numericmutation_aspectto compensate for a non-unit axes aspect ratio. In a plot withaspect="auto"(e.g. a typical bar chart), the rounding ofBoxStyle("Round", ...)is drawn as an ellipse on screen, not a circle. The only way to get isotropic rounding was the private workaroundmutation_aspect=1/ax._get_aspect_ratio(), which is also computed too early (before layout) and therefore stale by draw time.How it was reproduced
What caused it
FancyBboxPatch.get_path()appliesmutation_aspectin data coordinates only. When the axes display scaling differs between x and y (aspect != 1), a data-space circle is drawn as an on-screen ellipse. There was no public way to opt in to resolving the aspect ratio from the axes.What changed
FancyBboxPatch.mutation_aspectnow additionally accepts the string"screen-proportional". At draw time the patch resolves it from the owning axes using public API (get_window_extent, axis transforms), so the box is scaled like the data on screen and the rounding renders circular regardless of the axes aspect ratio.set_mutation_aspectvalidates the new value.Why this approach
The issue proposed an opt-in mode; discussion suggested a name that is more specific than a generic
"auto". The resolution is deferred to draw time so the layout (and thus the display scaling) is final, fixing the stale-value problem of the private-API workaround. All existing numeric behavior is unchanged.How it was tested
python -m pytest lib/matplotlib/tests/test_patches.py -k "mutation_aspect" -v→ 1 passedpython -m pytest lib/matplotlib/tests/test_patches.py→ 73 passed, 11 skipped (pre-existing skips)ValueErroron invalid values.Risks / limitations
"screen-proportional"falls back to an aspect of 1 (documented in the new tests).Related issue
Closes #31175