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
bar plot: in 2.0.0 bars not as given in the description, ie. first arg is not "left" but "center" #7954
Using bar, the first input argument is not used for the left edge of the bar, but rather the center, as if the kwarg align='center' was used. However, the desired behavior is obtained in both cases when using align = 'center' and align = 'edge'. Just when align is not specified, it should be 'edge' aligned which it is not.
My hunch is that this a documentation/naming convention oversight in the wake of the changes to the defaults.
IIRC, it was a bad user experience to align in the bars along the left edge (the previous default). So at some point, we added the align kwarg so that the left parameter could actually specify the center of the bars. At that point, we should have renamed left to x, but probably could not for backwards compatibility reasons.
Then with v2 we changed the default value of align to "center", but still did not update the symbol left to x.
I agree that left align was a poor user experience and I welcome the change to center being the default. I was just surprised to see the change in one of my scripts after updating to 2.0.0, in particular since the description did not reflect the obtained behavior.
I would suggest, though, to also make the same change to step, which, in 1.5.3, could be used somewhat interchangeably to bar, if none of the alignment options (align for bar and where for step) keywords were used. This is not the case anymore.
IIRC, it was a bad user experience to align in the bars along the left edge
Except that aligning bars along the center when using an axis with xscale='log' is a bit of a pain to deal with; you need to take the geometric mean of successive pairs edges.
Oh, never mind, you need to use arithmetic mean with xscale='log'. Gah. I don't really like this change (it's very weird when you're specifying widths so that you can get bars that butt up right next to each other) but at least I can use align='edge' and get the same behavior as before.
I also got hit by the doctring inconsistency (not by the change of default value, because I rarely use bar).
@tacaswell is it really impossible to rename the first argument from left to x and advertise this as delayed change part of the 2.0 release. Of course a solution is to add a warning further down in the docstring. It would be a good bandage, but it wouldn't fix for this terrible API inconsistency.
also as a different, but related, issue on the documentation of bar function: there is a data keyword argument in the signature which, I believe, is not documented.
The v2.0 change was not an API change release. It was a style change
release. All code as written before still works now. What *might* be
possible is to change that argument name, and then add support for a "left"
kwarg by checking **kwargs for that key. If it is there, we can emit a
deprecation message, and then assign its value over to the new renamed
argument. Presumedly, this situation can only happen if supplying all the
arguments via **kwargs. The only hiccup with this idea is that the new
positional arguments wouldn't be filled by this approach, so the function
call would fail...
perhaps my idea could inspire someone else for a path for deprecating these
badly named arguments?
No, the meaning didn't change in v2.0, the default value for `align`
changed. The meaning changed when the `align` feature was added. The
documentation was always wrong since then, and it became more apparent when
the defaults changed in v2.0.
Actually, upon further thought, we don't need to create signature objects; we can just do something like #6404 (comment). The advantage of using signature objects when using the #7966 decorator approach is that we can simulate positional-only args or even on Py2 keyword-only args, but if we're not using the decorator approach we may as well let the interpreter do the argument binding for us. So something like
def bar(*args, **kwargs):
matchers = [
(lambda x, height, width, bottom, **kwargs:
(x, height, width, bottom, kwargs)),
(lambda left, height, width, bottom, **kwargs:
(left, height, width, bottom, kwargs))]
for matcher in matchers:
try:
x, height, width, bottom, kwargs = matcher(*args, **kwargs)
except TypeError:
# This can only come from a no-match as there is no other logic in
# the matchers.
continue
else:
break
else:
raise TypeError("...") # We can even re-use the TypeError from the first match.
...
Activity
phobson commentedon Jan 26, 2017
My hunch is that this a documentation/naming convention oversight in the wake of the changes to the defaults.
IIRC, it was a bad user experience to align in the bars along the left edge (the previous default). So at some point, we added the
alignkwarg so that theleftparameter could actually specify the center of the bars. At that point, we should have renamedlefttox, but probably could not for backwards compatibility reasons.Then with v2 we changed the default value of
alignto "center", but still did not update the symbollefttox.I'm not sure what the best path forward is.
tacaswell commentedon Jan 26, 2017
This is definitely intended behavior. The docstring on
leftshould include a warning / comment on this.Unfortunately we can not re-name the first positional argument without breaking API, I think that is a wart we are stuck with.
t1nux commentedon Jan 27, 2017
I agree that left align was a poor user experience and I welcome the change to center being the default. I was just surprised to see the change in one of my scripts after updating to 2.0.0, in particular since the description did not reflect the obtained behavior.
I would suggest, though, to also make the same change to
step, which, in 1.5.3, could be used somewhat interchangeably tobar, if none of the alignment options (alignforbarandwhereforstep) keywords were used. This is not the case anymore.jason-s commentedon Mar 29, 2017
Except that aligning bars along the center when using an axis withxscale='log'is a bit of a pain to deal with; you need to take the geometric mean of successive pairs edges.Oh, never mind, you need to use arithmetic mean with
xscale='log'. Gah. I don't really like this change (it's very weird when you're specifying widths so that you can get bars that butt up right next to each other) but at least I can usealign='edge'and get the same behavior as before.pierre-haessig commentedon Apr 8, 2017
I also got hit by the doctring inconsistency (not by the change of default value, because I rarely use
bar).@tacaswell is it really impossible to rename the first argument from
lefttoxand advertise this as delayed change part of the 2.0 release. Of course a solution is to add a warning further down in the docstring. It would be a good bandage, but it wouldn't fix for this terrible API inconsistency.pierre-haessig commentedon Apr 8, 2017
also as a different, but related, issue on the documentation of
barfunction: there is adatakeyword argument in the signature which, I believe, is not documented.WeatherGod commentedon Apr 10, 2017
skjaeve commentedon Jul 17, 2017
@tacaswell
Isn't the API already broken if the meaning of a positional argument was changed?
WeatherGod commentedon Jul 17, 2017
tacaswell commentedon Jul 18, 2017
it is 'broken' in the sense that it is confusing not 'broken' in the sense that code will raise exceptions.
anntzer commentedon Jul 18, 2017
Still advertising #7966 as a way to fix the signature...
tacaswell commentedon Jul 25, 2017
The consensus on the phone call today is:
*args, **kwargsSignature.bindto try the current signature and(x, height, width=0.8, bottom=None, **kwargs)and(left, hegiht, width=0.8, bottom=None, **kwargs)anntzer commentedon Jul 25, 2017
Actually, upon further thought, we don't need to create signature objects; we can just do something like #6404 (comment). The advantage of using signature objects when using the #7966 decorator approach is that we can simulate positional-only args or even on Py2 keyword-only args, but if we're not using the decorator approach we may as well let the interpreter do the argument binding for us. So something like
API: change signature of bar and barh
API: change signature of bar and barh
API: change signature of bar and barh
API: change signature of bar and barh