From f41edb62de216d76121be1be1828e1752fdc5c59 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Sat, 4 Sep 2021 10:41:03 +0200 Subject: [PATCH] FIX: colorbar with boundary norm, proportional, extend --- lib/matplotlib/colorbar.py | 5 ++-- .../test_colorbar/proportional_colorbars.png | Bin 0 -> 11329 bytes lib/matplotlib/tests/test_colorbar.py | 27 ++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 lib/matplotlib/tests/baseline_images/test_colorbar/proportional_colorbars.png diff --git a/lib/matplotlib/colorbar.py b/lib/matplotlib/colorbar.py index 9d40ac8e5e9c..d826649af167 100644 --- a/lib/matplotlib/colorbar.py +++ b/lib/matplotlib/colorbar.py @@ -1198,8 +1198,9 @@ def _proportional_y(self): a proportional colorbar, plus extension lengths if required: """ if isinstance(self.norm, colors.BoundaryNorm): - y = (self._boundaries - self._boundaries[0]) - y = y / (self._boundaries[-1] - self._boundaries[0]) + y = (self._boundaries - self._boundaries[self._inside][0]) + y = y / (self._boundaries[self._inside][-1] - + self._boundaries[self._inside][0]) # need yscaled the same as the axes scale to get # the extend lengths. if self.spacing == 'uniform': diff --git a/lib/matplotlib/tests/baseline_images/test_colorbar/proportional_colorbars.png b/lib/matplotlib/tests/baseline_images/test_colorbar/proportional_colorbars.png new file mode 100644 index 0000000000000000000000000000000000000000..a1f9745230ba39cc362d144aa7994dc8a8a86edb GIT binary patch literal 11329 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 literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index 5f19a0aaf20a..00a6f52698e2 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -827,3 +827,30 @@ def test_aspects(): np.testing.assert_almost_equal( cb[1][0].ax.get_position(original=False).height * 2, cb[1][2].ax.get_position(original=False).height, decimal=2) + + +@image_comparison(['proportional_colorbars.png'], remove_text=True, + style='mpl20') +def test_proportional_colorbars(): + + x = y = np.arange(-3.0, 3.01, 0.025) + X, Y = np.meshgrid(x, y) + Z1 = np.exp(-X**2 - Y**2) + Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2) + Z = (Z1 - Z2) * 2 + + levels = [-1.25, -0.5, -0.125, 0.125, 0.5, 1.25] + cmap = mcolors.ListedColormap( + ['0.3', '0.5', 'white', 'lightblue', 'steelblue']) + cmap.set_under('darkred') + cmap.set_over('crimson') + norm = mcolors.BoundaryNorm(levels, cmap.N) + + extends = ['neither', 'both'] + spacings = ['uniform', 'proportional'] + fig, axs = plt.subplots(2, 2) + for i in range(2): + for j in range(2): + CS3 = axs[i, j].contourf(X, Y, Z, levels, cmap=cmap, norm=norm, + extend=extends[i]) + fig.colorbar(CS3, spacing=spacings[j], ax=axs[i, j])