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

Add set_in_autoscale() method #15595

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

robmarkcole
Copy link

PR Summary

The Artist class gained an set_in_autoscale() method which
is used to determine if the instance is used in the autoscale calculation.

PR Checklist

  • Has Pytest style unit tests
  • Code is Flake 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

@robmarkcole robmarkcole changed the title Add in autoscale Add set_in_autoscale() method Nov 2, 2019
@robmarkcole
Copy link
Author

PR suggested by @anntzer

@anntzer
Copy link
Contributor

anntzer commented Nov 4, 2019

Note that this would not only be useful in itself, but would also fix a long-standing issue hinted at in

# TODO: the fix for the collections relim problem is to move the
# limits calculation into the artist itself, including the property of
# whether or not the artist should affect the limits. Then there will
# be no distinction between axes.add_line, axes.add_patch, etc.
# Collections are deliberately not supported (yet); see
# the TODO note in artists.py.

which basically asks for Collections to have such a flag -- and then we can get rid of the autolim kwarg in
def add_collection(self, collection, autolim=True):

which is basically a one-off version of the property.

Copy link
Member

@timhoffm timhoffm left a comment

Choose a reason for hiding this comment

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

Generally, 👍

  1. How does this relate to autolim parameter of add_collection()?
  2. This conceptually is similar to the visibility checks in relim().
    if not visible_only or line.get_visible():

    It would be good to have both checks either inside the _update_*_limits or in relim() but not distributed over two places.

@anntzer
Copy link
Contributor

anntzer commented Nov 4, 2019

  1. How does this relate to autolim parameter of add_collection()?

Places which used to call add_collection(..., autolim=False) should just set the collection's in_autoscale property to False before passing it to add_collection (and add_collection should be updated to take it that property into account).

  1. This conceptually is similar to the visibility checks in relim(). It would be good to have both checks either inside the update*_limits or in relim() but not distributed over two places.

That's a bit tricky to do, as relim() is a public API but we should not modify the state of the artist depending on whether visible_only was passed to relim.

Copy link
Member

@jklymak jklymak left a comment

Choose a reason for hiding this comment

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

An example page would be nice..

@anntzer
Copy link
Contributor

anntzer commented Nov 12, 2019

will work on it

@anntzer
Copy link
Contributor

anntzer commented Nov 23, 2019

(Note to self: once this is merged this can also be used to control autolimits behavior in axline() as mentioned in the side note of #15330 (comment)).

@mwaskom
Copy link

mwaskom commented Dec 17, 2019

It was mentioned in #15967 that this method (which solves exactly a problem that I having been having) applies to both axes in a plot, but there may be times when you want to exclude autoscaling on one axis but allow it on another. In fact, there is some precedence for that independence, e.g. with the scalex/scaley parameters in plt.plot.

@timhoffm
Copy link
Member

I see the point of being able to specify this per axis.

Not completely thought this through API-wise, but a axis parameter similar to the one in tick_params might be the way to go.

@tacaswell
Copy link
Member

The input side of the API in clear and can be backwards ly, but what does the get side return? Do we want to do {'x': True, 'y': False}?

@mwaskom
Copy link

mwaskom commented Jul 22, 2020

Ymmv but I think an (x, y) pair would be fine

@tacaswell
Copy link
Member

Blind tuples are pragmatic, but can lead to confusion if we start to lose track of what they mean.

On the other hand, that ambiguity can be leverage to play nicely with polar plots.

If we go with a tuple / dict / whatever we should also extend it to 3D as well?

@timhoffm
Copy link
Member

How about using a namedtuple?

@tacaswell
Copy link
Member

On a bit more consideration, I think that a tuple is probably the best path. The artists don't actually know if they are in an (x, y), (r, \theta), (ra, dec), or (lat, lon) coordinate system, they just know they are in 2D (or 3D) so trying to same them will end up causing more issues because it will be wrong rather than ambiguous.

@timhoffm
Copy link
Member

timhoffm commented Nov 18, 2020

API proposal:

Setter

set_in_autoscale(False)  # for both axises
set_in_autoscale((False, True)) # for each axis s
set_in_autoscale((False, True, False)) # for 3D

Rationale: I find it more clear to have a single parameter that can be a scalar or a tuple compared to having variable number of arguments. In the latter case, we'd have to set_in_autoscale(*args) because you cannot have explicit arguments (set_in_autoscale(scalex, scaley)) and supporting a single value applying to all dimensions. But the single-parameter case is the primary usecase and excluding single dimensions is far more rare.

Getter

scalex, scaley = get_in_autoscale()
scalex, scaley, scalez = get_in_autoscale()

Per #15595 (comment) a simple tuple is good enough and saves the hassle of determining meaningful names, which can depend on the projection.

Internal representation

self._in_autoscale should always be a tuple with as many entries as dimensions in the plot (2D/3D). The expansion from scalar to tuple should be done in the setter.

@robmarkcole Sorry this fell under the table. Are you still interested in working on this?

@tacaswell
Copy link
Member

Rebased to use this as the start of the implementation for #25139

@tacaswell
Copy link
Member

Tasks:

  • adopt tuple rather than a single bool
  • move the autolim logic into the Artist classes.

@robmarkcole Do you mind if we work in this PR / on your branch? I would rather do so because it keeps the discussion in one place, but also completely understand if you no longer are interested in getting notified about this discussion!

@juseg
Copy link

juseg commented Mar 6, 2023

This new property will be super useful! Could you explain the rationale for naming it in_autoscale instead of partly backward-compatible autolim from add_collections? I am implemeting autolim in geopandas and wondering if I should call it in_autoscale instead. Thanks!

@fburgaud
Copy link

Any updates on this PR? would be a very useful feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Waiting for author
Development

Successfully merging this pull request may close these issues.

Add scale(x)(y) parameter(s) to imshow as in plot
10 participants