Skip to content

Conversation

@cvanelteren
Copy link
Collaborator

The colorbar (apparently) fundamentally changes the gridspec in a non-trivial way, see #234. This causes an issue with the introduced GeoAxes sharing feature where the borders were determined based on the position in the gridpec. We can sidestep this issue by using the gridspec of the figure to reconstruct the position.

Current implementation now produces

image

@cvanelteren
Copy link
Collaborator Author

For context, when a colorbar is added, for example, to the right, the gridspec will change the coordinate for the 4th plot to (1,2),(1,2) (row and col span) I really don't understand why this happens and a similar cut happens for plots 6. Furthermore, the gridspec is changed from 3 x 3 to a 4x3 which does not make sense -- 3x4 would make sense but then still the gridspec spans are odd. Dunno why this happens but this PR sidesteps that issue.

@cvanelteren cvanelteren requested a review from Copilot May 27, 2025 15:43
Copy link
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 implements a hotfix to modify the way border axes are determined when a colorbar interferes with the gridspec, aiming to restore proper GeoAxes sharing.

  • Filters out non-standard axes such as colorbars or panels.
  • Reconstructs a grid using axis numbering via np.unravel_index rather than relying on axes-specific gridspec data.
  • Updates border detection logic based on grid positions.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@cvanelteren cvanelteren marked this pull request as draft May 27, 2025 15:46
@cvanelteren
Copy link
Collaborator Author

There are some errors in the tests -- converting to draft until fixed.

@cvanelteren
Copy link
Collaborator Author

Need to rework this such that adding a new subplot will automatically update the labels. The issue is currently that adding a colorbar makes room for those axes but the modification to the gridspec is something that is unclear to me -- as indicated above. The second row will take more space while the first row is left unchanged. Since the labels behave differently for GeoAxes, we should either

  1. make the system behave the same as normal plots -- which would require understanding how the labels are handled for these plots
  2. only allow label sharing set at draw time.
    I much prefer the first option, but I am not sure how trivial it is to figure out given limited amount of time.

@cvanelteren
Copy link
Collaborator Author

The issue is caused by UltraPlot can confirm that with native matplotlib this does not occur.

It is related to how UltraPlot internally accesses panels. Hidden panels are created for the subplot (perhaps change this?). This moves the rowspan. There is an internal function I could use to map this. More soon to follow.

@cvanelteren
Copy link
Collaborator Author

The border checker algorithm is replaced with a recursive algorithm based on the grid space. It uses the internal functions to recreate a gridspace rather than to rely on the subplotspec directly. We do need to put it on the docket why the subplotspec behaves so strangely. I would suggest we add this to the todos when we cover the gridspec.py in tests.

@codecov
Copy link

codecov bot commented May 29, 2025

Codecov Report

❌ Patch coverage is 98.55072% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
ultraplot/figure.py 97.56% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@cvanelteren
Copy link
Collaborator Author

Need to still fix that after unsharing the default plots will look different than when the axes were not shared.

@cvanelteren cvanelteren marked this pull request as ready for review May 30, 2025 16:26
@cvanelteren
Copy link
Collaborator Author

Two tests fail. The first is a bit odd but the second is fine.

This is a bit odd as the labels seem shifted, not sure why.
image

We expect here the axes to be off anyway.
image

@cvanelteren cvanelteren requested review from beckermr and Copilot May 30, 2025 17:04
Copy link
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 hotfix addresses an issue where adding a colorbar changes the figure’s gridspec, which in turn disrupts GeoAxes border sharing. The PR updates tests to explicitly control the sharing behavior, revises the border‐axes detection logic using a grid reconstruction approach, and adjusts the grid label visibility expectations for GeoAxes.

  • Updated tests to include explicit share parameters and revised expectations.
  • Refactored _get_border_axes to rebuild grid boundaries robustly.
  • Adjusted grid label toggling in GeoAxes to account for colorbar effects.

Reviewed Changes

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

Show a summary per file
File Description
ultraplot/tests/test_geographic.py Added a colorbar to the test and updated sharing level assertions.
ultraplot/tests/test_format.py Modified figure creation tests to include an explicit share parameter.
ultraplot/tests/test_axes.py Refactored helper functions and updated label visibility expectations.
ultraplot/figure.py Rewrote _get_border_axes to use a grid-based approach to determine borders.
ultraplot/axes/geo.py Updated GeoAxes sharing logic with changes in stale state handling.

cvanelteren and others added 3 commits May 30, 2025 19:05
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@cvanelteren
Copy link
Collaborator Author

Note that the ticks are by default off as they were erroneously added directly if the axes are shared, which was not intended.

@cvanelteren cvanelteren mentioned this pull request May 30, 2025
for side in sides:
tmp[side] = True
axi._toggle_gridliner_labels(**tmp)
self.stale = False
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am confused about why this bit of code was left here. In the top of _apply_axis_sharing the code reads

  # Handle X axis sharing
        if self._sharex:
            self._handle_axis_sharing(
                source_axis=self._sharex._lonaxis,
                target_axis=self._lonaxis,
            )

        # Handle Y axis sharing
        if self._sharey:
            self._handle_axis_sharing(
                source_axis=self._sharey._lataxis,
                target_axis=self._lataxis,
            )

So how does the code block you moved ever get called then?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Specifically, it appears the code always sets stale = False and then you early return with

# If we are not stale just return
        if not self.stale:
            return

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The code gets called through GeoAxes.draw. I may have reversed the logic. But to my understanding when an object is stale, we don't have to update. So I think the code is correct, but we can move it outside of draw function and move it to the setup, and add appropriate calls when the labels are changed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

To add to this -- the reason I am skipping it as the draw is called repeatedly and it is unnecessary to handle this (and rather expensive)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am not really happy with the answer I gave you. I see your point. I think the labels should be handled on setup rather than on the sharing step. I will move it there and update it when the label setters are called. One moment please.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

hmm there is some issue I have to solve.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok I tried moving it to the setup but the gridmajors a only modified on draw which creates an issue when we attempt to set it up on the figure class for example. I am reverting the commits

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok so the issue is that for the normal cartesian plots we can rely on the internal mechanisms from matplotlib where sharex and sharey exists. For GeoAxes the ticks are behaving differently depending on the backend used. The gridliner object is created relatively late in its life cycle and here we are patching it in such a way where we are modifying the labels after all the figures are created. When subplots are added iteratively, the sharing may be incorrect on creation -- on draw we know that the plot should have all the plots we want to see (at least for that draw). This logic relies on the stale mechanism to not draw this on every frame but only when changes are necessary.

@cvanelteren cvanelteren force-pushed the hotfix-get_border_axes branch from 9c908f3 to b5e7243 Compare June 1, 2025 13:14
@cvanelteren cvanelteren enabled auto-merge (squash) June 2, 2025 15:46
@cvanelteren cvanelteren disabled auto-merge June 2, 2025 15:46
@cvanelteren cvanelteren merged commit 84a57e6 into Ultraplot:main Jun 2, 2025
11 of 15 checks passed
@cvanelteren cvanelteren deleted the hotfix-get_border_axes branch June 2, 2025 15:47
cvanelteren added a commit to cvanelteren/ultraplot that referenced this pull request Jun 2, 2025
* simplified logic and basing reference on original grid

* rm print statements

* spelling

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* do more comprehensive checking

* rm debug

* add some reasoning

* fixed

* add a stale check

* compound tests and check for the failure

* update calls

* update tests

* formatting restored to defaults

* don't adjust labels when not sharing

* tests pass -- some expected failures

* rm debug statements

* fix test

* Update ultraplot/tests/test_geographic.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update ultraplot/axes/geo.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Revert changes

* rm duplicate

* fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
beckermr pushed a commit that referenced this pull request Jun 3, 2025
* simplified logic and basing reference on original grid

* rm print statements

* spelling

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* do more comprehensive checking

* rm debug

* add some reasoning

* fixed

* add a stale check

* compound tests and check for the failure

* fixed missing functions in grid

* need to fix test

* update calls

* update tests

* formatting restored to defaults

* don't adjust labels when not sharing

* tests pass -- some expected failures

* rm debug statements

* fix test

* added tests

* updated test to check for sharing of panels

* update test

* update test

* Update ultraplot/tests/test_geographic.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* rm unnecessary funcs

* Deprecate basemap (#243)

* Deprecate basemap. Basemap will be deprecated in the next major release (v2.0). See #243 for context.

* Hotfix get_border_axes (#236)

* simplified logic and basing reference on original grid

* rm print statements

* spelling

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* do more comprehensive checking

* rm debug

* add some reasoning

* fixed

* add a stale check

* compound tests and check for the failure

* update calls

* update tests

* formatting restored to defaults

* don't adjust labels when not sharing

* tests pass -- some expected failures

* rm debug statements

* fix test

* Update ultraplot/tests/test_geographic.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update ultraplot/axes/geo.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Revert changes

* rm duplicate

* fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* refactor panel_group_member

* mv logic  to base

* mv to the correct spot

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
cvanelteren added a commit that referenced this pull request Aug 14, 2025
* simplified logic and basing reference on original grid

* rm print statements

* spelling

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* do more comprehensive checking

* rm debug

* add some reasoning

* fixed

* add a stale check

* compound tests and check for the failure

* update calls

* update tests

* formatting restored to defaults

* don't adjust labels when not sharing

* tests pass -- some expected failures

* rm debug statements

* fix test

* Update ultraplot/tests/test_geographic.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update ultraplot/axes/geo.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Revert changes

* rm duplicate

* fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
cvanelteren added a commit that referenced this pull request Aug 14, 2025
* simplified logic and basing reference on original grid

* rm print statements

* spelling

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* do more comprehensive checking

* rm debug

* add some reasoning

* fixed

* add a stale check

* compound tests and check for the failure

* fixed missing functions in grid

* need to fix test

* update calls

* update tests

* formatting restored to defaults

* don't adjust labels when not sharing

* tests pass -- some expected failures

* rm debug statements

* fix test

* added tests

* updated test to check for sharing of panels

* update test

* update test

* Update ultraplot/tests/test_geographic.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* rm unnecessary funcs

* Deprecate basemap (#243)

* Deprecate basemap. Basemap will be deprecated in the next major release (v2.0). See #243 for context.

* Hotfix get_border_axes (#236)

* simplified logic and basing reference on original grid

* rm print statements

* spelling

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* do more comprehensive checking

* rm debug

* add some reasoning

* fixed

* add a stale check

* compound tests and check for the failure

* update calls

* update tests

* formatting restored to defaults

* don't adjust labels when not sharing

* tests pass -- some expected failures

* rm debug statements

* fix test

* Update ultraplot/tests/test_geographic.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update ultraplot/axes/geo.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Revert changes

* rm duplicate

* fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* refactor panel_group_member

* mv logic  to base

* mv to the correct spot

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
cvanelteren added a commit that referenced this pull request Jan 16, 2026
* simplified logic and basing reference on original grid

* rm print statements

* spelling

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* do more comprehensive checking

* rm debug

* add some reasoning

* fixed

* add a stale check

* compound tests and check for the failure

* update calls

* update tests

* formatting restored to defaults

* don't adjust labels when not sharing

* tests pass -- some expected failures

* rm debug statements

* fix test

* Update ultraplot/tests/test_geographic.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update ultraplot/axes/geo.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Revert changes

* rm duplicate

* fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
cvanelteren added a commit that referenced this pull request Jan 16, 2026
* simplified logic and basing reference on original grid

* rm print statements

* spelling

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* do more comprehensive checking

* rm debug

* add some reasoning

* fixed

* add a stale check

* compound tests and check for the failure

* fixed missing functions in grid

* need to fix test

* update calls

* update tests

* formatting restored to defaults

* don't adjust labels when not sharing

* tests pass -- some expected failures

* rm debug statements

* fix test

* added tests

* updated test to check for sharing of panels

* update test

* update test

* Update ultraplot/tests/test_geographic.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* rm unnecessary funcs

* Deprecate basemap (#243)

* Deprecate basemap. Basemap will be deprecated in the next major release (v2.0). See #243 for context.

* Hotfix get_border_axes (#236)

* simplified logic and basing reference on original grid

* rm print statements

* spelling

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* do more comprehensive checking

* rm debug

* add some reasoning

* fixed

* add a stale check

* compound tests and check for the failure

* update calls

* update tests

* formatting restored to defaults

* don't adjust labels when not sharing

* tests pass -- some expected failures

* rm debug statements

* fix test

* Update ultraplot/tests/test_geographic.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update ultraplot/figure.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update ultraplot/axes/geo.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Revert changes

* rm duplicate

* fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* refactor panel_group_member

* mv logic  to base

* mv to the correct spot

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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.

2 participants