Skip to content

Commit c22cac0

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 ensuring that the test for negative values is stored in an array of the same type as the error (i.e., a masked array if needed), so that the test value is 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 c22cac0

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

lib/matplotlib/axes/_axes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3756,7 +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
3759+
res = np.zeros_like(err, dtype=bool) # Default in case of nan
37603760
if np.any(np.less(err, -err, out=res, where=(err == err))):
37613761
# like err<0, but also works for timedelta and nan.
37623762
raise ValueError(

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)