Skip to content

Conversation

@cvanelteren
Copy link
Collaborator

@cvanelteren cvanelteren commented Dec 14, 2025

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 changed the title Add kiwisolver-based constraint layout for non-orthogonal subplot arrangements Add UltraLayout: Advanced constraint-based positioning for non-orthogonal subplot arrangements Dec 14, 2025
@cvanelteren cvanelteren marked this pull request as draft December 14, 2025 07:53
@cvanelteren
Copy link
Collaborator Author

cvanelteren commented Jan 11, 2026

This PR is turning into a beast. It replaces one of the fundamentals of UltraPlot: its layout mechanism. It improves the layout by moving towards a constraint based approach (using kiwisolver). In the PR we separate gridspec from the layout to focus content on managing the layout (Gridspec) and drawing and aligning the plot (UltraLayout). While we get a small performance boost (+- 3-5%) the major improvement is behind the scenes and the user facing API is not affected. In addition, we allow for probe functions to pass through solving an issue with the IDE Positron (#270).

To aid in the review, I constructed the following checklist. I am aiming for a 2.0 release giving us some time to review and or iron out some kinks before merging. I am not expecting the 2.0 to be there for a while (couple of months) as we slowly progress and clean existing PRs with higher priority. Say we aim for the latest being May 2026.

The visual tests look good (locally) even though they fail on size, visually they look good

PR Review Checklist (novo-layout)

  • Layout semantics

    • Panels stack correctly on shared sides; panel widths/heights respect main grid spacing.
    • Ref sizing/aspect: refwidth/refheight targets preserved, sizes snapped to pixel grid, zero-tolerance resizes when refs are explicit.
    • Auto-layout does not re-run tight/aspect after final resize; whitespace looks stable.
  • UltraLayout

    • New ultralayout.py solver API is clear; enabled by default when kiwi is available.
    • tests/test_ultralayout.py covers core scenarios; solver on/off behavior is sane.
  • Robustness fixes

  • Tests/baselines

    • Imshow baselines updated (test_inbounds_data, test_standardized_input, test_colorbar) reflect square layout.
    • Key suites pass: pytest ultraplot/tests/test_imshow.py --mpl, pytest ultraplot/tests/test_ultralayout.py.
  • Behavior spot-checks

    • Manual plot with panels + imshow/pcolor shows correct spacing and square images.
    • Interactive backend draw doesn’t raise and feels at least as responsive as main.

@cvanelteren
Copy link
Collaborator Author

Some examples
image
image

@cvanelteren cvanelteren marked this pull request as ready for review January 11, 2026 02:01
@cvanelteren cvanelteren self-assigned this Jan 11, 2026

This comment was marked as resolved.

This comment was marked as resolved.

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

2 participants