| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent ecab6de commit c77fc36
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,4 @@ | |||
| 1 | + Fixed errorbars in polar plots | ||
| 2 | + ------------------------------ | ||
| 3 | + Caps and error lines are now drawn with respect to polar coordinates, | ||
| 4 | + when plotting errorbars on polar plots. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3522,10 +3522,11 @@ def _upcast_err(err): | |||
| 3522 | 3522 | eb_cap_style['color'] = ecolor | |
| 3523 | 3523 | ||
| 3524 | 3524 | barcols = [] | |
| 3525 | - caplines = [] | ||
| 3525 | + caplines = {'x': [], 'y': []} | ||
| 3526 | 3526 | ||
| 3527 | 3527 | # Vectorized fancy-indexer. | |
| 3528 | - def apply_mask(arrays, mask): return [array[mask] for array in arrays] | ||
| 3528 | + def apply_mask(arrays, mask): | ||
| 3529 | + return [array[mask] for array in arrays] | ||
| 3529 | 3530 | ||
| 3530 | 3531 | # dep: dependent dataset, indep: independent dataset | |
| 3531 | 3532 | for (dep_axis, dep, err, lolims, uplims, indep, lines_func, | |
@@ -3556,9 +3557,12 @@ def apply_mask(arrays, mask): return [array[mask] for array in arrays] | |||
| 3556 | 3557 | # return dep - elow * ~lolims, dep + ehigh * ~uplims | |
| 3557 | 3558 | # except that broadcast_to would strip units. | |
| 3558 | 3559 | low, high = dep + np.row_stack([-(1 - lolims), 1 - uplims]) * err | |
| 3559 | - | ||
| 3560 | 3560 | barcols.append(lines_func( | |
| 3561 | 3561 | *apply_mask([indep, low, high], everymask), **eb_lines_style)) | |
| 3562 | + if self.name == "polar" and dep_axis == "x": | ||
| 3563 | + for b in barcols: | ||
| 3564 | + for p in b.get_paths(): | ||
| 3565 | + p._interpolation_steps = 2 | ||
| 3562 | 3566 | # Normal errorbars for points without upper/lower limits. | |
| 3563 | 3567 | nolims = ~(lolims | uplims) | |
| 3564 | 3568 | if nolims.any() and capsize > 0: | |
@@ -3571,7 +3575,7 @@ def apply_mask(arrays, mask): return [array[mask] for array in arrays] | |||
| 3571 | 3575 | line = mlines.Line2D(indep_masked, indep_masked, | |
| 3572 | 3576 | marker=marker, **eb_cap_style) | |
| 3573 | 3577 | line.set(**{f"{dep_axis}data": lh_masked}) | |
| 3574 | - caplines.append(line) | ||
| 3578 | + caplines[dep_axis].append(line) | ||
| 3575 | 3579 | for idx, (lims, hl) in enumerate([(lolims, high), (uplims, low)]): | |
| 3576 | 3580 | if not lims.any(): | |
| 3577 | 3581 | continue | |
@@ -3585,15 +3589,29 @@ def apply_mask(arrays, mask): return [array[mask] for array in arrays] | |||
| 3585 | 3589 | line = mlines.Line2D(x_masked, y_masked, | |
| 3586 | 3590 | marker=hlmarker, **eb_cap_style) | |
| 3587 | 3591 | line.set(**{f"{dep_axis}data": hl_masked}) | |
| 3588 | - caplines.append(line) | ||
| 3592 | + caplines[dep_axis].append(line) | ||
| 3589 | 3593 | if capsize > 0: | |
| 3590 | - caplines.append(mlines.Line2D( | ||
| 3594 | + caplines[dep_axis].append(mlines.Line2D( | ||
| 3591 | 3595 | x_masked, y_masked, marker=marker, **eb_cap_style)) | |
| 3592 | - | ||
| 3593 | - for l in caplines: | ||
| 3594 | - self.add_line(l) | ||
| 3596 | + if self.name == 'polar': | ||
| 3597 | + for axis in caplines: | ||
| 3598 | + for l in caplines[axis]: | ||
| 3599 | + # Rotate caps to be perpendicular to the error bars | ||
| 3600 | + for theta, r in zip(l.get_xdata(), l.get_ydata()): | ||
| 3601 | + rotation = mtransforms.Affine2D().rotate(theta) | ||
| 3602 | + if axis == 'y': | ||
| 3603 | + rotation.rotate(-np.pi / 2) | ||
| 3604 | + ms = mmarkers.MarkerStyle(marker=marker, | ||
| 3605 | + transform=rotation) | ||
| 3606 | + self.add_line(mlines.Line2D([theta], [r], marker=ms, | ||
| 3607 | + **eb_cap_style)) | ||
| 3608 | + else: | ||
| 3609 | + for axis in caplines: | ||
| 3610 | + for l in caplines[axis]: | ||
| 3611 | + self.add_line(l) | ||
| 3595 | 3612 | ||
| 3596 | 3613 | self._request_autoscale_view() | |
| 3614 | + caplines = caplines['x'] + caplines['y'] | ||
| 3597 | 3615 | errorbar_container = ErrorbarContainer( | |
| 3598 | 3616 | (data_line, tuple(caplines), tuple(barcols)), | |
| 3599 | 3617 | has_xerr=(xerr is not None), has_yerr=(yerr is not None), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3600,6 +3600,32 @@ def test_errorbar(): | |||
| 3600 | 3600 | ax.set_title("Simplest errorbars, 0.2 in x, 0.4 in y") | |
| 3601 | 3601 | ||
| 3602 | 3602 | ||
| 3603 | + @image_comparison(['mixed_errorbar_polar_caps'], extensions=['png'], | ||
| 3604 | + remove_text=True) | ||
| 3605 | + def test_mixed_errorbar_polar_caps(): | ||
| 3606 | + fig = plt.figure() | ||
| 3607 | + ax = plt.subplot(111, projection='polar') | ||
| 3608 | + theta = np.linspace(0, np.pi, 3, False) | ||
| 3609 | + r = [1.0]*3 | ||
| 3610 | + ax.errorbar(theta, r, xerr=0.35, yerr=0.2, fmt="o") | ||
| 3611 | + _long_errorbar_polar_caps(ax) | ||
| 3612 | + _asymmetric_polar_caps(ax) | ||
| 3613 | + | ||
| 3614 | + | ||
| 3615 | + def _long_errorbar_polar_caps(ax): | ||
| 3616 | + theta = np.linspace(0, 2 * np.pi, 2, False) + np.pi/2 | ||
| 3617 | + r = [1.8, 2.2] | ||
| 3618 | + ax.errorbar(theta, r, xerr=0.8 * np.pi, yerr=0.2, fmt="o") | ||
| 3619 | + | ||
| 3620 | + | ||
| 3621 | + def _asymmetric_polar_caps(ax): | ||
| 3622 | + theta = np.linspace(0, np.pi, 3, False) + np.pi | ||
| 3623 | + r = [1.0]*3 | ||
| 3624 | + xerr = [[.3, .3, .2], [.2, .3, .3]] | ||
| 3625 | + yerr = [[.35, .5, .5], [.5, .35, .5]] | ||
| 3626 | + ax.errorbar(theta, r, xerr=xerr, yerr=yerr, fmt="o") | ||
| 3627 | + | ||
| 3628 | + | ||
| 3603 | 3629 | def test_errorbar_colorcycle(): | |
| 3604 | 3630 | ||
| 3605 | 3631 | f, ax = plt.subplots() | |
| Back | FazBrowse Home | New Git URL |
0 commit comments