Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Axes.cla() with sharex may wrongly reset the axes limit. #27825

Open
tianzhuqiao opened this issue Feb 27, 2024 · 1 comment · May be fixed by #28101
Open

[Bug]: Axes.cla() with sharex may wrongly reset the axes limit. #27825

tianzhuqiao opened this issue Feb 27, 2024 · 1 comment · May be fixed by #28101
Milestone

Comments

@tianzhuqiao
Copy link

Bug summary

For example, when subplot A shares the x-axis with subplot B (A is created with sharex=B), a call to B.cla() will set the xlimit to [0, 1], which may not be expected (in contrast, a call to A.cla() will not change the xlimit).

I think the main problem comes from the following function, where it will check whether its _sharex attribute is None; however, in this case, B is shared to A, but no axis is shared to B, so B's _sharex attribute is None.

if share is not None:

Code for reproduction

ax = plt.subplot(211)
ax2 = plt.subplot(212, sharex=ax)
ax.plot(range(50))
ax2.plot(range(50))
ax.cla()
plt.show()

Actual outcome

image

Expected outcome

image

Additional information

No response

Operating system

No response

Matplotlib Version

3.8.3

Matplotlib Backend

'TkAgg'

Python version

3.9.13

Jupyter version

No response

Installation

pip

@JamesCamilleri13
Copy link

Hi,
I suggest that if A shares an axis with B, then B should also have his sharex/sharey attribute changed.

The following modification in the lib/matplotlib/axes/_base.py file solves your issue.

diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py
index 12dace5b00..874e30e9e5 100644
--- a/lib/matplotlib/axes/_base.py
+++ b/lib/matplotlib/axes/_base.py
@@ -1233,8 +1233,8 @@ class _AxesBase(martist.Artist):
         x0, x1 = other.get_xlim()
         self.set_xlim(x0, x1, emit=False, auto=other.get_autoscalex_on())
         self.xaxis._scale = other.xaxis._scale
+        other._shared_axes["x"].join(other, self)
+        other._sharex = self

     def sharey(self, other):
         """
@@ -1254,8 +1254,8 @@ class _AxesBase(martist.Artist):
         y0, y1 = other.get_ylim()
         self.set_ylim(y0, y1, emit=False, auto=other.get_autoscaley_on())
         self.yaxis._scale = other.yaxis._scale
+        other._shared_axes["y"].join(other, self)
+        other._sharey = self

     def __clear(self):
         """Clear the Axes."""
@@ -1374,7 +1374,7 @@ class _AxesBase(martist.Artist):
             share = getattr(self, f"_share{name}")
             if share is not None:
 		 getattr(self, f"share{name}")(share)
+                axis.set_inverted(False)
             else:
                 # Although the scale was set to linear as part of clear,
                 # polar requires that _set_scale is called again

After running tests , i noticed that we also have to manually invert any inverted axis when clearing a subplot

@JamesCamilleri13 JamesCamilleri13 linked a pull request Apr 18, 2024 that will close this issue
@tacaswell tacaswell added this to the v3.10.0 milestone Apr 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants