Repository: GenericMappingTools/pygmt

Issue:
Rename the sizes parameter in plot/plot3d to be size
**Description of the problem**

Both [plot](https://www.pygmt.org/latest/api/generated/pygmt.Figure.plot.html#pygmt.Figure.plot) and [plot3d](https://www.pygmt.org/latest/api/generated/pygmt.Figure.plot3d.html#pygmt.Figure.plot3d) have the `sizes` parameter that are used to plot symbols with different sizes. However, `size` is used in GMT documentation. Shall we rename this parameter to be `size`? If yes, I think we should do it as early as possible cause this parameter is often used in PyGMT.

Originally posted in https://github.com/GenericMappingTools/pygmt/issues/1076#issuecomment-804986728: 
> > like the `sizes` parameter (I dont' understand why we add a **s** at the end) of the `plot`/`plot3d` method
> 
> `plot` is one of the oldest wrappers in PyGMT, and the parameters are not carefully chosen. We had some discussions in the GMT Community meeting, and I think we agree that we will change `sizes` to `size`.

----

See the format of the [**-S**](https://docs.generic-mapping-tools.org/latest/plot.html#s) option in GMT `plot`:

> x y [ z ] [ size ] [ symbol-parameters ] [ symbol ]

See the format of the [**-S**](https://docs.generic-mapping-tools.org/latest/plot3d.html#s) option in GMT `plot3d`:

> x y z [ w ] [ size ] [ symbol-parameters ] [ symbol ]


GMT plot | PyGMT plot | GMT plot3d | PyGMT plot3d
:---: | :---:|:---: | :---:
*z* | `color` | *w* | `color`
*size* | `sizes` | *size* | `sizes`
*intensity* | `intensity` |*intensity* | `intensity` 
*symbol* | `symbol` (requested in #1076) | *symbol* | `symbol` (requested in #1076)


---

Now, `sizes` is used in the following files:
- `src/plot.py`
- `tests/test_plot.py`
- `examples/tutorials/plot.py`
- `examples/gallery/symbols/scatter.py`
- `examples/gallery/symbols/points_categorical.py`
- `src/plot3d.py`
- `tests/test_plot3d.py`
- `examples/gallery/3d_plots/scatter3d.py`


Discussion:

Patch:
diff --git a/examples/gallery/3d_plots/scatter3d.py b/examples/gallery/3d_plots/scatter3d.py
index 568c2de7..0c70581f 100644
--- a/examples/gallery/3d_plots/scatter3d.py
+++ b/examples/gallery/3d_plots/scatter3d.py
@@ -47,7 +47,7 @@ fig.plot3d(
     y=df.sepal_length,
     z=df.petal_length,
     # Vary each symbol size according to another feature (sepal width, scaled by 0.1)
-    sizes=0.1 * df.sepal_width,
+    size=0.1 * df.sepal_width,
     # Use 3D cubes ("u") as symbols, with size in centimeter units ("c")
     style="uc",
     # Points colored by categorical number code
diff --git a/pygmt/src/plot3d.py b/pygmt/src/plot3d.py
index 85b4826c..e6944c8e 100644
--- a/pygmt/src/plot3d.py
+++ b/pygmt/src/plot3d.py
@@ -6,6 +6,7 @@ from pygmt.exceptions import GMTInvalidInput
 from pygmt.helpers import (
     build_arg_string,
     data_kind,
+    deprecate_parameter,
     fmt_docstring,
     is_nonstr_iter,
     kwargs_to_strings,
@@ -43,8 +44,9 @@ from pygmt.helpers import (
     t="transparency",
 )
 @kwargs_to_strings(R="sequence", c="sequence_comma", i="sequence_comma", p="sequence")
+@deprecate_parameter("sizes", "size", "v0.4.0", remove_version="v0.6.0")
 def plot3d(
-    self, x=None, y=None, z=None, data=None, sizes=None, direction=None, **kwargs
+    self, x=None, y=None, z=None, data=None, size=None, direction=None, **kwargs
 ):
     r"""
     Plot lines, polygons, and symbols in 3-D.
@@ -80,8 +82,8 @@ def plot3d(
         Either a data file name or a 2d numpy array with the tabular data.
         Use parameter ``columns`` to choose which columns are x, y, z,
         color, and size, respectively.
-    sizes : 1d array
-        The sizes of the data points in units specified in ``style``.
+    size : 1d array
+        The size of the data points in units specified in ``style``.
         Only valid if using ``x``/``y``/``z``.
     direction : list of two 1d arrays
         If plotting vectors (using ``style='V'`` or ``style='v'``), then
@@ -179,12 +181,12 @@ def plot3d(
             )
         extra_arrays.append(kwargs["G"])
         del kwargs["G"]
-    if sizes is not None:
+    if size is not None:
         if kind != "vectors":
             raise GMTInvalidInput(
-                "Can't use arrays for sizes if data is matrix or file."
+                "Can't use arrays for 'size' if data is a matrix or a file."
             )
-        extra_arrays.append(sizes)
+        extra_arrays.append(size)
 
     for flag in ["I", "t"]:
         if flag in kwargs and is_nonstr_iter(kwargs[flag]):


Test patch:
diff --git a/pygmt/tests/test_plot3d.py b/pygmt/tests/test_plot3d.py
index 492e95a9..05708f7f 100644
--- a/pygmt/tests/test_plot3d.py
+++ b/pygmt/tests/test_plot3d.py
@@ -110,7 +110,7 @@ def test_plot3d_fail_no_data(data, region):
 
 def test_plot3d_fail_color_size_intensity(data, region):
     """
-    Should raise an exception if array color, sizes and intensity are used with
+    Should raise an exception if array color, size and intensity are used with
     matrix.
     """
     fig = Figure()
@@ -118,7 +118,7 @@ def test_plot3d_fail_color_size_intensity(data, region):
     with pytest.raises(GMTInvalidInput):
         fig.plot3d(style="c0.2c", color=data[:, 2], **kwargs)
     with pytest.raises(GMTInvalidInput):
-        fig.plot3d(style="cc", sizes=data[:, 2], color="red", **kwargs)
+        fig.plot3d(style="cc", size=data[:, 2], color="red", **kwargs)
     with pytest.raises(GMTInvalidInput):
         fig.plot3d(style="cc", intensity=data[:, 2], color="red", **kwargs)
 
@@ -178,7 +178,7 @@ def test_plot3d_sizes(data, region):
         z=data[:, 2],
         zscale=5,
         perspective=[225, 30],
-        sizes=0.5 * data[:, 2],
+        size=0.5 * data[:, 2],
         region=region,
         projection="X10c",
         # Using inches instead of cm because of upstream bug at
@@ -203,7 +203,7 @@ def test_plot3d_colors_sizes(data, region):
         zscale=5,
         perspective=[225, 30],
         color=data[:, 2],
-        sizes=0.5 * data[:, 2],
+        size=0.5 * data[:, 2],
         region=region,
         projection="X6c",
         # Using inches instead of cm because of upstream bug at
@@ -231,7 +231,7 @@ def test_plot3d_colors_sizes_proj(data, region):
         projection="M20c",
         frame=["af", "zaf"],
         color=data[:, 2],
-        sizes=data[:, 2],
+        size=data[:, 2],
         # Using inches instead of cm because of upstream bug at
         # https://github.com/GenericMappingTools/gmt/issues/4386
         style="ui",
@@ -343,7 +343,7 @@ def test_plot3d_sizes_colors_transparencies():
         frame=True,
         style="uc",
         color=color,
-        sizes=size,
+        size=size,
         cmap="gray",
         transparency=transparency,
     )
@@ -458,3 +458,30 @@ def test_plot3d_scalar_xyz():
         x=1.5, y=-1.5, z=1.5, style="s1c", color="blue", zscale=True, perspective=True
     )
     return fig
+
+
+@pytest.mark.mpl_image_compare(filename="test_plot3d_sizes.png")
+def test_plot3d_deprecate_sizes_to_size(data, region):
+    """
+    Make sure that the old parameter "sizes" is supported and it reports an
+    warning.
+
+    Modified from the test_plot3d_sizes() test.
+    """
+    fig = Figure()
+    with pytest.warns(expected_warning=FutureWarning) as record:
+        fig.plot3d(
+            x=data[:, 0],
+            y=data[:, 1],
+            z=data[:, 2],
+            zscale=5,
+            perspective=[225, 30],
+            sizes=0.5 * data[:, 2],
+            region=region,
+            projection="X10c",
+            style="ui",
+            color="blue",
+            frame=["af", "zaf"],
+        )
+        assert len(record) == 1  # check that only one warning was raised
+    return fig