-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Added ability to offset errorbars when using errorevery. #6280
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
lib/matplotlib/axes/_axes.py
Outdated
if not iterable(errorevery): | ||
errorevery = (errorevery, 0) | ||
try: | ||
assert all(int(x)==x for x in errorevery) |
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 while ago we cleaned all of the asserts out of the main code base and use a if ... raise
pattern.
👍 I like the idea, just left some code-style comments. Can you also add a test (just a png image comparison should be enough) and a |
Done - is there any documentation / examples I should do? |
👍 Looks good to me. If you want to update the mark-every examples in the gallery that would be good. |
lib/matplotlib/axes/_axes.py
Outdated
subsamples the errorbars. e.g., if errorevery=5, errorbars for | ||
every 5-th datapoint will be plotted. The data plot itself still | ||
shows all data points. | ||
every 5-th datapoint will be plotted. If errorevery=(a,b), points |
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.
Missing space after comma in tuple.
In an earlier revision, I had validation of the sort which ensured
.... Regarding @QuLogic 's note: Personally, I prefer
|
Sometimes I make bad suggestions 🐑
|
That should be |
Hm, not sure how I broke |
(My bad, I didn't realize "Close and comment" closed the issue) |
That test is known to be flaky, but no one has been able to reproduce it reliably to debug it. We are pretty sure it is an artifact of running nose in parallel + not perfectly isolated tests. |
This looks like a cool new feature! @jcalbert could you rebase this on to the current master branch, and then I'll have a look at it in detail? |
@dstansby Alright, it's going to take me a second to learn |
Sorry this got lost in the weeds 😞 |
power-cycled to re-run CI. This looks like a very useful feature (that got a lot of discussion), however from skimming the discussion it looks like there are still outstanding issues with the API being inconsistent with the API of |
IIRC, I think it was getting mysteriously snagged on one of the CI tests but I don't know how to go back and check old results. I think we settled on having errorevery support a subset of the functionality of markevery, but that subset is consistent. I'll rebase and fix one style issue "(6,3)" -> "(6, 3)" tomorrow |
4523509
to
9fd0233
Compare
Should be good now. |
@@ -0,0 +1,10 @@ | |||
Errorbar plots can shift which points have error bars | |||
---------------------- |
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 decorator should be the same length as the title.
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.
modulo moving the whats_new file to next_whats_new
Thanks for sticking with this for so long! |
|
||
|
||
# Now switch to a more OO interface to exercise more features. | ||
fig, axs = plt.subplots(nrows=1, ncols=2, sharex=True) | ||
fig, axs = plt.subplots(nrows=1, ncols=3, sharex=True, figsize=(12, 6)) |
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.
fig, axs = plt.subplots(nrows=1, ncols=3, sharex=True, figsize=(12, 6)) | |
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=3, sharex=True, figsize=(12, 6)) |
and using ax1
, ax2
below is better than reassigning ax = ax[i]
later.
@@ -12,22 +12,29 @@ | |||
|
|||
# example data | |||
x = np.arange(0.1, 4, 0.1) | |||
y = np.exp(-x) | |||
y = np.exp(np.vstack([-1.0 * x, -.5 * x])) |
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 think, it's easier to follow if you keep the data in two separate variables:
y1 = np.exp(-x)
y2 = np.exp(-0.5 * x)
|
||
# example variable error bar values | ||
yerr = 0.1 + 0.1 * np.sqrt(x) | ||
yerr = 0.1 + 0.1 * np.sqrt(np.vstack([x, x/2])) |
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 with y1err
, y2err
.
ax = axs[0] | ||
ax.errorbar(x, y, yerr=yerr) | ||
for i in range(2): | ||
ax.errorbar(x, y[i], yerr=yerr[i]) |
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.
With above changes simpler:
ax1.errorbar(x, y1, yerr=y1err)
ax1.errorbar(x, y2, yerr=y2err)
Same for the following for loops.
lib/matplotlib/axes/_axes.py
Outdated
except TypeError: | ||
offset = 0 | ||
|
||
int_msg = 'errorevery must be positive integer or tuple of integers' |
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.
It's more readable to define the message directly in the context of the ValueError
. Also, this allows to make the error message more specific.
if errorevery < 1 or int(errorevery) != errorevery:
raise ValueError(
'errorevery must be positive integer or tuple of integers')
if int(offset) != offset:
raise ValueError('errorevery offset must be an integer >= 0')
Added @timhoffm 's suggestions, fixed what's new. |
flake8 complains: Doc build is broken due to #14003 (unrelated to this PR). Can be fixed by rebasing. |
In addition to adding errorbars on a subset of data points one may add them to (2, 5, 8...) rather than (0, 3, 6...) to avoid overlaps.
made 2-argument errorevery give a more accurate error message
718522c
to
2bfcf8c
Compare
Thanks a lot for keeping at this! I think this is PR with the longest history I've merged into matplotlib. Anyway, glad that it's in 🎉. Hope to see you back some time. |
I was having a problem where errorbars for different series would perfectly overlap, as shown in the top plot:
I added the ability to specify the
errorevery
such thatplt.errorbar(x,y,yerr, errorevery=7)
still adds error bars to the 1st, 8th, 15th ... data points butplt.errorbar(x,y,yerr, errorevery=(7,3))
adds error bars to the 3rd, 10th, 17th ... points.I apologize if I'm violating some protocol - I haven't contributed to a project like this before.
P.S. The plot above was generated by: