Skip to content

Conversation

@cvanelteren
Copy link
Collaborator

@cvanelteren cvanelteren commented Jan 14, 2025

Addresses #11 (comment)

The MPL api changed in v3.6 where get_[x/y]_shared_axes returns an immutable object.

  • check remaining code base for use of this object
  • write unittests
    • to test for sharing limits
    • to test for sharing labels (only)

@cvanelteren cvanelteren marked this pull request as draft January 14, 2025 16:54
@cvanelteren
Copy link
Collaborator Author

Note to self: not sure exactly how the sharing is operating at this moment. There was an api change that made the original implementation in proplot invalid and ultraplot inherited this legacy. The proposed change makes it work as it should, but the actual labels of the axis are still internally held the same. That is, we get a proper output image, but when I check if the labels of the individual axes are in fact shared, they are not. I feel uncomfortable merging this without this feature being there -- I will need to check if older versions in fact pass this test or not.

@cvanelteren
Copy link
Collaborator Author

image

@cvanelteren
Copy link
Collaborator Author

Quick update.

  • Proplot has the same issue with 0.95 that the axis sharing is a bit funky
  • I noticed that draw is not called pre-plot. Manually drawing it does update the shared labels correctly.

@cvanelteren
Copy link
Collaborator Author

Should be good now -- open for review

@cvanelteren cvanelteren marked this pull request as ready for review January 16, 2025 09:47
@cvanelteren
Copy link
Collaborator Author

cvanelteren commented Jan 16, 2025

Pinging @beckermr @pratiman-91 🔔

Copy link
Contributor

@pratiman-91 pratiman-91 left a comment

Choose a reason for hiding this comment

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

It looks good to me! Maybe check with another reviewer.

Copy link
Collaborator

@beckermr beckermr left a comment

Choose a reason for hiding this comment

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

Relying on private class attributes is fragile. It'd be better to only use public methods / attributes.

@cvanelteren
Copy link
Collaborator Author

cvanelteren commented Jan 16, 2025

The MPL documentation does not allow to share one axis across multiple subplots (see here). I tried implementing this:

    def _safe_share(self, axis_name, other_axis):
        if hasattr(self, f"_share{axis_name}"):
            setattr(self, f"_share{axis_name}", None)
        getattr(self, f"share{axis_name}")(other_axis)

However this results in the axis labels not being shared properly and the ticks being messed up:

image

@cvanelteren
Copy link
Collaborator Author

Note unsharing axis is also not allowed according to their docs. This would force us to either (a) write our own implementation, or abuse the api as is done here.

@cvanelteren
Copy link
Collaborator Author

Perhaps we could do this

   def share_axis(self, which, other):
        if not isinstance(other, plot.PlotAxes):
            raise ValueError("other must be an Axes instance")
        shared = getattr(self, f"get_shared_{which}_axes")()
        if which == "x":
            if other in shared:
                return
            self._shared_axes["x"].join(self, other)
        else:
            if other in shared:
                return
            self._shared_axes["y"].join(self, other)

To circumenvent the error and enable proper sharing?

@beckermr
Copy link
Collaborator

Then it appears developing an implementation using public apis is the correct approach.

There appears to be api instability in MPL even for public attributes. One should therefore expect that relying explicitly on private ones will be even more unstable. I think the history of new MPL versions breaking with proplot/ultraplot matches these expectations.

@cvanelteren
Copy link
Collaborator Author

Actually scratch that these methods produce error. Not sure how to proceed here.. open for feedback.

@cvanelteren
Copy link
Collaborator Author

To maintain Ultraplot's multiple axis sharing capability while respecting Matplotlib's API changes, we can override Matplotlib's public sharing methods with our own implementation. This approach allows us to bypass Matplotlib's single-axis sharing limitation while preserving Ultraplot's existing functionality. Although not ideal, this serves as a pragmatic interim solution until a more permanent resolution can be implemented.

Copy link
Collaborator

@beckermr beckermr left a comment

Choose a reason for hiding this comment

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

Comments on the code. I still see one private attribute accessed, but this PR is closer in that we are adding APIs that we needed and/or were removed.

cvanelteren and others added 3 commits January 16, 2025 16:59
Co-authored-by: Matthew R. Becker <beckermr@users.noreply.github.com>
@cvanelteren cvanelteren merged commit 46616ab into Ultraplot:main Jan 17, 2025
3 checks passed
@cvanelteren cvanelteren deleted the axis_sharing_fix branch January 17, 2025 16:20
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.

3 participants