diff --git a/doc/api/colors_api.rst b/doc/api/colors_api.rst index ccd1cf18aa07..9a8717541b99 100644 --- a/doc/api/colors_api.rst +++ b/doc/api/colors_api.rst @@ -34,6 +34,7 @@ Classes Normalize PowerNorm SymLogNorm + TwoSlopeNorm Functions --------- diff --git a/doc/api/prev_api_changes/api_changes_3.2.0/deprecations.rst b/doc/api/prev_api_changes/api_changes_3.2.0/deprecations.rst index 4774515da565..5c6ed4ac9cb4 100644 --- a/doc/api/prev_api_changes/api_changes_3.2.0/deprecations.rst +++ b/doc/api/prev_api_changes/api_changes_3.2.0/deprecations.rst @@ -260,6 +260,16 @@ is deprecated. ``testing.jpl_units.UnitDbl.UnitDbl.checkUnits`` is deprecated. +``DivergingNorm`` renamed to ``TwoSlopeNorm`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``DivergingNorm`` was a misleading name; although the norm was +developed with the idea that it would likely be used with diverging +colormaps, the word 'diverging' does not describe or evoke the norm's +mapping function. Since that function is monotonic, continuous, and +piece-wise linear with two segments, the norm has been renamed to +`.TwoSlopeNorm` + Misc ~~~~ ``matplotlib.get_home`` is deprecated (use e.g. ``os.path.expanduser("~")``) diff --git a/examples/userdemo/colormap_normalizations_diverging.py b/examples/userdemo/colormap_normalizations_diverging.py index 7a5a68c29b73..3c1b6a26ef72 100644 --- a/examples/userdemo/colormap_normalizations_diverging.py +++ b/examples/userdemo/colormap_normalizations_diverging.py @@ -1,7 +1,7 @@ """ -===================================== -DivergingNorm colormap normalization -===================================== +=================================== +TwoSlopeNorm colormap normalization +=================================== Sometimes we want to have a different colormap on either side of a conceptual center point, and we want those two colormaps to have @@ -33,7 +33,7 @@ # make the norm: Note the center is offset so that the land has more # dynamic range: -divnorm = colors.DivergingNorm(vmin=-500, vcenter=0, vmax=4000) +divnorm = colors.TwoSlopeNorm(vmin=-500, vcenter=0, vmax=4000) pcm = ax.pcolormesh(longitude, latitude, topo, rasterized=True, norm=divnorm, cmap=terrain_map,) diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 1aa4ca9cd40d..c9635d97887d 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -1060,7 +1060,7 @@ def scaled(self): return self.vmin is not None and self.vmax is not None -class DivergingNorm(Normalize): +class TwoSlopeNorm(Normalize): def __init__(self, vcenter, vmin=None, vmax=None): """ Normalize data with a set center. @@ -1086,8 +1086,8 @@ def __init__(self, vcenter, vmin=None, vmax=None): between is linearly interpolated:: >>> import matplotlib.colors as mcolors - >>> offset = mcolors.DivergingNorm(vmin=-4000., - vcenter=0., vmax=10000) + >>> offset = mcolors.TwoSlopeNorm(vmin=-4000., + vcenter=0., vmax=10000) >>> data = [-4000., -2000., 0., 2500., 5000., 7500., 10000.] >>> offset(data) array([0., 0.25, 0.5, 0.625, 0.75, 0.875, 1.0]) @@ -1130,6 +1130,11 @@ def __call__(self, value, clip=None): return result +@cbook.deprecation.deprecated('3.2', alternative='TwoSlopeNorm') +class DivergingNorm(TwoSlopeNorm): + ... + + class LogNorm(Normalize): """Normalize a given value to the 0-1 range on a log scale.""" diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index 84368cba8a8d..0798e257bbd5 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -8,7 +8,7 @@ from matplotlib.testing.decorators import image_comparison import matplotlib.pyplot as plt from matplotlib.colors import (BoundaryNorm, LogNorm, PowerNorm, Normalize, - DivergingNorm) + TwoSlopeNorm) from matplotlib.colorbar import ColorbarBase, _ColorbarLogLocator from matplotlib.ticker import LogLocator, LogFormatter, FixedLocator @@ -536,7 +536,7 @@ def test_colorbar_inverted_ticks(): def test_extend_colorbar_customnorm(): - # This was a funny error with DivergingNorm, maybe with other norms, + # This was a funny error with TwoSlopeNorm, maybe with other norms, # when extend='both' N = 100 X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)] @@ -546,7 +546,7 @@ def test_extend_colorbar_customnorm(): fig, ax = plt.subplots(2, 1) pcm = ax[0].pcolormesh(X, Y, Z, - norm=DivergingNorm(vcenter=0., vmin=-2, vmax=1), + norm=TwoSlopeNorm(vcenter=0., vmin=-2, vmax=1), cmap='RdBu_r') cb = fig.colorbar(pcm, ax=ax[0], extend='both') np.testing.assert_allclose(cb.ax.get_position().extents, diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py index 96e34edfbd74..c0c9b6d06620 100644 --- a/lib/matplotlib/tests/test_colors.py +++ b/lib/matplotlib/tests/test_colors.py @@ -295,91 +295,91 @@ def test_Normalize(): assert 0 < norm(1 + 50 * eps) < 1 -def test_DivergingNorm_autoscale(): - norm = mcolors.DivergingNorm(vcenter=20) +def test_TwoSlopeNorm_autoscale(): + norm = mcolors.TwoSlopeNorm(vcenter=20) norm.autoscale([10, 20, 30, 40]) assert norm.vmin == 10. assert norm.vmax == 40. -def test_DivergingNorm_autoscale_None_vmin(): - norm = mcolors.DivergingNorm(2, vmin=0, vmax=None) +def test_TwoSlopeNorm_autoscale_None_vmin(): + norm = mcolors.TwoSlopeNorm(2, vmin=0, vmax=None) norm.autoscale_None([1, 2, 3, 4, 5]) assert norm(5) == 1 assert norm.vmax == 5 -def test_DivergingNorm_autoscale_None_vmax(): - norm = mcolors.DivergingNorm(2, vmin=None, vmax=10) +def test_TwoSlopeNorm_autoscale_None_vmax(): + norm = mcolors.TwoSlopeNorm(2, vmin=None, vmax=10) norm.autoscale_None([1, 2, 3, 4, 5]) assert norm(1) == 0 assert norm.vmin == 1 -def test_DivergingNorm_scale(): - norm = mcolors.DivergingNorm(2) +def test_TwoSlopeNorm_scale(): + norm = mcolors.TwoSlopeNorm(2) assert norm.scaled() is False norm([1, 2, 3, 4]) assert norm.scaled() is True -def test_DivergingNorm_scaleout_center(): +def test_TwoSlopeNorm_scaleout_center(): # test the vmin never goes above vcenter - norm = mcolors.DivergingNorm(vcenter=0) + norm = mcolors.TwoSlopeNorm(vcenter=0) norm([1, 2, 3, 5]) assert norm.vmin == 0 assert norm.vmax == 5 -def test_DivergingNorm_scaleout_center_max(): +def test_TwoSlopeNorm_scaleout_center_max(): # test the vmax never goes below vcenter - norm = mcolors.DivergingNorm(vcenter=0) + norm = mcolors.TwoSlopeNorm(vcenter=0) norm([-1, -2, -3, -5]) assert norm.vmax == 0 assert norm.vmin == -5 -def test_DivergingNorm_Even(): - norm = mcolors.DivergingNorm(vmin=-1, vcenter=0, vmax=4) +def test_TwoSlopeNorm_Even(): + norm = mcolors.TwoSlopeNorm(vmin=-1, vcenter=0, vmax=4) vals = np.array([-1.0, -0.5, 0.0, 1.0, 2.0, 3.0, 4.0]) expected = np.array([0.0, 0.25, 0.5, 0.625, 0.75, 0.875, 1.0]) assert_array_equal(norm(vals), expected) -def test_DivergingNorm_Odd(): - norm = mcolors.DivergingNorm(vmin=-2, vcenter=0, vmax=5) +def test_TwoSlopeNorm_Odd(): + norm = mcolors.TwoSlopeNorm(vmin=-2, vcenter=0, vmax=5) vals = np.array([-2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0]) expected = np.array([0.0, 0.25, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]) assert_array_equal(norm(vals), expected) -def test_DivergingNorm_VminEqualsVcenter(): +def test_TwoSlopeNorm_VminEqualsVcenter(): with pytest.raises(ValueError): - mcolors.DivergingNorm(vmin=-2, vcenter=-2, vmax=2) + mcolors.TwoSlopeNorm(vmin=-2, vcenter=-2, vmax=2) -def test_DivergingNorm_VmaxEqualsVcenter(): +def test_TwoSlopeNorm_VmaxEqualsVcenter(): with pytest.raises(ValueError): - mcolors.DivergingNorm(vmin=-2, vcenter=2, vmax=2) + mcolors.TwoSlopeNorm(vmin=-2, vcenter=2, vmax=2) -def test_DivergingNorm_VminGTVcenter(): +def test_TwoSlopeNorm_VminGTVcenter(): with pytest.raises(ValueError): - mcolors.DivergingNorm(vmin=10, vcenter=0, vmax=20) + mcolors.TwoSlopeNorm(vmin=10, vcenter=0, vmax=20) -def test_DivergingNorm_DivergingNorm_VminGTVmax(): +def test_TwoSlopeNorm_TwoSlopeNorm_VminGTVmax(): with pytest.raises(ValueError): - mcolors.DivergingNorm(vmin=10, vcenter=0, vmax=5) + mcolors.TwoSlopeNorm(vmin=10, vcenter=0, vmax=5) -def test_DivergingNorm_VcenterGTVmax(): +def test_TwoSlopeNorm_VcenterGTVmax(): with pytest.raises(ValueError): - mcolors.DivergingNorm(vmin=10, vcenter=25, vmax=20) + mcolors.TwoSlopeNorm(vmin=10, vcenter=25, vmax=20) -def test_DivergingNorm_premature_scaling(): - norm = mcolors.DivergingNorm(vcenter=2) +def test_TwoSlopeNorm_premature_scaling(): + norm = mcolors.TwoSlopeNorm(vcenter=2) with pytest.raises(ValueError): norm.inverse(np.array([0.1, 0.5, 0.9])) @@ -915,3 +915,8 @@ def test_same_color(): def test_hex_shorthand_notation(): assert mcolors.same_color("#123", "#112233") assert mcolors.same_color("#123a", "#112233aa") + + +def test_DivergingNorm_deprecated(): + with pytest.warns(cbook.MatplotlibDeprecationWarning): + norm = mcolors.DivergingNorm(vcenter=0) diff --git a/tutorials/colors/colormapnorms.py b/tutorials/colors/colormapnorms.py index 7bdeb9c5c893..1c3c62ce577c 100644 --- a/tutorials/colors/colormapnorms.py +++ b/tutorials/colors/colormapnorms.py @@ -188,8 +188,8 @@ ############################################################################### -# DivergingNorm: Different mapping on either side of a center -# ----------------------------------------------------------- +# TwoSlopeNorm: Different mapping on either side of a center +# ---------------------------------------------------------- # # Sometimes we want to have a different colormap on either side of a # conceptual center point, and we want those two colormaps to have @@ -215,7 +215,7 @@ # make the norm: Note the center is offset so that the land has more # dynamic range: -divnorm = colors.DivergingNorm(vmin=-500., vcenter=0, vmax=4000) +divnorm = colors.TwoSlopeNorm(vmin=-500., vcenter=0, vmax=4000) pcm = ax.pcolormesh(longitude, latitude, topo, rasterized=True, norm=divnorm, cmap=terrain_map,) @@ -230,7 +230,7 @@ # Custom normalization: Manually implement two linear ranges # ---------------------------------------------------------- # -# The `.DivergingNorm` described above makes a useful example for +# The `.TwoSlopeNorm` described above makes a useful example for # defining your own norm. class MidpointNormalize(colors.Normalize):