Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4507a59

Browse files
jcalberttimhoffm
authored andcommitted
Added ability to offset errorbars when using errorevery. (#6280)
* Added ability to offset errorbars with errorevery 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. * modified errorbar_subsample example to demonstrate feature * tests to check functionality using check_figures_equal decorator * document new features * style compliance fixes * fixed example to match behavior for two-tuple arguments * moved what's new to new what's new * proper length heading line for .rst * unpacked and named y, yerr, and axs (previously iterables) for clarity. * moved error message into ValueError made 2-argument errorevery give a more accurate error message * tiny flake8 change
1 parent 2753cf5 commit 4507a59

File tree

4 files changed

+69
-17
lines changed

4 files changed

+69
-17
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Errorbar plots can shift which points have error bars
2+
-----------------------------------------------------
3+
4+
Previously, `plt.errorbar()` accepted a kwarg `errorevery` such that the
5+
command `plt.errorbar(x, y, yerr, errorevery=6)` would add error bars to
6+
datapoints `x[::6], y[::6]`.
7+
8+
`errorbar()` now also accepts a tuple for `errorevery` such that
9+
`plt.errorbar(x, y, yerr, errorevery=(start, N))` adds error bars to points
10+
`x[start::N], y[start::N]`.

examples/lines_bars_and_markers/errorbar_subsample.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,29 @@
1212

1313
# example data
1414
x = np.arange(0.1, 4, 0.1)
15-
y = np.exp(-x)
15+
y1 = np.exp(-1.0 * x)
16+
y2 = np.exp(-0.5 * x)
1617

1718
# example variable error bar values
18-
yerr = 0.1 + 0.1 * np.sqrt(x)
19+
y1err = 0.1 + 0.1 * np.sqrt(x)
20+
y2err = 0.1 + 0.1 * np.sqrt(x/2)
1921

2022

2123
# Now switch to a more OO interface to exercise more features.
22-
fig, axs = plt.subplots(nrows=1, ncols=2, sharex=True)
23-
ax = axs[0]
24-
ax.errorbar(x, y, yerr=yerr)
25-
ax.set_title('all errorbars')
24+
fig, (ax_l, ax_c, ax_r) = plt.subplots(nrows=1, ncols=3,
25+
sharex=True, figsize=(12, 6))
2626

27-
ax = axs[1]
28-
ax.errorbar(x, y, yerr=yerr, errorevery=5)
29-
ax.set_title('only every 5th errorbar')
27+
ax_l.set_title('all errorbars')
28+
ax_l.errorbar(x, y1, yerr=y1err)
29+
ax_l.errorbar(x, y2, yerr=y2err)
3030

31+
ax_c.set_title('only every 6th errorbar')
32+
ax_c.errorbar(x, y1, yerr=y1err, errorevery=6)
33+
ax_c.errorbar(x, y2, yerr=y2err, errorevery=6)
3134

32-
fig.suptitle('Errorbar subsampling for better appearance')
35+
ax_r.set_title('second series shifted by 3')
36+
ax_r.errorbar(x, y1, yerr=y1err, errorevery=(0, 6))
37+
ax_r.errorbar(x, y2, yerr=y2err, errorevery=(3, 6))
3338

39+
fig.suptitle('Errorbar subsampling for better appearance')
3440
plt.show()

lib/matplotlib/axes/_axes.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3151,10 +3151,14 @@ def errorbar(self, x, y, yerr=None, xerr=None,
31513151
and *yerr*. To use limits with inverted axes, :meth:`set_xlim`
31523152
or :meth:`set_ylim` must be called before :meth:`errorbar`.
31533153
3154-
errorevery : positive integer, optional, default: 1
3155-
Subsamples the errorbars. e.g., if errorevery=5, errorbars for
3156-
every 5-th datapoint will be plotted. The data plot itself still
3157-
shows all data points.
3154+
errorevery : int or (int, int), optional, default: 1
3155+
draws error bars on a subset of the data. *errorevery* =N draws
3156+
error bars on the points (x[::N], y[::N]).
3157+
*errorevery* =(start, N) draws error bars on the points
3158+
(x[start::N], y[start::N]). e.g. errorevery=(6, 3)
3159+
adds error bars to the data at (x[6], x[9], x[12], x[15], ...).
3160+
Used to avoid overlapping error bars when two series share x-axis
3161+
values.
31583162
31593163
Returns
31603164
-------
@@ -3199,9 +3203,17 @@ def errorbar(self, x, y, yerr=None, xerr=None,
31993203
kwargs = {k: v for k, v in kwargs.items() if v is not None}
32003204
kwargs.setdefault('zorder', 2)
32013205

3202-
if errorevery < 1:
3206+
try:
3207+
offset, errorevery = errorevery
3208+
except TypeError:
3209+
offset = 0
3210+
3211+
if errorevery < 1 or int(errorevery) != errorevery:
3212+
raise ValueError(
3213+
'errorevery must be positive integer or tuple of integers')
3214+
if int(offset) != offset:
32033215
raise ValueError(
3204-
'errorevery has to be a strictly positive integer')
3216+
'errorevery\'s starting index must be an integer')
32053217

32063218
self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
32073219

@@ -3310,7 +3322,8 @@ def errorbar(self, x, y, yerr=None, xerr=None,
33103322
xlolims = np.broadcast_to(xlolims, len(x)).astype(bool)
33113323
xuplims = np.broadcast_to(xuplims, len(x)).astype(bool)
33123324

3313-
everymask = np.arange(len(x)) % errorevery == 0
3325+
everymask = np.zeros(len(x), bool)
3326+
everymask[offset::errorevery] = True
33143327

33153328
def xywhere(xs, ys, mask):
33163329
"""

lib/matplotlib/tests/test_axes.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2945,6 +2945,29 @@ def test_errorbar_with_prop_cycle():
29452945
ax.errorbar(x=[2, 4, 10], y=[6, 4, 2], yerr=0.5)
29462946

29472947

2948+
@check_figures_equal()
2949+
def test_errorbar_offsets(fig_test, fig_ref):
2950+
x = np.linspace(0, 1, 15)
2951+
y = x * (1-x)
2952+
yerr = y/6
2953+
2954+
ax_ref = fig_ref.subplots()
2955+
ax_test = fig_test.subplots()
2956+
2957+
for color, shift in zip('rgbk', [0, 0, 2, 7]):
2958+
y += .02
2959+
2960+
# Using feature in question
2961+
ax_test.errorbar(x, y, yerr, errorevery=(shift, 4),
2962+
capsize=4, c=color)
2963+
2964+
# Using manual errorbars
2965+
# n.b. errorbar draws the main plot at z=2.1 by default
2966+
ax_ref.plot(x, y, c=color, zorder=2.1)
2967+
ax_ref.errorbar(x[shift::4], y[shift::4], yerr[shift::4],
2968+
capsize=4, c=color, fmt='none')
2969+
2970+
29482971
@image_comparison(baseline_images=['hist_stacked_stepfilled',
29492972
'hist_stacked_stepfilled'])
29502973
def test_hist_stacked_stepfilled():

0 commit comments

Comments
 (0)