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

Skip to content

Commit 0eeef9a

Browse files
committed
Sync caps of errorbar3d with 2d.
There are a few differences that cause some image changes: * When both upper and lower limits are True, `errorbar3d` incorrectly used full errorbar length for them. They should both have 0 errorbar with the arrow-head cap. * The arrow-head cap should use `eb_cap_style`, not `eb_lines_style`. This meant that the capsize defaulted to 0, so this was made explicitly non-zero in the test. * The baseline of the triangle (bottom/top for caps above/below a line) in 2D is aligned with the end of the errorbar, *not* the tip of the triangle, so all quivers in 3D shifted outward to match. * The quiver would preferably not overlap the existing errorbar, which I've hopefully achieved by setting the length based on `capsize`, and using the above positioning. Consequently, `arrow_length_ratio` is no longer exposed.
1 parent 7ec93d7 commit 0eeef9a

File tree

4 files changed

+19
-37
lines changed

4 files changed

+19
-37
lines changed

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2995,7 +2995,7 @@ def errorbar(self, x, y, z, zerr=None, yerr=None, xerr=None, fmt='',
29952995
barsabove=False, errorevery=1, ecolor=None, elinewidth=None,
29962996
capsize=None, capthick=None, xlolims=False, xuplims=False,
29972997
ylolims=False, yuplims=False, zlolims=False, zuplims=False,
2998-
arrow_length_ratio=.4, **kwargs):
2998+
**kwargs):
29992999
"""
30003000
Plot lines and/or markers with errorbars around them.
30013001
@@ -3072,10 +3072,6 @@ def errorbar(self, x, y, z, zerr=None, yerr=None, xerr=None, fmt='',
30723072
Used to avoid overlapping error bars when two series share x-axis
30733073
values.
30743074
3075-
arrow_length_ratio : float, default: 0.4
3076-
Passed to :meth:`quiver`, the ratio of the arrow head with respect
3077-
to the quiver.
3078-
30793075
Returns
30803076
-------
30813077
errlines : list
@@ -3188,7 +3184,7 @@ def errorbar(self, x, y, z, zerr=None, yerr=None, xerr=None, fmt='',
31883184
eb_lines_style[key] = kwargs[key]
31893185

31903186
# Make the style dict for caps (the "hats").
3191-
eb_cap_style = {**base_style, 'linestyle': 'none'}
3187+
eb_cap_style = {**base_style, 'linestyle': 'None'}
31923188
if capsize is None:
31933189
capsize = rcParams["errorbar.capsize"]
31943190
if capsize > 0:
@@ -3217,14 +3213,8 @@ def _extract_errs(err, data, lomask, himask):
32173213
else:
32183214
low_err, high_err = err, err
32193215

3220-
# for compatibility with the 2d errorbar function, when both upper
3221-
# and lower limits specified, we need to draw the markers / line
3222-
common_mask = (lomask == himask) & everymask
3223-
_lomask = lomask | common_mask
3224-
_himask = himask | common_mask
3225-
3226-
lows = np.where(_lomask, data - low_err, data)
3227-
highs = np.where(_himask, data + high_err, data)
3216+
lows = np.where(lomask | ~everymask, data, data - low_err)
3217+
highs = np.where(himask | ~everymask, data, data + high_err)
32283218

32293219
return lows, highs
32303220

@@ -3259,18 +3249,16 @@ def _extract_errs(err, data, lomask, himask):
32593249
lolims = np.broadcast_to(lolims, len(data)).astype(bool)
32603250
uplims = np.broadcast_to(uplims, len(data)).astype(bool)
32613251

3262-
nolims = ~(lolims | uplims)
3263-
32643252
# a nested list structure that expands to (xl,xh),(yl,yh),(zl,zh),
32653253
# where x/y/z and l/h correspond to dimensions and low/high
32663254
# positions of errorbars in a dimension we're looping over
32673255
coorderr = [
3268-
_extract_errs(err * dir_vector[i], coord,
3269-
~lolims & everymask, ~uplims & everymask)
3256+
_extract_errs(err * dir_vector[i], coord, lolims, uplims)
32703257
for i, coord in enumerate([x, y, z])]
32713258
(xl, xh), (yl, yh), (zl, zh) = coorderr
32723259

32733260
# draws capmarkers - flat caps orthogonal to the error bars
3261+
nolims = ~(lolims | uplims)
32743262
if nolims.any() and capsize > 0:
32753263
lo_caps_xyz = _apply_mask([xl, yl, zl], nolims & everymask)
32763264
hi_caps_xyz = _apply_mask([xh, yh, zh], nolims & everymask)
@@ -3288,24 +3276,18 @@ def _extract_errs(err, data, lomask, himask):
32883276
caplines.append(cap_lo)
32893277
caplines.append(cap_hi)
32903278

3291-
if (lolims | uplims).any():
3292-
limits = [
3293-
_extract_errs(err*dir_vector[i], coord, uplims, lolims)
3294-
for i, coord in enumerate([x, y, z])]
3295-
3296-
(xlo, xup), (ylo, yup), (zlo, zup) = limits
3297-
lomask = lolims & everymask
3298-
upmask = uplims & everymask
3299-
lolims_xyz = np.array(_apply_mask([xlo, ylo, zlo], upmask))
3300-
uplims_xyz = np.array(_apply_mask([xup, yup, zup], lomask))
3301-
lo_xyz = np.array(_apply_mask([x, y, z], upmask))
3302-
up_xyz = np.array(_apply_mask([x, y, z], lomask))
3303-
x0, y0, z0 = np.concatenate([lo_xyz, up_xyz], axis=-1)
3304-
dx, dy, dz = np.concatenate([lolims_xyz - lo_xyz,
3305-
uplims_xyz - up_xyz], axis=-1)
3306-
self.quiver(x0, y0, z0, dx, dy, dz,
3307-
arrow_length_ratio=arrow_length_ratio,
3308-
**eb_lines_style)
3279+
markersize = eb_cap_style.pop('markersize',
3280+
rcParams['lines.markersize']) / 30
3281+
if lolims.any():
3282+
xh0, yh0, zh0 = _apply_mask([xh, yh, zh], lolims & everymask)
3283+
self.quiver(xh0, yh0, zh0, *dir_vector,
3284+
length=markersize, arrow_length_ratio=1,
3285+
**eb_cap_style)
3286+
if uplims.any():
3287+
xl0, yl0, zl0 = _apply_mask([xl, yl, zl], uplims & everymask)
3288+
self.quiver(xl0, yl0, zl0, *-dir_vector,
3289+
length=markersize, arrow_length_ratio=1,
3290+
**eb_cap_style)
33093291

33103292
errline = art3d.Line3DCollection(np.array(coorderr).T,
33113293
**eb_lines_style)

lib/mpl_toolkits/tests/test_mplot3d.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,7 @@ def test_errorbar3d_errorevery():
12161216
zlolims = (i % estep == 0) & (i // estep % 3 == 2)
12171217

12181218
ax.errorbar(x, y, z, 0.2, zuplims=zuplims, zlolims=zlolims,
1219-
errorevery=estep)
1219+
errorevery=estep, capsize=1)
12201220

12211221

12221222
@mpl3d_image_comparison(['errorbar3d.png'])

0 commit comments

Comments
 (0)