diff --git a/doc/source/getting_started/intro_tutorials/04_plotting.rst b/doc/source/getting_started/intro_tutorials/04_plotting.rst index e9f83c602d086..e963a63881cd8 100644 --- a/doc/source/getting_started/intro_tutorials/04_plotting.rst +++ b/doc/source/getting_started/intro_tutorials/04_plotting.rst @@ -108,7 +108,7 @@ I want to visually compare the :math:`NO_2` values measured in London versus Par :okwarning: @savefig 04_airqual_scatter.png - air_quality.plot.scatter(x="station_london", y="station_paris", alpha=0.5) + air_quality.plot.scatter(x="station_london", y="station_paris", s = 20, alpha=0.5) plt.show() .. raw:: html @@ -121,6 +121,7 @@ number of alternatives are available to plot data. Let’s use some standard Python to get an overview of the available plot methods: .. ipython:: python + :okwarning: [ method_name diff --git a/doc/source/user_guide/dsintro.rst b/doc/source/user_guide/dsintro.rst index 919dafb291b86..b025a5a0ae6cb 100644 --- a/doc/source/user_guide/dsintro.rst +++ b/doc/source/user_guide/dsintro.rst @@ -577,7 +577,7 @@ greater than 5, calculate the ratio, and plot: SepalRatio=lambda x: x.SepalWidth / x.SepalLength, PetalRatio=lambda x: x.PetalWidth / x.PetalLength, ) - .plot(kind="scatter", x="SepalRatio", y="PetalRatio") + .plot(kind="scatter", x="SepalRatio", y="PetalRatio", s = 20) ) Since a function is passed in, the function is computed on the DataFrame diff --git a/doc/source/user_guide/visualization.rst b/doc/source/user_guide/visualization.rst index 4b5cdca23103c..388b3d72a2b57 100644 --- a/doc/source/user_guide/visualization.rst +++ b/doc/source/user_guide/visualization.rst @@ -626,7 +626,7 @@ It is recommended to specify ``color`` and ``label`` keywords to distinguish eac ax = df.plot.scatter(x="a", y="b", color="DarkBlue", label="Group 1") @savefig scatter_plot_repeated.png - df.plot.scatter(x="c", y="d", color="DarkGreen", label="Group 2", ax=ax); + df.plot.scatter(x="c", y="d", color="DarkGreen", label="Group 2", ax=ax, s = 20); .. ipython:: python :suppress: diff --git a/doc/source/whatsnew/v2.1.0.rst b/doc/source/whatsnew/v2.1.0.rst index 2817945c55a86..9d9201d6bb1fa 100644 --- a/doc/source/whatsnew/v2.1.0.rst +++ b/doc/source/whatsnew/v2.1.0.rst @@ -785,6 +785,7 @@ Plotting ^^^^^^^^ - Bug in :meth:`Series.plot` when invoked with ``color=None`` (:issue:`51953`) - Fixed UserWarning in :meth:`DataFrame.plot.scatter` when invoked with ``c="b"`` (:issue:`53908`) +- Fixed bug in :meth:`DataFrame.plot.scatter` wherein marker size was previously hardcoded to a default value (:issue:`54204`) Groupby/resample/rolling ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index b8f59363b5107..62942778b0d5e 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -23,7 +23,10 @@ import numpy as np from pandas._libs import lib -from pandas.errors import AbstractMethodError +from pandas.errors import ( + AbstractMethodError, + PandasFutureWarning, +) from pandas.util._decorators import cache_readonly from pandas.util._exceptions import find_stack_level @@ -1325,8 +1328,17 @@ def __init__( **kwargs, ) -> None: if s is None: - # hide the matplotlib default for size, in case we want to change - # the handling of this argument later + # The default size of the elements in a scatter plot + # is 20, but this will change in a future version. + # In the future the value will be derived from + # mpl.rcParams["lines.markersize"] if not provided + warnings.warn( + "The default of s=20 will be changed to use " + "mpl.rcParams['lines.markersize'] in the future. " + "Specify `s` to suppress this warning", + PandasFutureWarning, + stacklevel=find_stack_level(), + ) s = 20 elif is_hashable(s) and s in data.columns: s = data[s] diff --git a/pandas/tests/plotting/test_misc.py b/pandas/tests/plotting/test_misc.py index 2d2ac1a437068..cbd287726c760 100644 --- a/pandas/tests/plotting/test_misc.py +++ b/pandas/tests/plotting/test_misc.py @@ -5,6 +5,7 @@ import numpy as np import pytest +from pandas.errors import PandasFutureWarning import pandas.util._test_decorators as td from pandas import ( @@ -864,3 +865,45 @@ def test_plot_bar_label_count_expected_success(): [(30, 10, 10, 10), (20, 20, 20, 20), (10, 30, 30, 10)], columns=list("ABCD") ) df.plot(subplots=[("A", "B", "D")], kind="bar", title=["A&B&D", "C"]) + + +def test_change_scatter_markersize_future_warning(): + # GH 54204 + # Will raise FutureWarning if s not provided to df.plot.scatter + df = DataFrame(data={"x": [1, 2, 3], "y": [1, 2, 3]}) + with tm.assert_produces_warning(PandasFutureWarning): + pandas_default_without_rcparams = df.plot.scatter( + x="x", y="y", title="pandas scatter, default rc marker size" + ) + # Verify that pandas still defaults to 20 + assert pandas_default_without_rcparams.collections[0].get_sizes()[0] == 20 + + +@pytest.mark.filterwarnings( + "ignore:The default of s=20 will be changed:pandas.errors.PandasFutureWarning" +) +def test_scatter_markersize_same_default_with_rcparams(): + # GH 54204 + # Ensure default markersize is still 20 if no rcparams + df = DataFrame(data={"x": [1, 2, 3], "y": [1, 2, 3]}) + with mpl.rc_context({"lines.markersize": 10}): + pandas_default_with_rcparams = df.plot.scatter( + x="x", y="y", title="pandas scatter, changed rc marker size" + ) + # Verify that pandas default markersize is still 20 with rc_params + assert pandas_default_with_rcparams.collections[0].get_sizes()[0] == 20 + + +@pytest.mark.filterwarnings( + "ignore:The default of s=20 will be changed:pandas.errors.PandasFutureWarning" +) +def test_scatter_markersize_same_default_without_rcparams(): + # GH 54204 + # Ensure default markersize is still 20 if no rcparams + df = DataFrame(data={"x": [1, 2, 3], "y": [1, 2, 3]}) + + pandas_default_with_rcparams = df.plot.scatter( + x="x", y="y", title="pandas scatter, changed rc marker size" + ) + # Verify that pandas default markersize is still 20 without rc_params + assert pandas_default_with_rcparams.collections[0].get_sizes()[0] == 20