From 1b96a31d13a1813178e31a3e151b467339e74dce Mon Sep 17 00:00:00 2001 From: David Stansby Date: Tue, 16 Apr 2019 10:18:34 +0100 Subject: [PATCH 1/2] Check vmin/vmax are valid when doing inverse in LogNorm --- lib/matplotlib/colors.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 8cb18d852322..72e47189fdac 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -1038,6 +1038,12 @@ def __call__(self, value, clip=None): class LogNorm(Normalize): """Normalize a given value to the 0-1 range on a log scale.""" + def _check_vmin_vmax(self): + if self.vmin > self.vmax: + raise ValueError("minvalue must be less than or equal to maxvalue") + elif self.vmin <= 0: + raise ValueError("minvalue must be positive") + def __call__(self, value, clip=None): if clip is None: clip = self.clip @@ -1047,12 +1053,9 @@ def __call__(self, value, clip=None): result = np.ma.masked_less_equal(result, 0, copy=False) self.autoscale_None(result) + self._check_vmin_vmax() vmin, vmax = self.vmin, self.vmax - if vmin > vmax: - raise ValueError("minvalue must be less than or equal to maxvalue") - elif vmin <= 0: - raise ValueError("values must all be positive") - elif vmin == vmax: + if vmin == vmax: result.fill(0) else: if clip: @@ -1078,6 +1081,7 @@ def __call__(self, value, clip=None): def inverse(self, value): if not self.scaled(): raise ValueError("Not invertible until scaled") + self._check_vmin_vmax() vmin, vmax = self.vmin, self.vmax if np.iterable(value): From c56c551476cbcf08e824cb2d58c29d8b61ec8226 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Thu, 18 Apr 2019 11:21:54 +0100 Subject: [PATCH 2/2] Add invalid LogNorm limits test --- lib/matplotlib/tests/test_colors.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py index 19fabbfdb551..31398c17d72a 100644 --- a/lib/matplotlib/tests/test_colors.py +++ b/lib/matplotlib/tests/test_colors.py @@ -145,6 +145,16 @@ def test_BoundaryNorm(): assert np.all(bn(vals).mask) +@pytest.mark.parametrize("vmin,vmax", [[-1, 2], [3, 1]]) +def test_lognorm_invalid(vmin, vmax): + # Check that invalid limits in LogNorm error + norm = mcolors.LogNorm(vmin=vmin, vmax=vmax) + with pytest.raises(ValueError): + norm(1) + with pytest.raises(ValueError): + norm.inverse(1) + + def test_LogNorm(): """ LogNorm ignored clip, now it has the same