diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index a963442ecda1c..d9d1ce797dd62 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -193,6 +193,7 @@ Other enhancements - Where possible :meth:`RangeIndex.difference` and :meth:`RangeIndex.symmetric_difference` will return :class:`RangeIndex` instead of :class:`Int64Index` (:issue:`36564`) - Added :meth:`Rolling.sem()` and :meth:`Expanding.sem()` to compute the standard error of mean (:issue:`26476`). - :meth:`Rolling.var()` and :meth:`Rolling.std()` use Kahan summation and Welfords Method to avoid numerical issues (:issue:`37051`) +- :meth:`DataFrame.plot` now recognizes ``xlabel`` and ``ylabel`` arguments for plots of type ``scatter`` and ``hexbin`` (:issue:`37001`) .. _whatsnew_120.api_breaking.python: diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index d02f12a8e1029..e0e35e31d22ac 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -678,15 +678,25 @@ class PlotAccessor(PandasObject): ylim : 2-tuple/list Set the y limits of the current axes. xlabel : label, optional - Name to use for the xlabel on x-axis. Default uses index name as xlabel. + Name to use for the xlabel on x-axis. Default uses index name as xlabel, or the + x-column name for planar plots. .. versionadded:: 1.1.0 + .. versionchanged:: 1.2.0 + + Now applicable to planar plots (`scatter`, `hexbin`). + ylabel : label, optional - Name to use for the ylabel on y-axis. Default will show no ylabel. + Name to use for the ylabel on y-axis. Default will show no ylabel, or the + y-column name for planar plots. .. versionadded:: 1.1.0 + .. versionchanged:: 1.2.0 + + Now applicable to planar plots (`scatter`, `hexbin`). + rot : int, default None Rotation for ticks (xticks for vertical, yticks for horizontal plots). diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index a69767df267fc..6c9924e0ada79 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -924,8 +924,10 @@ def nseries(self) -> int: def _post_plot_logic(self, ax: "Axes", data): x, y = self.x, self.y - ax.set_ylabel(pprint_thing(y)) - ax.set_xlabel(pprint_thing(x)) + xlabel = self.xlabel if self.xlabel is not None else pprint_thing(x) + ylabel = self.ylabel if self.ylabel is not None else pprint_thing(y) + ax.set_xlabel(xlabel) + ax.set_ylabel(ylabel) def _plot_colorbar(self, ax: "Axes", **kwds): # Addresses issues #10611 and #10678: diff --git a/pandas/tests/plotting/test_frame.py b/pandas/tests/plotting/test_frame.py index d4d2256d209cf..e666a8e412a52 100644 --- a/pandas/tests/plotting/test_frame.py +++ b/pandas/tests/plotting/test_frame.py @@ -3449,6 +3449,27 @@ def test_xlabel_ylabel_dataframe_single_plot( assert ax.get_ylabel() == str(new_label) assert ax.get_xlabel() == str(new_label) + @pytest.mark.parametrize( + "xlabel, ylabel", + [ + (None, None), + ("X Label", None), + (None, "Y Label"), + ("X Label", "Y Label"), + ], + ) + @pytest.mark.parametrize("kind", ["scatter", "hexbin"]) + def test_xlabel_ylabel_dataframe_plane_plot(self, kind, xlabel, ylabel): + # GH 37001 + xcol = "Type A" + ycol = "Type B" + df = pd.DataFrame([[1, 2], [2, 5]], columns=[xcol, ycol]) + + # default is the labels are column names + ax = df.plot(kind=kind, x=xcol, y=ycol, xlabel=xlabel, ylabel=ylabel) + assert ax.get_xlabel() == (xcol if xlabel is None else xlabel) + assert ax.get_ylabel() == (ycol if ylabel is None else ylabel) + @pytest.mark.parametrize( "index_name, old_label, new_label", [