Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9113e53

Browse filesBrowse files
committed
Factor out x/y lo/hi handling in errorbar.
1 parent 183018c commit 9113e53
Copy full SHA for 9113e53

File tree

Expand file treeCollapse file tree

1 file changed

+50
-100
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+50
-100
lines changed

‎lib/matplotlib/axes/_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_axes.py
+50-100Lines changed: 50 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -3398,116 +3398,66 @@ def errorbar(self, x, y, yerr=None, xerr=None,
33983398
barcols = []
33993399
caplines = []
34003400

3401-
# arrays fine here, they are booleans and hence not units
3402-
lolims = np.broadcast_to(lolims, len(x)).astype(bool)
3403-
uplims = np.broadcast_to(uplims, len(x)).astype(bool)
3404-
xlolims = np.broadcast_to(xlolims, len(x)).astype(bool)
3405-
xuplims = np.broadcast_to(xuplims, len(x)).astype(bool)
3406-
34073401
# Vectorized fancy-indexer.
34083402
def apply_mask(arrays, mask): return [array[mask] for array in arrays]
34093403

3410-
def extract_err(name, err, data, lolims, uplims):
3411-
"""
3412-
Private function to compute error bars.
3413-
3414-
Parameters
3415-
----------
3416-
name : {'x', 'y'}
3417-
Name used in the error message.
3418-
err : array-like
3419-
xerr or yerr from errorbar().
3420-
data : array-like
3421-
x or y from errorbar().
3422-
lolims : array-like
3423-
Error is only applied on **upper** side when this is True. See
3424-
the note in the main docstring about this parameter's name.
3425-
uplims : array-like
3426-
Error is only applied on **lower** side when this is True. See
3427-
the note in the main docstring about this parameter's name.
3428-
"""
3404+
# dep: dependent dataset, indep: independent dataset
3405+
for (dep_axis, dep, err, lolims, uplims, indep, lines_func,
3406+
marker, lomarker, himarker) in [
3407+
("x", x, xerr, xlolims, xuplims, y, self.hlines,
3408+
"|", mlines.CARETRIGHTBASE, mlines.CARETLEFTBASE),
3409+
("y", y, yerr, lolims, uplims, x, self.vlines,
3410+
"_", mlines.CARETUPBASE, mlines.CARETDOWNBASE),
3411+
]:
3412+
if err is None:
3413+
continue
3414+
lolims = np.broadcast_to(lolims, len(dep)).astype(bool)
3415+
uplims = np.broadcast_to(uplims, len(dep)).astype(bool)
34293416
try:
3430-
np.broadcast_to(err, (2, len(data)))
3417+
np.broadcast_to(err, (2, len(dep)))
34313418
except ValueError:
34323419
raise ValueError(
3433-
f"'{name}err' (shape: {np.shape(err)}) must be a scalar "
3434-
f"or a 1D or (2, n) array-like whose shape matches "
3435-
f"'{name}' (shape: {np.shape(data)})") from None
3420+
f"'{dep_axis}err' (shape: {np.shape(err)}) must be a "
3421+
f"scalar or a 1D or (2, n) array-like whose shape matches "
3422+
f"'{dep_axis}' (shape: {np.shape(dep)})") from None
34363423
# This is like
3437-
# low, high = np.broadcast_to(...)
3438-
# return data - low * ~lolims, data + high * ~uplims
3424+
# elow, ehigh = np.broadcast_to(...)
3425+
# return dep - elow * ~lolims, dep + ehigh * ~uplims
34393426
# except that broadcast_to would strip units.
3440-
return data + np.row_stack([-(1 - lolims), 1 - uplims]) * err
3441-
3442-
if xerr is not None:
3443-
left, right = extract_err('x', xerr, x, xlolims, xuplims)
3444-
barcols.append(self.hlines(
3445-
*apply_mask([y, left, right], everymask), **eb_lines_style))
3446-
# select points without upper/lower limits in x and
3447-
# draw normal errorbars for these points
3448-
noxlims = ~(xlolims | xuplims)
3449-
if noxlims.any() and capsize > 0:
3450-
yo, lo, ro = apply_mask([y, left, right], noxlims & everymask)
3451-
caplines.extend([
3452-
mlines.Line2D(lo, yo, marker='|', **eb_cap_style),
3453-
mlines.Line2D(ro, yo, marker='|', **eb_cap_style)])
3454-
if xlolims.any():
3455-
xo, yo, ro = apply_mask([x, y, right], xlolims & everymask)
3456-
if self.xaxis_inverted():
3457-
marker = mlines.CARETLEFTBASE
3458-
else:
3459-
marker = mlines.CARETRIGHTBASE
3460-
caplines.append(mlines.Line2D(
3461-
ro, yo, ls='None', marker=marker, **eb_cap_style))
3462-
if capsize > 0:
3463-
caplines.append(mlines.Line2D(
3464-
xo, yo, marker='|', **eb_cap_style))
3465-
if xuplims.any():
3466-
xo, yo, lo = apply_mask([x, y, left], xuplims & everymask)
3467-
if self.xaxis_inverted():
3468-
marker = mlines.CARETRIGHTBASE
3469-
else:
3470-
marker = mlines.CARETLEFTBASE
3471-
caplines.append(mlines.Line2D(
3472-
lo, yo, ls='None', marker=marker, **eb_cap_style))
3473-
if capsize > 0:
3474-
caplines.append(mlines.Line2D(
3475-
xo, yo, marker='|', **eb_cap_style))
3476-
3477-
if yerr is not None:
3478-
lower, upper = extract_err('y', yerr, y, lolims, uplims)
3479-
barcols.append(self.vlines(
3480-
*apply_mask([x, lower, upper], everymask), **eb_lines_style))
3481-
# select points without upper/lower limits in y and
3482-
# draw normal errorbars for these points
3483-
noylims = ~(lolims | uplims)
3484-
if noylims.any() and capsize > 0:
3485-
xo, lo, uo = apply_mask([x, lower, upper], noylims & everymask)
3486-
caplines.extend([
3487-
mlines.Line2D(xo, lo, marker='_', **eb_cap_style),
3488-
mlines.Line2D(xo, uo, marker='_', **eb_cap_style)])
3489-
if lolims.any():
3490-
xo, yo, uo = apply_mask([x, y, upper], lolims & everymask)
3491-
if self.yaxis_inverted():
3492-
marker = mlines.CARETDOWNBASE
3493-
else:
3494-
marker = mlines.CARETUPBASE
3495-
caplines.append(mlines.Line2D(
3496-
xo, uo, ls='None', marker=marker, **eb_cap_style))
3497-
if capsize > 0:
3498-
caplines.append(mlines.Line2D(
3499-
xo, yo, marker='_', **eb_cap_style))
3500-
if uplims.any():
3501-
xo, yo, lo = apply_mask([x, y, lower], uplims & everymask)
3502-
if self.yaxis_inverted():
3503-
marker = mlines.CARETUPBASE
3504-
else:
3505-
marker = mlines.CARETDOWNBASE
3506-
caplines.append(mlines.Line2D(
3507-
xo, lo, ls='None', marker=marker, **eb_cap_style))
3427+
low, high = dep + np.row_stack([-(1 - lolims), 1 - uplims]) * err
3428+
3429+
barcols.append(lines_func(
3430+
*apply_mask([indep, low, high], everymask), **eb_lines_style))
3431+
# Normal errorbars for points without upper/lower limits.
3432+
nolims = ~(lolims | uplims)
3433+
if nolims.any() and capsize > 0:
3434+
indep_masked, lo_masked, hi_masked = apply_mask(
3435+
[indep, low, high], nolims & everymask)
3436+
for lh_masked in [lo_masked, hi_masked]:
3437+
# Since this has to work for x and y as dependent data, we
3438+
# first set both x and y to the independent variable and
3439+
# overwrite the respective dependent data in a second step.
3440+
line = mlines.Line2D(indep_masked, indep_masked,
3441+
marker=marker, **eb_cap_style)
3442+
line.set(**{f"{dep_axis}data": lh_masked})
3443+
caplines.append(line)
3444+
for idx, (lims, hl) in enumerate([(lolims, high), (uplims, low)]):
3445+
if not lims.any():
3446+
continue
3447+
hlmarker = (
3448+
himarker
3449+
if getattr(self, f"{dep_axis}axis").get_inverted() ^ idx
3450+
else lomarker)
3451+
x_masked, y_masked, hl_masked = apply_mask(
3452+
[x, y, hl], lims & everymask)
3453+
# As above, we set the dependent data in a second step.
3454+
line = mlines.Line2D(x_masked, y_masked,
3455+
marker=hlmarker, **eb_cap_style)
3456+
line.set(**{f"{dep_axis}data": hl_masked})
3457+
caplines.append(line)
35083458
if capsize > 0:
35093459
caplines.append(mlines.Line2D(
3510-
xo, yo, marker='_', **eb_cap_style))
3460+
x_masked, y_masked, marker=marker, **eb_cap_style))
35113461

35123462
for l in caplines:
35133463
self.add_line(l)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.