From c7df5d2770030fe4588a0fc1ab4449a689554dfc Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Mon, 10 Feb 2020 12:43:58 -0800 Subject: [PATCH 1/3] FIX: add base kwarg to symlognorm --- doc/api/next_api_changes/behaviour.rst | 7 ++++ examples/userdemo/colormap_normalizations.py | 2 +- .../colormap_normalizations_symlognorm.py | 2 +- lib/matplotlib/colors.py | 35 ++++++++++++++----- lib/matplotlib/tests/test_colors.py | 27 ++++++++++---- tutorials/colors/colormapnorms.py | 2 +- 6 files changed, 57 insertions(+), 18 deletions(-) diff --git a/doc/api/next_api_changes/behaviour.rst b/doc/api/next_api_changes/behaviour.rst index be394fbd4277..2db6e027ea21 100644 --- a/doc/api/next_api_changes/behaviour.rst +++ b/doc/api/next_api_changes/behaviour.rst @@ -85,3 +85,10 @@ Previously, rcParams entries whose values were color-like accepted "spurious" extra letters or characters in the "middle" of the string, e.g. ``"(0, 1a, '0.5')"`` would be interpreted as ``(0, 1, 0.5)``. These extra characters (including the internal quotes) now cause a ValueError to be raised. + +`.SymLogNorm` now has a *base* kwarg. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Previously, `.SymLogNorm` had not *base* kwarg, and defaulted to ``base=np.e`` +whereas the documentation said it was ``base=10``. In preparation to make +the default 10, calling `.SymLogNorm` without the new *base* kwarg emits a +deprecation warning. diff --git a/examples/userdemo/colormap_normalizations.py b/examples/userdemo/colormap_normalizations.py index 419a4b5051aa..2844fd9f9646 100644 --- a/examples/userdemo/colormap_normalizations.py +++ b/examples/userdemo/colormap_normalizations.py @@ -69,7 +69,7 @@ pcm = ax[0].pcolormesh(X, Y, Z1, norm=colors.SymLogNorm(linthresh=0.03, linscale=0.03, - vmin=-1.0, vmax=1.0), + vmin=-1.0, vmax=1.0, base=10), cmap='RdBu_r') fig.colorbar(pcm, ax=ax[0], extend='both') diff --git a/examples/userdemo/colormap_normalizations_symlognorm.py b/examples/userdemo/colormap_normalizations_symlognorm.py index 780381e43da8..b0fbf0dc30ea 100644 --- a/examples/userdemo/colormap_normalizations_symlognorm.py +++ b/examples/userdemo/colormap_normalizations_symlognorm.py @@ -29,7 +29,7 @@ pcm = ax[0].pcolormesh(X, Y, Z, norm=colors.SymLogNorm(linthresh=0.03, linscale=0.03, - vmin=-1.0, vmax=1.0), + vmin=-1.0, vmax=1.0, base=10), cmap='RdBu_r') fig.colorbar(pcm, ax=ax[0], extend='both') diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 52d2b2438959..7f3ed2afb4e7 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -1202,8 +1202,8 @@ class SymLogNorm(Normalize): *linthresh* allows the user to specify the size of this range (-*linthresh*, *linthresh*). """ - def __init__(self, linthresh, linscale=1.0, - vmin=None, vmax=None, clip=False): + def __init__(self, linthresh, linscale=1.0, vmin=None, vmax=None, + clip=False, base=None): """ Parameters ---------- @@ -1213,14 +1213,29 @@ def __init__(self, linthresh, linscale=1.0, linscale : float, default: 1 This allows the linear range (-*linthresh* to *linthresh*) to be stretched relative to the logarithmic range. Its value is the - number of decades to use for each half of the linear range. For - example, when *linscale* == 1.0 (the default), the space used for - the positive and negative halves of the linear range will be equal - to one decade in the logarithmic range. + number of powers of *base* (decades for base 10) to use for each + half of the linear range. For example, when *linscale* == 1.0 + (the default), the space used for the positive and negative halves + of the linear range will be equal to a decade in the logarithmic + range if ``base=10``. + base : float, default: None + For v3.2 the default is the old value of ``np.e``, but that is + deprecated for v3.3 when base will default to 10. During the + transition, specify the *base* kwarg to avoid a deprecation + warning. """ Normalize.__init__(self, vmin, vmax, clip) + if base is None: + self._base = np.e + cbook.warn_deprecated("3.3", message="default base will change " + "from np.e to 10. To suppress this warning specify the base " + "kwarg.") + else: + self._base = base + self._log_base = np.log(self._base) + self.linthresh = float(linthresh) - self._linscale_adj = (linscale / (1.0 - np.e ** -1)) + self._linscale_adj = (linscale / (1.0 - self._base ** -1)) if vmin is not None and vmax is not None: self._transform_vmin_vmax() @@ -1255,7 +1270,8 @@ def _transform(self, a): with np.errstate(invalid="ignore"): masked = np.abs(a) > self.linthresh sign = np.sign(a[masked]) - log = (self._linscale_adj + np.log(np.abs(a[masked]) / self.linthresh)) + log = (self._linscale_adj + + np.log(np.abs(a[masked]) / self.linthresh) / self._log_base) log *= sign * self.linthresh a[masked] = log a[~masked] *= self._linscale_adj @@ -1265,7 +1281,8 @@ def _inv_transform(self, a): """Inverse inplace Transformation.""" masked = np.abs(a) > (self.linthresh * self._linscale_adj) sign = np.sign(a[masked]) - exp = np.exp(sign * a[masked] / self.linthresh - self._linscale_adj) + exp = np.power(self._base, + sign * a[masked] / self.linthresh - self._linscale_adj) exp *= sign * self.linthresh a[masked] = exp a[~masked] /= self._linscale_adj diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py index 05a81e26def3..d1cedfeb141e 100644 --- a/lib/matplotlib/tests/test_colors.py +++ b/lib/matplotlib/tests/test_colors.py @@ -398,7 +398,7 @@ def test_SymLogNorm(): """ Test SymLogNorm behavior """ - norm = mcolors.SymLogNorm(3, vmax=5, linscale=1.2) + norm = mcolors.SymLogNorm(3, vmax=5, linscale=1.2, base=np.e) vals = np.array([-30, -1, 2, 6], dtype=float) normed_vals = norm(vals) expected = [0., 0.53980074, 0.826991, 1.02758204] @@ -408,16 +408,30 @@ def test_SymLogNorm(): _mask_tester(norm, vals) # Ensure that specifying vmin returns the same result as above - norm = mcolors.SymLogNorm(3, vmin=-30, vmax=5, linscale=1.2) + norm = mcolors.SymLogNorm(3, vmin=-30, vmax=5, linscale=1.2, base=np.e) normed_vals = norm(vals) assert_array_almost_equal(normed_vals, expected) + # test something more easily checked. + norm = mcolors.SymLogNorm(1, vmin=-np.e**3, vmax=np.e**3, base=np.e) + nn = norm([-np.e**3, -np.e**2, -np.e**1, -1, + 0, 1, np.e**1, np.e**2, np.e**3]) + xx = np.array([0., 0.109123, 0.218246, 0.32737, 0.5, 0.67263, + 0.781754, 0.890877, 1.]) + assert_array_almost_equal(nn, xx) + norm = mcolors.SymLogNorm(1, vmin=-10**3, vmax=10**3, base=10) + nn = norm([-10**3, -10**2, -10**1, -1, + 0, 1, 10**1, 10**2, 10**3]) + xx = np.array([0., 0.121622, 0.243243, 0.364865, 0.5, 0.635135, + 0.756757, 0.878378, 1.]) + assert_array_almost_equal(nn, xx) + def test_SymLogNorm_colorbar(): """ Test un-called SymLogNorm in a colorbar. """ - norm = mcolors.SymLogNorm(0.1, vmin=-1, vmax=1, linscale=1) + norm = mcolors.SymLogNorm(0.1, vmin=-1, vmax=1, linscale=1, base=np.e) fig = plt.figure() mcolorbar.ColorbarBase(fig.add_subplot(111), norm=norm) plt.close(fig) @@ -428,7 +442,7 @@ def test_SymLogNorm_single_zero(): Test SymLogNorm to ensure it is not adding sub-ticks to zero label """ fig = plt.figure() - norm = mcolors.SymLogNorm(1e-5, vmin=-1, vmax=1) + norm = mcolors.SymLogNorm(1e-5, vmin=-1, vmax=1, base=np.e) cbar = mcolorbar.ColorbarBase(fig.add_subplot(111), norm=norm) ticks = cbar.get_ticks() assert sum(ticks == 0) == 1 @@ -905,9 +919,10 @@ def __add__(self, other): mydata = data.view(MyArray) for norm in [mcolors.Normalize(), mcolors.LogNorm(), - mcolors.SymLogNorm(3, vmax=5, linscale=1), + mcolors.SymLogNorm(3, vmax=5, linscale=1, base=np.e), mcolors.Normalize(vmin=mydata.min(), vmax=mydata.max()), - mcolors.SymLogNorm(3, vmin=mydata.min(), vmax=mydata.max()), + mcolors.SymLogNorm(3, vmin=mydata.min(), vmax=mydata.max(), + base=np.e), mcolors.PowerNorm(1)]: assert_array_equal(norm(mydata), norm(data)) fig, ax = plt.subplots() diff --git a/tutorials/colors/colormapnorms.py b/tutorials/colors/colormapnorms.py index 412278ac45cb..ea982b243207 100644 --- a/tutorials/colors/colormapnorms.py +++ b/tutorials/colors/colormapnorms.py @@ -98,7 +98,7 @@ pcm = ax[0].pcolormesh(X, Y, Z, norm=colors.SymLogNorm(linthresh=0.03, linscale=0.03, - vmin=-1.0, vmax=1.0), + vmin=-1.0, vmax=1.0, base=10), cmap='RdBu_r') fig.colorbar(pcm, ax=ax[0], extend='both') From ec05b764c87b84ea0415fd1c2f52f75c48792119 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Sat, 15 Feb 2020 16:38:07 -0800 Subject: [PATCH 2/3] Update doc/api/next_api_changes/behaviour.rst Co-Authored-By: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> --- doc/api/next_api_changes/behaviour.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/api/next_api_changes/behaviour.rst b/doc/api/next_api_changes/behaviour.rst index 2db6e027ea21..3cca24e94df7 100644 --- a/doc/api/next_api_changes/behaviour.rst +++ b/doc/api/next_api_changes/behaviour.rst @@ -86,9 +86,10 @@ extra letters or characters in the "middle" of the string, e.g. ``"(0, 1a, '0.5' would be interpreted as ``(0, 1, 0.5)``. These extra characters (including the internal quotes) now cause a ValueError to be raised. -`.SymLogNorm` now has a *base* kwarg. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Previously, `.SymLogNorm` had not *base* kwarg, and defaulted to ``base=np.e`` +`.SymLogNorm` now has a *base* parameter +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Previously, `.SymLogNorm` had no *base* kwarg, and defaulted to ``base=np.e`` whereas the documentation said it was ``base=10``. In preparation to make the default 10, calling `.SymLogNorm` without the new *base* kwarg emits a deprecation warning. From fe5fdf8f10586f147eb134d16a2db7427722d144 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Sat, 15 Feb 2020 16:38:20 -0800 Subject: [PATCH 3/3] Update lib/matplotlib/colors.py Co-Authored-By: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> --- lib/matplotlib/colors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 7f3ed2afb4e7..5b584cfac2b3 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -1203,7 +1203,7 @@ class SymLogNorm(Normalize): (-*linthresh*, *linthresh*). """ def __init__(self, linthresh, linscale=1.0, vmin=None, vmax=None, - clip=False, base=None): + clip=False, *, base=None): """ Parameters ---------- pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy