From 7c688ecbbae3d5c35c1ce04dfe1f99e2429fad94 Mon Sep 17 00:00:00 2001 From: dcherian Date: Sun, 29 Mar 2020 10:23:42 -0600 Subject: [PATCH 1/3] Use divergent colormap if lowest and highest level span 0 Fixes #3524 --- doc/whats-new.rst | 2 ++ xarray/plot/utils.py | 7 ++++++- xarray/tests/test_plot.py | 6 ++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index c70dfd4f3f6..dd967f31c08 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -48,6 +48,8 @@ Bug fixes - Fix a regression where deleting a coordinate from a copied :py:class:`DataArray` can affect the original :py:class:`Dataarray`. (:issue:`3899`, :pull:`3871`) By `Todd Jennings `_ +- Use divergent colormap if ``levels`` spans 0. (:issue:`3524`) + By `Deepak Cherian `_ Documentation diff --git a/xarray/plot/utils.py b/xarray/plot/utils.py index e6c15037cb8..19506f2ab46 100644 --- a/xarray/plot/utils.py +++ b/xarray/plot/utils.py @@ -216,8 +216,13 @@ def _determine_cmap_params( vlim = abs(vmax - center) if possibly_divergent: + levels_are_divergent = ( + isinstance(levels, Iterable) and levels[0] * levels[-1] < 0 + ) # kwargs not specific about divergent or not: infer defaults from data - divergent = ((vmin < 0) and (vmax > 0)) or not center_is_none + divergent = ( + ((vmin < 0) and (vmax > 0)) or not center_is_none or levels_are_divergent + ) else: divergent = False diff --git a/xarray/tests/test_plot.py b/xarray/tests/test_plot.py index 7f3f1620133..b62bf81c104 100644 --- a/xarray/tests/test_plot.py +++ b/xarray/tests/test_plot.py @@ -827,6 +827,12 @@ def test_divergentcontrol(self): assert cmap_params["vmax"] == 0.6 assert cmap_params["cmap"] == "viridis" + # regression test for GH3524 + # infer diverging colormap from divergent levels + cmap_params = _determine_cmap_params(pos, levels=[-0.1, 0, 1]) + # specifying levels makes cmap a Colormap object + assert cmap_params["cmap"].name == "RdBu_r" + def test_norm_sets_vmin_vmax(self): vmin = self.data.min() vmax = self.data.max() From d2c3c52e61dd0f8a7c30d5bcd1cc86ebdf26a239 Mon Sep 17 00:00:00 2001 From: dcherian Date: Tue, 31 Mar 2020 08:10:02 -0600 Subject: [PATCH 2/3] sort levels by default. --- xarray/plot/utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xarray/plot/utils.py b/xarray/plot/utils.py index 19506f2ab46..b3f8ccad53f 100644 --- a/xarray/plot/utils.py +++ b/xarray/plot/utils.py @@ -169,6 +169,9 @@ def _determine_cmap_params( """ import matplotlib as mpl + if levels is not None: + levels = sorted(levels) + calc_data = np.ravel(plot_data[np.isfinite(plot_data)]) # Handle all-NaN input data gracefully From 52b6d42f1d17dc5c7ae6e23252e5a086cd35099d Mon Sep 17 00:00:00 2001 From: dcherian Date: Tue, 31 Mar 2020 12:39:12 -0600 Subject: [PATCH 3/3] better levels check --- xarray/plot/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/plot/utils.py b/xarray/plot/utils.py index b3f8ccad53f..46cd4cde29a 100644 --- a/xarray/plot/utils.py +++ b/xarray/plot/utils.py @@ -169,7 +169,7 @@ def _determine_cmap_params( """ import matplotlib as mpl - if levels is not None: + if isinstance(levels, Iterable): levels = sorted(levels) calc_data = np.ravel(plot_data[np.isfinite(plot_data)])