-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Make kwargs names in scale.py not include the axis direction. #14916
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
Conversation
1e946e0
to
acd0e2f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've always found the abbreviations quite confusing. Since we're renaming the parameters anyway, we could move to more telling names:
subs
-> subticks
nonpos
-> nonpositive
linthresh
-> linthreshold
But to be fair, that'd be a bit more work; at least for subs
and linthresh
. They are used as public attributes in some places, which should then be deprecated/changed as well. nonpos
is only a private attribute.
@rename_parameter("3.2", f"linthresh{axis.axis_name}", "linthresh") | ||
@rename_parameter("3.2", f"subs{axis.axis_name}", "subs") | ||
@rename_parameter("3.2", f"linscale{axis.axis_name}", "linscale") | ||
def __init__(*, base=10, linthresh=2, subs=None, linscale=1, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any particular reason to call this __init__
? I would just use init
because it's just a regular local method. The dunder may be a bit misleading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is so that when the wrong arg names are passed, Python generates the error message with the right name (__init__() got an unexpected argument...
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a comment in the code for why you did this? I guess its just a place holder until a future version?
I agree that if we are changing the names it may be better to directly pick better names rather than have two changes in a row... but subs and linthresh are also used as parameter/attribute names in ticker.py, which would also need to be changed for consistency, but that seems to not cross the threshold of "is it really worth the disruption". |
We should at least change For reference: Usages of
Usage of
I agree that |
nonpos also maps to minpos, which appears in various places. |
😭 In the trade-off I wouldn't let that prevent the |
acd0e2f
to
6551cb1
Compare
I'm fine with renaming |
6551cb1
to
965f599
Compare
92041d0
to
3e4af57
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great to me, just a few minor questions. I think this is worth the API change - I don't see any reason a scale
should care if its an x or y axis....
lib/matplotlib/axes/_axes.py
Outdated
@@ -1791,16 +1791,13 @@ def loglog(self, *args, **kwargs): | |||
**kwargs | |||
All parameters supported by `.plot`. | |||
""" | |||
dx = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx'] | |||
dx = {k[:-1]: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, why are you excluding the last element here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the kwarg name for semilogx/y is still "basex"; this PR doesn't change that. Specifically, while I could change the kwarg name in semilogx to "base" (with the same deprecation), this doesn't work for loglog(), which needs a separate basex/basey (although it would also be reasonable to deprecate supporting directly setting two different bases for x and y in loglog() and require the user to call set_x/yscale("log", base=...) for that specific case. I think we just need to decide on the best API change here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Duh, I see now, but this might be a rare case where not using comprehension might be a lot clearer:
for k in ['basex', 'subex', 'nonposx']:
dx{k[:-1]} = kwargs.pop(k)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the side-effect of popping kwargs in the comprehension may not be nicest, and can change that, but before doing so, do you have comments on the API changes suggested above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that most folks won't use different basex
, basey
. OTOH there is call to use different subs
and nonpos
isn't there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
People can still use set_xscale("log", subs=...)
in that case. Note that in the (common?) case of using the same subs on x and y, the proposed new API is actually nicer (loglog(..., subs=...)
instead of repeating yourself with subs(..., subsx=..., subsy=...)
).
I have kind of changed my mind compared to when I first wrote the PR; I now think that having the same kwargs in loglog
/semilogx/y
as in set_scale("log", ...)
would actually be quite nice (whereas I was previously more ok with keeping basex/basey on loglog/semilog).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be onboard with this, but we should prob be prepared to not do this if the deprecation warning freaks too many people out.
Other comments? @timhoffm @ImportanceOfBeingErnest @efiring?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
basex, basey are poor names anyway; I would be happy to see them go. This sort of regularization of the API will inevitably cause some pain, but I think we should do it.
@@ -280,8 +280,11 @@ class LogTransform(Transform): | |||
|
|||
def __init__(self, base, nonpos='clip'): | |||
Transform.__init__(self) | |||
if base <= 0 or base == 1: | |||
raise ValueError('The log base cannot be <= 0 or == 1') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happened before? Did we just get a ValueError later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error checking was in LogScale (which calls into LogTransform), but that meant that you could construct invalid LogTransforms which only errored out at use time. With the change you can't construct invalid LogTransforms or LogScales anymore.
if linthresh <= 0.0: | ||
raise ValueError("'linthresh' must be positive") | ||
if linscale <= 0.0: | ||
raise ValueError("'linscale' must be positive") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as above
@rename_parameter("3.2", f"linthresh{axis.axis_name}", "linthresh") | ||
@rename_parameter("3.2", f"subs{axis.axis_name}", "subs") | ||
@rename_parameter("3.2", f"linscale{axis.axis_name}", "linscale") | ||
def __init__(*, base=10, linthresh=2, subs=None, linscale=1, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a comment in the code for why you did this? I guess its just a place holder until a future version?
3e4af57
to
bbb5d4f
Compare
re your last point: added a comment to clarify. |
bbb5d4f
to
eb37584
Compare
👍 in principle, but have not reviewed in detail. |
OK, added a second commit which also changes the kwarg names on the Axes methods. |
eb37584
to
dee07b2
Compare
Codecov Report
@@ Coverage Diff @@
## master #14916 +/- ##
==========================================
- Coverage 80.85% 80.46% -0.39%
==========================================
Files 307 307
Lines 75746 74412 -1334
Branches 9691 9695 +4
==========================================
- Hits 61244 59876 -1368
- Misses 11962 11988 +26
- Partials 2540 2548 +8
Continue to review full report at Codecov.
|
- Make names of kwargs to Scale subclasses independent of whether the underlying axis is x or y (so that after the deprecation period, one can just have a normal signature -- `def __init__(self, *, base=10, ...)`. We could possibly also change semilogx and semilogy to use the unsuffixed names (with deprecation), leaving only loglog with the suffixed names, or even also make loglog use unsuffixed names, in which case it would become impossible to set separate x and y bases directly in loglog -- one should then do `gca().set_xscale("log", base=...)` which doesn't seem too onerous. (loglog is the only case where the suffixed names has *some* utility.) In general, note that having kwargs that depend on the axis direction doesn't really scale -- for example, if we were to finally add log-scale support to mplot3d, should scale.py know about it and add `basez`? Should we have `baser` for log-scale polar plots? (at least in the radial direction, they make sense) - Move argument validation up the the Transform subclasses. - Make SymmetricalLogScale.{base,linthresh,linscale} properties mapping to the underlying transform so that they can't go out of sync.
rebased |
dee07b2
to
82ee63e
Compare
before this gets merged please comment on @timhoffm's suggestion to switch |
It's a modest difference, but I agree that "nonpositive='clip'" reads better than "nonpos='clip'". I'm guessing the kwarg (the plain version, not "nonposx" etc.) is not widely used, so the additional irritation will be moderate. |
82ee63e
to
ea57339
Compare
I'm still happy with this. @efiring if you are OK can you merge? |
Make names of kwargs to Scale subclasses independent of whether the
underlying axis is x or y (so that after the deprecation period, one
can just have a normal signature --
def __init__(self, *, base=10, ...)
.We could possibly also change semilogx and semilogy to use the
unsuffixed names (with deprecation), leaving only loglog with the
suffixed names, or even also make loglog use unsuffixed names, in
which case it would become impossible to set separate x and y bases
directly in loglog -- one should then do
gca().set_xscale("log", base=...)
which doesn't seem too onerous. (loglog is the only casewhere the suffixed names has some utility.)
EDIT: see Make kwargs names in scale.py not include the axis direction. #14916 (comment).
In general, note that having kwargs that depend on the axis direction
doesn't really scale -- for example, if we were to finally add
log-scale support to mplot3d, should scale.py know about it and add
basez
? Should we havebaser
for log-scale polar plots? (at leastin the radial direction, they make sense)
Move argument validation up the the Transform subclasses.
Make SymmetricalLogScale.{base,linthresh,linscale} properties
mapping to the underlying transform so that they can't go out of sync.
As discussed with @tacaswell during the dev call.
PR Summary
PR Checklist