Thanks to visit codestin.com
Credit goes to github.com

Skip to content

FIX: add base kwarg to symlognor #16404

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions doc/api/next_api_changes/behaviour.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,11 @@ 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* 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.
2 changes: 1 addition & 1 deletion examples/userdemo/colormap_normalizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand Down
2 changes: 1 addition & 1 deletion examples/userdemo/colormap_normalizations_symlognorm.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand Down
35 changes: 26 additions & 9 deletions lib/matplotlib/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
----------
Expand All @@ -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()

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
27 changes: 21 additions & 6 deletions lib/matplotlib/tests/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion tutorials/colors/colormapnorms.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand Down