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

Skip to content

Commit ae1edf8

Browse files
committed
BUG: ensure that errorbar does not error on masked negative errors.
errorbar checks that errors are not negative, but a bit convolutedly, in order to avoid triggering on nan. Unfortunately, the work-around for nan means that possible masks get discarded, and hence passing in a masked error array that has a negative but masked value leads to an exception. This PR solves that by simply combining the test for negative values with the indirect isnan test (err == err), so that if a masked array is passed, the test values are masked and ignored in the check. As a bonus, this also means that astropy's ``Masked`` arrays can now be used -- those refuse to write output of tests to unmasked values since that would discard the mask (which is indeed the underlying problem here).
1 parent d55bdde commit ae1edf8

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

lib/matplotlib/axes/_axes.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3756,8 +3756,7 @@ def apply_mask(arrays, mask):
37563756
f"'{dep_axis}err' must not contain None. "
37573757
"Use NaN if you want to skip a value.")
37583758

3759-
res = np.zeros(err.shape, dtype=bool) # Default in case of nan
3760-
if np.any(np.less(err, -err, out=res, where=(err == err))):
3759+
if np.any((err < -err) & (err == err)):
37613760
# like err<0, but also works for timedelta and nan.
37623761
raise ValueError(
37633762
f"'{dep_axis}err' must not contain negative values")

lib/matplotlib/tests/test_axes.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4538,6 +4538,19 @@ def test_errorbar_nan(fig_test, fig_ref):
45384538
ax.errorbar([4], [3], [6], fmt="C0")
45394539

45404540

4541+
@check_figures_equal()
4542+
def test_errorbar_masked_negative(fig_test, fig_ref):
4543+
ax = fig_test.add_subplot()
4544+
xs = range(5)
4545+
mask = np.array([False, False, True, True, False])
4546+
ys = np.ma.array([1, 2, 2, 2, 3], mask=mask)
4547+
es = np.ma.array([4, 5, -1, -10, 6], mask=mask)
4548+
ax.errorbar(xs, ys, es)
4549+
ax = fig_ref.add_subplot()
4550+
ax.errorbar([0, 1], [1, 2], [4, 5])
4551+
ax.errorbar([4], [3], [6], fmt="C0")
4552+
4553+
45414554
@image_comparison(['hist_stacked_stepfilled.png', 'hist_stacked_stepfilled.png'])
45424555
def test_hist_stacked_stepfilled():
45434556
# make some data

0 commit comments

Comments
 (0)