Skip to content

gca(projection="rectilinear") fails to reset projection on axes #10700

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

Closed
anntzer opened this issue Mar 6, 2018 · 7 comments · Fixed by #19438
Closed

gca(projection="rectilinear") fails to reset projection on axes #10700

anntzer opened this issue Mar 6, 2018 · 7 comments · Fixed by #19438

Comments

@anntzer
Copy link
Contributor

anntzer commented Mar 6, 2018

Bug report

Bug summary

As of 2.2:

plt.gca(projection="polar"); plt.gca(projection="lambert")

shows a warning and replaces the originally created polar axes by a lambert axes (not sure what behavior we actually want this to have once axes-collision detection in add_axes is removed).
However, in

plt.gca(projection="polar"); plt.gca(projection="rectilinear")

the second call to gca (using a rectilinear projection) fails to reset the projection at all and leaves the original polar axes in place.

Noted while thinking about #10674.

@efiring
Copy link
Member

efiring commented Mar 7, 2018

We need to figure out exactly what gca is supposed to do, with or without kwargs. Suggestion:

  • If the current Axes exists and matches the kwargs (if any), return it.
  • If the current Axes exists and doesn't match the request, raise an Exception.
  • Otherwise, make a new Axes as requested.

Note: All this is in the pyplot context, where there can be many Axes, Figures, and Images, but for each of these categories there is a single current one.

In my suggestion, gca would not search through existing Axes--it would only check to see if it can use the current one. It would never modify or delete the current Axes.

I think that part of the problem we are running into is confusion between gca as a user-level pyplot command, and our use of gca inside pyplot functions, like polar. Functions like gca and polar should be simple--they were supposed to be designed for casual users and quick use. We need to lay out the simple scenarios for their use, and construct and document them accordingly.

If such a scenario includes gca(); polar(r, theta); then the logic for replacing the current rectilinear Axes with a polar Axes can reside in polar, without complicating gca.

@efiring
Copy link
Member

efiring commented Mar 7, 2018

Addendum: Looking at some code, I suspect my precise suggestion is not feasible (can't get there from here), but the basic points remain.

@timhoffm
Copy link
Member

timhoffm commented Apr 4, 2018

I agree with @efiring's suggestion. In my interpretation, the main purpose is "getting the current axes" as the name says - no arguments required. As a fallback, if no axes exists, one is created which may need the parameters "get the current axes with these parameters".

For a sane API plt.gca(projection="rectilinear") must always result in a rectilinear axes and not change the current axes. Otherwise it should fail with an exception.

If a function like polar needs a certain projection it has to care for that itself.

Why exactly do you think a clean gca is not feasible?

@anntzer
Copy link
Contributor Author

anntzer commented Apr 4, 2018

(fwiw I don't actually really care about what the exact semantics of gca() are (I don't ever use it, after all :-)), other that they should be reasonably consistent... additional points if it allows us to get rid of (parts of) the internal AxesStack object, which seems to try to do too much IMO)

@anntzer
Copy link
Contributor Author

anntzer commented Dec 24, 2019

Looking at this again I wonder whether the simple solution is not just to deprecate all kwargs to gca() (one can instead call plt.subplot(**kwargs) to create a new subplot) and restrict gca() to, well, returning the current axes and do nothing else.

@timhoffm
Copy link
Member

Agreed, that plt.gca() should not be used to create complex axes, so kwargs should be deprecated.

I would still allow a bare plt.gca() to create a default figure/axes if none exists. That's in the spirit of pyplot: A figure and axes are automatically created if necessary.

@anntzer
Copy link
Contributor Author

anntzer commented Dec 25, 2019

Yes, gca() should still create an axes if none exists.

tacaswell added a commit to tacaswell/matplotlib that referenced this issue Feb 12, 2021
This adds a small amount of additional state to the Axes created via
Figure.add_axes and Figure.add_subplot (which the other Axes creation
methods eventually funnel through) to track the projection class and
(processed) kwargs.

We then use that state in `pyplot.subplot` to determine if we should
re-use an Axes found at a given position or create a new one (and
implicitly destroy the existing one).

This also changes the behavior of `plt.subplot` when no kwargs are
passed to return the Axes at the location without doing any matching
of the kwargs.

As part of this work we also fixed two additional bugs:
 - you can now force Axes "back to" rectilinear Axes by passing
   projection='rectilinear'
 - Axes3D instances can now be re-selected at all

closes matplotlib#19432
closes matplotlib#10700
tacaswell added a commit to tacaswell/matplotlib that referenced this issue Feb 16, 2021
This adds a small amount of additional state to the Axes created via
Figure.add_axes and Figure.add_subplot (which the other Axes creation
methods eventually funnel through) to track the projection class and
(processed) kwargs.

We then use that state in `pyplot.subplot` to determine if we should
re-use an Axes found at a given position or create a new one (and
implicitly destroy the existing one).

This also changes the behavior of `plt.subplot` when no kwargs are
passed to return the Axes at the location without doing any matching
of the kwargs.

As part of this work we also fixed two additional bugs:
 - you can now force Axes "back to" rectilinear Axes by passing
   projection='rectilinear'
 - Axes3D instances can now be re-selected at all

closes matplotlib#19432
closes matplotlib#10700
tacaswell added a commit to tacaswell/matplotlib that referenced this issue Feb 18, 2021
This adds a small amount of additional state to the Axes created via
Figure.add_axes and Figure.add_subplot (which the other Axes creation
methods eventually funnel through) to track the projection class and
(processed) kwargs.

We then use that state in `pyplot.subplot` to determine if we should
re-use an Axes found at a given position or create a new one (and
implicitly destroy the existing one).

This also changes the behavior of `plt.subplot` when no kwargs are
passed to return the Axes at the location without doing any matching
of the kwargs.

As part of this work we also fixed two additional bugs:
 - you can now force Axes "back to" rectilinear Axes by passing
   projection='rectilinear'
 - Axes3D instances can now be re-selected at all

closes matplotlib#19432
closes matplotlib#10700

Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
tacaswell added a commit to tacaswell/matplotlib that referenced this issue Feb 18, 2021
This adds a small amount of additional state to the Axes created via
Figure.add_axes and Figure.add_subplot (which the other Axes creation
methods eventually funnel through) to track the projection class and
(processed) kwargs.

We then use that state in `pyplot.subplot` to determine if we should
re-use an Axes found at a given position or create a new one (and
implicitly destroy the existing one).

This also changes the behavior of `plt.subplot` when no kwargs are
passed to return the Axes at the location without doing any matching
of the kwargs.

As part of this work we also fixed two additional bugs:
 - you can now force Axes "back to" rectilinear Axes by passing
   projection='rectilinear'
 - Axes3D instances can now be re-selected at all

closes matplotlib#19432
closes matplotlib#10700

Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
tacaswell added a commit to tacaswell/matplotlib that referenced this issue Feb 18, 2021
This adds a small amount of additional state to the Axes created via
Figure.add_axes and Figure.add_subplot (which the other Axes creation
methods eventually funnel through) to track the projection class and
(processed) kwargs.

We then use that state in `pyplot.subplot` to determine if we should
re-use an Axes found at a given position or create a new one (and
implicitly destroy the existing one).

This also changes the behavior of `plt.subplot` when no kwargs are
passed to return the Axes at the location without doing any matching
of the kwargs.

As part of this work we also fixed two additional bugs:
 - you can now force Axes "back to" rectilinear Axes by passing
   projection='rectilinear'
 - Axes3D instances can now be re-selected at all

closes matplotlib#19432
closes matplotlib#10700

Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
MihaiAnton pushed a commit to MihaiAnton/matplotlib that referenced this issue Mar 8, 2021
This adds a small amount of additional state to the Axes created via
Figure.add_axes and Figure.add_subplot (which the other Axes creation
methods eventually funnel through) to track the projection class and
(processed) kwargs.

We then use that state in `pyplot.subplot` to determine if we should
re-use an Axes found at a given position or create a new one (and
implicitly destroy the existing one).

This also changes the behavior of `plt.subplot` when no kwargs are
passed to return the Axes at the location without doing any matching
of the kwargs.

As part of this work we also fixed two additional bugs:
 - you can now force Axes "back to" rectilinear Axes by passing
   projection='rectilinear'
 - Axes3D instances can now be re-selected at all

closes matplotlib#19432
closes matplotlib#10700

Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
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