You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Unexpected change in behavior in plt.subplot #19432
No deprecation warning or future warning was raised in this case.
Following #19153, this silently ignores the projection and slices in the second call and the print statement returns True.
I don't think #19153 was intended to start making plt.subplot return the same axes in some cases, rather I thought the goal of that PR was to remove re-use of axes in certain circumstances, so I think this is a regression/bug
The behavior of the functions to create new axes (pyplot.axes, pyplot.subplot, figure.Figure.add_axes, figure.Figure.add_subplot) has changed. In the past, these functions would detect if you were attempting to create Axes with the same keyword arguments as already-existing axes in the current figure, and if so, they would return the existing Axes. Now, these functions will always create new Axes. A special exception is pyplot.subplot, which will reuse any existing subplot with a matching subplot spec. However, if there is a subplot with a matching subplot spec, then that subplot will be returned, even if the keyword arguments with which it was created differ.
It seems like even if this is new expected behaviour, we shouldn't be making behaviour changes without a suitable deprecation period, and it sounds like there wasn't any deprecation for the example above.
So, for 3.4 I think we should
Re-instate the previous behaviour for the case above (same subplot spec, different projections)
Add a deprecation warning saying that the behaviour will change in the future
@lpsinger that is a pretty radical change that might break things for a lot of astropy users, and I don't think something like this can be done without a deprecation warning of some kind (the example I showed above did not show any deprecation warning). This seems like a step backwards - what is the motivation for breaking this behavior? I'm completely on board with no longer automatically returning the same axes in many cases but why change things for the example above from not returning the same to returning the same?
Just out of curiosity, what is the motivation for breaking cases like the example I showed? Why would a user ever want the same axes object if the projection is different?
Just out of curiosity, what is the motivation for breaking cases like the example I showed? Why would a user ever want the same axes object if the projection is different?
Indeed, our docs even said that if you had unique args and kwargs you would get a new subplot, so this is definitely a bug that needs fixing before 3.4 is released:
If the figure already has a subplot with key (*args*,
*kwargs*) then it will simply make that subplot current and
return it. This behavior is deprecated. Meanwhile, if you do
not want this behavior (i.e., you want to force the creation of a
new subplot), you must use a unique set of args and kwargs.
@lpsinger - but this just refers to the case where kwargs are the same:
In Matplotlib 2.1, the behavior of reusing existing axes when created with the same arguments was deprecated (see #9037). The request is to finally remove this behavior.
I don't see any good reason why in my example above ax1 and ax2 should be the same since the kwargs are clearly different?
Again, this is a major change that is going to affect a lot of users - think about users who loop over files and in the loop call plt.subplot with different projections each time - now they will silently get the same axes over and over with the projection from the first file.
Indeed, our docs even said that if you had unique args and kwargs you would get a new subplot, so this is definitely a bug that needs fixing before 3.4 is released:
If the figure already has a subplot with key (*args*,
*kwargs*) then it will simply make that subplot current and
return it. This behavior is deprecated. Meanwhile, if you do
not want this behavior (i.e., you want to force the creation of a
new subplot), you must use a unique set of args and kwargs.
It was an oversight that this paragraph should have been removed in #19153. See #19433.
While researching why Matplotlib required projection keyword arguments to be hashable, I discovered that it was in order to support axes reuse. That was my rationale for removing axes reuse, except (as was suggested by @tacaswell in #18978 (comment)) the one special case of plt.subplot when reusing existing subplots with the same subplot spec.
@lpsinger - I can see why removing axes reuse makes sense, but I don't see the motivation for introducing new axes reuse behavior where it did not previously exist?
My reading of #18978 was that @tacaswell did not want to break certain behaviors (e.g. calling plt.subplot(222) twice should return the same object) but I don't think it was his intent to mean that examples such as the one here should now be changed to return the same axes? (@tacaswell can you comment on this?)
That's right, that behavior is (supposed to be) preserved. Is it?
It is, but I was going down the path of sorting out how to resolve "we have N axes at this location, we need to see if any of them match .." so the diff is even smaller than I anticipated.
Activity
lpsinger commentedon Feb 2, 2021
This is the expected behavior. From https://matplotlib.org/devdocs/users/next_whats_new/axes_kwargs_collision.html:
dstansby commentedon Feb 2, 2021
It seems like even if this is new expected behaviour, we shouldn't be making behaviour changes without a suitable deprecation period, and it sounds like there wasn't any deprecation for the example above.
So, for 3.4 I think we should
astrofrog commentedon Feb 2, 2021
@lpsinger that is a pretty radical change that might break things for a lot of astropy users, and I don't think something like this can be done without a deprecation warning of some kind (the example I showed above did not show any deprecation warning). This seems like a step backwards - what is the motivation for breaking this behavior? I'm completely on board with no longer automatically returning the same axes in many cases but why change things for the example above from not returning the same to returning the same?
astrofrog commentedon Feb 2, 2021
Just out of curiosity, what is the motivation for breaking cases like the example I showed? Why would a user ever want the same axes object if the projection is different?
lpsinger commentedon Feb 2, 2021
For the motivation, see #18832.
dstansby commentedon Feb 2, 2021
Indeed, our docs even said that if you had unique args and kwargs you would get a new subplot, so this is definitely a bug that needs fixing before 3.4 is released:
astrofrog commentedon Feb 2, 2021
@lpsinger - but this just refers to the case where kwargs are the same:
In Matplotlib 2.1, the behavior of reusing existing axes when created with the same arguments was deprecated (see #9037). The request is to finally remove this behavior.
I don't see any good reason why in my example above
ax1andax2should be the same since the kwargs are clearly different?Again, this is a major change that is going to affect a lot of users - think about users who loop over files and in the loop call
plt.subplotwith different projections each time - now they will silently get the same axes over and over with the projection from the first file.lpsinger commentedon Feb 2, 2021
It was an oversight that this paragraph should have been removed in #19153. See #19433.
astrofrog commentedon Feb 2, 2021
@lpsinger - could you clarify though, why would a user ever want the same axes if the projection and kwargs are different?
lpsinger commentedon Feb 2, 2021
As I wrote in #18832:
While researching why Matplotlib required projection keyword arguments to be hashable, I discovered that it was in order to support axes reuse. That was my rationale for removing axes reuse, except (as was suggested by @tacaswell in #18978 (comment)) the one special case of
plt.subplotwhen reusing existing subplots with the same subplot spec.astrofrog commentedon Feb 2, 2021
@lpsinger - I can see why removing axes reuse makes sense, but I don't see the motivation for introducing new axes reuse behavior where it did not previously exist?
astrofrog commentedon Feb 2, 2021
My reading of #18978 was that @tacaswell did not want to break certain behaviors (e.g. calling
plt.subplot(222)twice should return the same object) but I don't think it was his intent to mean that examples such as the one here should now be changed to return the same axes? (@tacaswell can you comment on this?)astrofrog commentedon Feb 2, 2021
To be clear, if people want to keep this new behavior, I think that:
11 remaining items
tacaswell commentedon Feb 2, 2021
It is, but I was going down the path of sorting out how to resolve "we have N axes at this location, we need to see if any of them match .." so the diff is even smaller than I anticipated.
tacaswell commentedon Feb 2, 2021
See #19438 which I think gets everything we want:
at the cost of carry around one more dictionary as private state on the Axes.
lpsinger commentedon Feb 2, 2021
Nice! That patch is delightfully simple.
astrofrog commentedon Feb 2, 2021
Thanks everyone for converging on a solution and @tacaswell for the PR! :)
FIX: restore creating new axes via plt.subplot with different kwargs
FIX: restore creating new axes via plt.subplot with different kwargs
FIX: restore creating new axes via plt.subplot with different kwargs
FIX: restore creating new axes via plt.subplot with different kwargs
FIX: restore creating new axes via plt.subplot with different kwargs
FIX: restore creating new axes via plt.subplot with different kwargs
FIX: restore creating new axes via plt.subplot with different kwargs
FIX: restore creating new axes via plt.subplot with different kwargs
FIX: restore creating new axes via plt.subplot with different kwargs
FIX: restore creating new axes via plt.subplot with different kwargs