Skip to content

Commit 9fd8b0c

Browse files
committed
Added AsinhNorm for colorscale support
1 parent 0249861 commit 9fd8b0c

File tree

6 files changed

+48
-5
lines changed

6 files changed

+48
-5
lines changed

examples/images_contours_and_fields/colormap_normalizations_symlognorm.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
2626
Z1 = np.exp(-X**2 - Y**2)
2727
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
28-
Z = (Z1 - Z2) * 2
28+
Z = (5 * Z1 - Z2) * 2
2929

3030
fig, ax = plt.subplots(2, 1)
3131

lib/matplotlib/colors.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,27 @@ def linthresh(self, value):
16521652
self._scale.linthresh = value
16531653

16541654

1655+
@make_norm_from_scale(
1656+
scale.AsinhScale,
1657+
init=lambda linear_width=1, vmin=None, vmax=None, clip=False: None)
1658+
class AsinhNorm(Normalize):
1659+
"""
1660+
The inverse hyperbolic sine scale is approximately linear near
1661+
the origin, but becomes logarithmic for larger positive
1662+
or negative values. Unlike the `SymLogNorm`, the transition between
1663+
these linear and logarithmic regions is smooth, which may reduce
1664+
the risk of visual artifacts.
1665+
"""
1666+
1667+
@property
1668+
def linear_width(self):
1669+
return self._scale.linear_width
1670+
1671+
@linear_width.setter
1672+
def linear_width(self, value):
1673+
self._scale.linear_width = value
1674+
1675+
16551676
class PowerNorm(Normalize):
16561677
"""
16571678
Linearly map a given value to the 0-1 range and then apply

lib/matplotlib/scale.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,8 @@ class AsinhScale(ScaleBase):
519519
10: (2, 5),
520520
16: (2, 4, 8),
521521
64: (4, 16),
522-
1024: (256, 512) }
522+
1024: (256, 512)
523+
}
523524

524525
def __init__(self, axis, *, linear_width=1.0,
525526
base=10, subs='auto', **kwargs):

lib/matplotlib/tests/test_colors.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,28 @@ def test_SymLogNorm_single_zero():
745745
plt.close(fig)
746746

747747

748+
class TestAsinhNorm:
749+
"""
750+
Tests for `~.colors.AsinhNorm`
751+
"""
752+
753+
def test_init(self):
754+
norm0 = mcolors.AsinhNorm()
755+
assert norm0.linear_width == 1
756+
757+
norm5 = mcolors.AsinhNorm(linear_width=5)
758+
assert norm5.linear_width == 5
759+
760+
def test_norm(self):
761+
norm = mcolors.AsinhNorm(2, vmin=-4, vmax=4)
762+
vals = np.arange(-3.5, 3.5, 10)
763+
normed_vals = norm(vals)
764+
asinh2 = np.arcsinh(2)
765+
766+
expected = (2 * np.arcsinh(vals / 2) + 2 * asinh2) / (4 * asinh2)
767+
assert_array_almost_equal(normed_vals, expected)
768+
769+
748770
def _inverse_tester(norm_instance, vals):
749771
"""
750772
Checks if the inverse of the given normalization is working.

lib/matplotlib/tests/test_ticker.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,6 @@ def test_base_rounding(self):
549549
0.2, 1, 5, 25, 125, 625])
550550

551551

552-
553552
class TestScalarFormatter:
554553
offset_data = [
555554
(123, 189, 0),

lib/matplotlib/ticker.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2664,7 +2664,7 @@ def tick_values(self, vmin, vmax):
26642664
if self.base > 1:
26652665
log_base = math.log(self.base)
26662666
powers = (
2667-
np.where(zero_xs, 0, np.where(xs >=0, 1, -1)) *
2667+
np.where(zero_xs, 0, np.where(xs >= 0, 1, -1)) *
26682668
np.power(self.base,
26692669
np.where(zero_xs, 0.0,
26702670
np.floor(np.log(np.abs(xs) + zero_xs*1e-6)
@@ -2684,7 +2684,7 @@ def tick_values(self, vmin, vmax):
26842684
qs = powers * np.round(xs / powers)
26852685
ticks = np.array(sorted(set(qs)))
26862686

2687-
if len(ticks) >= 2:
2687+
if len(ticks) >= 2:
26882688
return ticks
26892689
else:
26902690
return np.linspace(vmin, vmax, self.numticks)

0 commit comments

Comments
 (0)