From ab7831895dda1cfdc2ef0f408b9e3b4aaf5b54a1 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Tue, 9 Aug 2022 16:03:17 -0400 Subject: [PATCH] Backport PR #23549: Don't clip colorbar dividers --- lib/matplotlib/colorbar.py | 35 +++++++-- .../test_colorbar/extend_drawedges.png | Bin 0 -> 16748 bytes lib/matplotlib/tests/test_colorbar.py | 67 ++++++++++++------ 3 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 lib/matplotlib/tests/baseline_images/test_colorbar/extend_drawedges.png diff --git a/lib/matplotlib/colorbar.py b/lib/matplotlib/colorbar.py index f53d5f8f16ec..554db1b52497 100644 --- a/lib/matplotlib/colorbar.py +++ b/lib/matplotlib/colorbar.py @@ -467,7 +467,8 @@ def __init__(self, ax, mappable=None, *, cmap=None, self.dividers = collections.LineCollection( [], colors=[mpl.rcParams['axes.edgecolor']], - linewidths=[0.5 * mpl.rcParams['axes.linewidth']]) + linewidths=[0.5 * mpl.rcParams['axes.linewidth']], + clip_on=False) self.ax.add_collection(self.dividers) self.locator = None @@ -627,12 +628,31 @@ def _add_solids(self, X, Y, C): if not self.drawedges: if len(self._y) >= self.n_rasterize: self.solids.set_rasterized(True) - if self.drawedges: - start_idx = 0 if self._extend_lower() else 1 - end_idx = len(X) if self._extend_upper() else -1 - self.dividers.set_segments(np.dstack([X, Y])[start_idx:end_idx]) - else: + self._update_dividers() + + def _update_dividers(self): + if not self.drawedges: self.dividers.set_segments([]) + return + # Place all *internal* dividers. + if self.orientation == 'vertical': + lims = self.ax.get_ylim() + bounds = (lims[0] < self._y) & (self._y < lims[1]) + else: + lims = self.ax.get_xlim() + bounds = (lims[0] < self._y) & (self._y < lims[1]) + y = self._y[bounds] + # And then add outer dividers if extensions are on. + if self._extend_lower(): + y = np.insert(y, 0, lims[0]) + if self._extend_upper(): + y = np.append(y, lims[1]) + X, Y = np.meshgrid([0, 1], y) + if self.orientation == 'vertical': + segments = np.dstack([X, Y]) + else: + segments = np.dstack([Y, X]) + self.dividers.set_segments(segments) def _add_solids_patches(self, X, Y, C, mappable): hatches = mappable.hatches * len(C) # Have enough hatches. @@ -737,7 +757,8 @@ def _do_extends(self, ax=None): zorder=np.nextafter(self.ax.patch.zorder, -np.inf)) self.ax.add_patch(patch) self._extend_patches.append(patch) - return + + self._update_dividers() def add_lines(self, *args, **kwargs): """ diff --git a/lib/matplotlib/tests/baseline_images/test_colorbar/extend_drawedges.png b/lib/matplotlib/tests/baseline_images/test_colorbar/extend_drawedges.png new file mode 100644 index 0000000000000000000000000000000000000000..864eeefbae10c1d13a5e050777accff8eceb1da4 GIT binary patch literal 16748 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 Sqg&|fu~G`Rvv1yi^1lE!^I(7g literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index 8bbb738fee2b..f103fde7ee7f 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -929,28 +929,51 @@ def test_proportional_colorbars(): fig.colorbar(CS3, spacing=spacings[j], ax=axs[i, j]) -@pytest.mark.parametrize("extend, coloroffset, res", [ - ('both', 1, [np.array([[0., 0.], [0., 1.]]), - np.array([[1., 0.], [1., 1.]]), - np.array([[2., 0.], [2., 1.]])]), - ('min', 0, [np.array([[0., 0.], [0., 1.]]), - np.array([[1., 0.], [1., 1.]])]), - ('max', 0, [np.array([[1., 0.], [1., 1.]]), - np.array([[2., 0.], [2., 1.]])]), - ('neither', -1, [np.array([[1., 0.], [1., 1.]])]) - ]) -def test_colorbar_extend_drawedges(extend, coloroffset, res): - cmap = plt.get_cmap("viridis") - bounds = np.arange(3) - nb_colors = len(bounds) + coloroffset - colors = cmap(np.linspace(100, 255, nb_colors).astype(int)) - cmap, norm = mcolors.from_levels_and_colors(bounds, colors, extend=extend) - - plt.figure(figsize=(5, 1)) - ax = plt.subplot(111) - cbar = Colorbar(ax, cmap=cmap, norm=norm, orientation='horizontal', - drawedges=True) - assert np.all(np.equal(cbar.dividers.get_segments(), res)) +@image_comparison(['extend_drawedges.png'], remove_text=True, style='mpl20') +def test_colorbar_extend_drawedges(): + params = [ + ('both', 1, [[[1.1, 0], [1.1, 1]], + [[2, 0], [2, 1]], + [[2.9, 0], [2.9, 1]]]), + ('min', 0, [[[1.1, 0], [1.1, 1]], + [[2, 0], [2, 1]]]), + ('max', 0, [[[2, 0], [2, 1]], + [[2.9, 0], [2.9, 1]]]), + ('neither', -1, [[[2, 0], [2, 1]]]), + ] + + plt.rcParams['axes.linewidth'] = 2 + + fig = plt.figure(figsize=(10, 4)) + subfigs = fig.subfigures(1, 2) + + for orientation, subfig in zip(['horizontal', 'vertical'], subfigs): + if orientation == 'horizontal': + axs = subfig.subplots(4, 1) + else: + axs = subfig.subplots(1, 4) + fig.subplots_adjust(left=0.05, bottom=0.05, right=0.95, top=0.95) + + for ax, (extend, coloroffset, res) in zip(axs, params): + cmap = plt.get_cmap("viridis") + bounds = np.arange(5) + nb_colors = len(bounds) + coloroffset + colors = cmap(np.linspace(100, 255, nb_colors).astype(int)) + cmap, norm = mcolors.from_levels_and_colors(bounds, colors, + extend=extend) + + cbar = Colorbar(ax, cmap=cmap, norm=norm, orientation=orientation, + drawedges=True) + # Set limits such that only two colours are visible, and the + # dividers would be outside the Axes, to ensure that a) they are + # not drawn outside, and b) a divider still appears between the + # main colour and the extension. + if orientation == 'horizontal': + ax.set_xlim(1.1, 2.9) + else: + ax.set_ylim(1.1, 2.9) + res = np.array(res)[:, :, [1, 0]] + np.testing.assert_array_equal(cbar.dividers.get_segments(), res) def test_negative_boundarynorm():