diff --git a/doc/whats-new.rst b/doc/whats-new.rst index ed7bbc685a8..3740a5a44f1 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -29,7 +29,8 @@ Breaking changes Deprecations ~~~~~~~~~~~~ - +- `hue_style` is being deprecated for scatter plots. (:issue:`7907`, :pull:`7925`). + By `Jimmy Westling `_. Bug fixes ~~~~~~~~~ @@ -43,8 +44,6 @@ Internal Changes ~~~~~~~~~~~~~~~~ -.. _whats-new.2023.07.0: - v2023.07.0 (July 11, 2023) -------------------------- diff --git a/xarray/plot/dataarray_plot.py b/xarray/plot/dataarray_plot.py index 7f11ddac0a6..d2c0a8e2af6 100644 --- a/xarray/plot/dataarray_plot.py +++ b/xarray/plot/dataarray_plot.py @@ -733,15 +733,6 @@ def _plot1d(plotfunc): If specified plot 3D and use this coordinate for *z* axis. hue : Hashable or None, optional Dimension or coordinate for which you want multiple lines plotted. - hue_style: {'discrete', 'continuous'} or None, optional - How to use the ``hue`` variable: - - - ``'continuous'`` -- continuous color scale - (default for numeric ``hue`` variables) - - ``'discrete'`` -- a color for each unique value, - using the default color cycle - (default for non-numeric ``hue`` variables) - markersize: Hashable or None, optional scatter only. Variable by which to vary size of scattered points. linewidth: Hashable or None, optional @@ -935,6 +926,19 @@ def newplotfunc( warnings.warn(msg, DeprecationWarning, stacklevel=2) del args + if hue_style is not None: + # TODO: Not used since 2022.10. Deprecated since 2023.07. + warnings.warn( + ( + "hue_style is no longer used for plot1d plots " + "and the argument will eventually be removed. " + "Convert numbers to string for a discrete hue " + "and use add_legend or add_colorbar to control which guide to display." + ), + DeprecationWarning, + stacklevel=2, + ) + _is_facetgrid = kwargs.pop("_is_facetgrid", False) if plotfunc.__name__ == "scatter": diff --git a/xarray/plot/utils.py b/xarray/plot/utils.py index e807081f838..2c58fe83cef 100644 --- a/xarray/plot/utils.py +++ b/xarray/plot/utils.py @@ -1438,6 +1438,16 @@ def data_is_numeric(self) -> bool: >>> a = xr.DataArray([0.5, 0, 0, 0.5, 2, 3]) >>> _Normalize(a).data_is_numeric True + + >>> # TODO: Datetime should be numeric right? + >>> a = xr.DataArray(pd.date_range("2000-1-1", periods=4)) + >>> _Normalize(a).data_is_numeric + False + + # TODO: Timedelta should be numeric right? + >>> a = xr.DataArray(pd.timedelta_range("-1D", periods=4, freq="D")) + >>> _Normalize(a).data_is_numeric + True """ return self._data_is_numeric diff --git a/xarray/tests/test_plot.py b/xarray/tests/test_plot.py index 18ca49670ba..8b2dfbdec41 100644 --- a/xarray/tests/test_plot.py +++ b/xarray/tests/test_plot.py @@ -2708,23 +2708,32 @@ def test_bad_args( x=x, y=y, hue=hue, add_legend=add_legend, add_colorbar=add_colorbar ) - @pytest.mark.xfail(reason="datetime,timedelta hue variable not supported.") - @pytest.mark.parametrize("hue_style", ["discrete", "continuous"]) - def test_datetime_hue(self, hue_style: Literal["discrete", "continuous"]) -> None: + def test_datetime_hue(self) -> None: ds2 = self.ds.copy() + + # TODO: Currently plots as categorical, should it behave as numerical? ds2["hue"] = pd.date_range("2000-1-1", periods=4) - ds2.plot.scatter(x="A", y="B", hue="hue", hue_style=hue_style) + ds2.plot.scatter(x="A", y="B", hue="hue") ds2["hue"] = pd.timedelta_range("-1D", periods=4, freq="D") - ds2.plot.scatter(x="A", y="B", hue="hue", hue_style=hue_style) + ds2.plot.scatter(x="A", y="B", hue="hue") - @pytest.mark.parametrize("hue_style", ["discrete", "continuous"]) - def test_facetgrid_hue_style( - self, hue_style: Literal["discrete", "continuous"] - ) -> None: - g = self.ds.plot.scatter( - x="A", y="B", row="row", col="col", hue="hue", hue_style=hue_style - ) + def test_facetgrid_hue_style(self) -> None: + ds2 = self.ds.copy() + + # Numbers plots as continous: + g = ds2.plot.scatter(x="A", y="B", row="row", col="col", hue="hue") + assert isinstance(g._mappables[-1], mpl.collections.PathCollection) + + # Datetimes plots as categorical: + # TODO: Currently plots as categorical, should it behave as numerical? + ds2["hue"] = pd.date_range("2000-1-1", periods=4) + g = ds2.plot.scatter(x="A", y="B", row="row", col="col", hue="hue") + assert isinstance(g._mappables[-1], mpl.collections.PathCollection) + + # Strings plots as categorical: + ds2["hue"] = ["a", "a", "b", "b"] + g = ds2.plot.scatter(x="A", y="B", row="row", col="col", hue="hue") assert isinstance(g._mappables[-1], mpl.collections.PathCollection) @pytest.mark.parametrize(