diff --git a/doc/whats-new.rst b/doc/whats-new.rst index e5a574d692b..9d71f294f77 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -56,6 +56,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 `_ - Fix ``FacetGrid`` when ``vmin == vmax``. (:issue:`3734`) By `Deepak Cherian `_ diff --git a/xarray/plot/utils.py b/xarray/plot/utils.py index 9fdfcc2c318..2a9a4b4dec7 100644 --- a/xarray/plot/utils.py +++ b/xarray/plot/utils.py @@ -169,6 +169,9 @@ def _determine_cmap_params( """ import matplotlib as mpl + if isinstance(levels, Iterable): + levels = sorted(levels) + calc_data = np.ravel(plot_data[np.isfinite(plot_data)]) # Handle all-NaN input data gracefully @@ -216,8 +219,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 46556c14517..7d34a6ed4d9 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()