Skip to content

Conversation

@cvanelteren
Copy link
Collaborator

Closes #297,#270

This PR introduces UltraLayout, a novel constraint-based layout system using kiwisolver that enables aesthetically pleasing positioning for non-orthogonal subplot arrangements (e.g., [[1, 1, 2, 2], [0, 3, 3, 0]] where subplot 3 should be centered between subplots 1 and 2). The existing gridspec works great for orthogonal layouts but fails to produce visually balanced results when subplots span multiple rows/columns in non-aligned ways. UltraLayout automatically detects non-orthogonal layouts, applies constraint satisfaction to compute optimal positions that respect spacing, ratios, and aesthetic balance (e.g., centering subplots between neighbors), and gracefully falls back to the standard grid layout if kiwisolver is not installed or for orthogonal arrangements. This enhancement is fully backward compatible, adds zero overhead for standard grid layouts, includes comprehensive test coverage in ultraplot/tests/test_ultralayout.py, and provides a foundation for more sophisticated layout constraints in the future.

Make subplot param probes backend-safe: GridSpec.get_subplot_params now returns a read-only snapshot of our margins/spaces and locally_modified_subplot_params returns False. This keeps Positron/other backends from erroring while preserving our restriction on mutating Matplotlib’s subplot params.

@cvanelteren cvanelteren requested a review from beckermr January 16, 2026 22:22
@cvanelteren cvanelteren added this to the v2.0 milestone Jan 16, 2026
@cvanelteren
Copy link
Collaborator Author

Made a local error with the history so this is a restored version of the old PR.

@codecov
Copy link

codecov bot commented Jan 17, 2026

Codecov Report

❌ Patch coverage is 70.45658% with 330 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
ultraplot/axes/base.py 45.90% 218 Missing and 20 partials ⚠️
ultraplot/gridspec.py 65.66% 36 Missing and 21 partials ⚠️
ultraplot/ultralayout.py 86.71% 21 Missing and 13 partials ⚠️
ultraplot/figure.py 50.00% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@cvanelteren
Copy link
Collaborator Author

@beckermr should we merge with dev first? This is such a large change that this warrants a 2.0 release I reckon. I played around with it locally during work but it is likely that some bugs will turn up.

@beckermr
Copy link
Collaborator

Does anyone use the dev version? We can merge there, but I doubt we're going to do a ton more testing just because we merged to dev.

@cvanelteren
Copy link
Collaborator Author

I don't -- initially I want to structure the testing by first making it upstream. But we now got in the flow of pushing to main and then releasing from there. I can give this a spin for a week and first focus on the extra plot types before merging this to main. Then we can work up to the v2.0 and leave this as is for now. I have some code locall that implements #472 and #458 is not that difficult to implement either (perhaps a few weeks at most, time permitting). I don't necessarily mind jumping from say a v1.7x to 2.0 but just wanted to touch base with you before shipping a buggy release.

@beckermr
Copy link
Collaborator

Alright. If we think this feature will be deferred to 2.0, then let's do the following:

  • make a 1.x release branch from main now
  • merge this PR to main
  • merge future bug fixes and features to both main and 1.x until we release 2.0

@cvanelteren cvanelteren merged commit d108101 into main Jan 22, 2026
2 of 4 checks passed
@cvanelteren cvanelteren deleted the ultralayout-clean branch January 22, 2026 23:53
@cvanelteren
Copy link
Collaborator Author

cvanelteren commented Jan 22, 2026

Ok performed the actions you outlined and removed some stray branches on the remote (including dev as it was not used)

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.

Colorbar not aligning with custom layout

3 participants