diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index e7efe125c25..ba6f87763d9 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -1773,7 +1773,7 @@ def virtualfile_in( # noqa: PLR0912 if check_kind == "raster": valid_kinds += ("grid", "image") elif check_kind == "vector": - valid_kinds += ("matrix", "vectors", "geojson") + valid_kinds += ("empty", "matrix", "vectors", "geojson") if kind not in valid_kinds: raise GMTInvalidInput( f"Unrecognized data type for {check_kind}: {type(data)}" @@ -1781,8 +1781,9 @@ def virtualfile_in( # noqa: PLR0912 # Decide which virtualfile_from_ function to use _virtualfile_from = { - "file": contextlib.nullcontext, "arg": contextlib.nullcontext, + "empty": self.virtualfile_from_vectors, + "file": contextlib.nullcontext, "geojson": tempfile_from_geojson, "grid": self.virtualfile_from_grid, "image": tempfile_from_image, @@ -1803,15 +1804,15 @@ def virtualfile_in( # noqa: PLR0912 ) warnings.warn(message=msg, category=RuntimeWarning, stacklevel=2) _data = (data,) if not isinstance(data, pathlib.PurePath) else (str(data),) + elif kind == "empty": + # data is None, so data must be given via x/y/z. + _data = [x, y] + if z is not None: + _data.append(z) + if extra_arrays: + _data.extend(extra_arrays) elif kind == "vectors": - if data is None: - # data is None, so data must be given via x/y/z. - _data = [x, y] - if z is not None: - _data.append(z) - if extra_arrays: - _data.extend(extra_arrays) - elif hasattr(data, "items") and not hasattr(data, "to_frame"): + if hasattr(data, "items") and not hasattr(data, "to_frame"): # pandas.DataFrame or xarray.Dataset types. # pandas.Series will be handled below like a 1-D numpy.ndarray. _data = [array for _, array in data.items()] diff --git a/pygmt/helpers/utils.py b/pygmt/helpers/utils.py index 07c965ae277..ace5b6fe01f 100644 --- a/pygmt/helpers/utils.py +++ b/pygmt/helpers/utils.py @@ -190,7 +190,7 @@ def _check_encoding( def data_kind( data: Any, required: bool = True ) -> Literal[ - "arg", "file", "geojson", "grid", "image", "matrix", "stringio", "vectors" + "arg", "empty", "file", "geojson", "grid", "image", "matrix", "stringio", "vectors" ]: r""" Check the kind of data that is provided to a module. @@ -200,6 +200,8 @@ def data_kind( - ``"arg"``: ``data`` is ``None`` and ``required=False``, or bool, int, float, representing an optional argument, used for dealing with optional virtual files + - ``"empty"`: ``data`` is ``None`` and ``required=True``. It means the data is given + via a series of vectors like x/y/z - ``"file"``: a string or a :class:`pathlib.PurePath` object or a sequence of them, representing one or more file names - ``"geojson"``: a geo-like Python object that implements ``__geo_interface__`` @@ -209,10 +211,9 @@ def data_kind( - ``"stringio"``: a :class:`io.StringIO` object - ``"matrix"``: a 2-D array-like object that implements ``__array_interface__`` (e.g., :class:`numpy.ndarray`) - - ``"vectors"``: ``data`` is ``None`` and ``required=True``, or any unrecognized - data. Common data types include, a :class:`pandas.DataFrame` object, a dictionary - with array-like values, a 1-D/3-D :class:`numpy.ndarray` object, or array-like - objects. + - ``"vectors"``: any unrecognized data. Common data types include, a + :class:`pandas.DataFrame` object, a dictionary with array-like values, a 1-D/3-D + :class:`numpy.ndarray` object, or array-like objects. Parameters ---------- @@ -242,6 +243,11 @@ def data_kind( >>> data_kind(data=None, required=False) 'arg' + The "empty" kind: + + >>> data_kind(data=None, required=True) + 'empty' + The "file" kind: >>> [data_kind(data=data) for data in ("file.txt", ("file1.txt", "file2.txt"))] @@ -293,10 +299,10 @@ def data_kind( 'vectors' >>> data_kind(data=pd.Series([1, 2, 3], name="x")) # pd.Series 'vectors' - >>> data_kind(data=None) - 'vectors' """ match data: + case None if required: # No data provided and required=True. + kind = "empty" case str() | pathlib.PurePath(): # One file. kind = "file" case list() | tuple() if all( diff --git a/pygmt/src/legend.py b/pygmt/src/legend.py index ddc26cbd2eb..f6e2d61f34f 100644 --- a/pygmt/src/legend.py +++ b/pygmt/src/legend.py @@ -91,7 +91,7 @@ def legend( kwargs["F"] = box kind = data_kind(spec) - if spec is not None and kind not in {"file", "stringio"}: + if kind not in {"empty", "file", "stringio"}: raise GMTInvalidInput(f"Unrecognized data type: {type(spec)}") if kind == "file" and is_nonstr_iter(spec): raise GMTInvalidInput("Only one legend specification file is allowed.") diff --git a/pygmt/src/plot.py b/pygmt/src/plot.py index 61db357bfde..4565d02e0db 100644 --- a/pygmt/src/plot.py +++ b/pygmt/src/plot.py @@ -206,7 +206,7 @@ def plot(self, data=None, x=None, y=None, size=None, direction=None, **kwargs): kind = data_kind(data) extra_arrays = [] - if kind == "vectors": # Add more columns for vectors input + if kind == "empty": # Add more columns for vectors input # Parameters for vector styles if ( kwargs.get("S") is not None diff --git a/pygmt/src/plot3d.py b/pygmt/src/plot3d.py index 7c7a78f2ab3..31695a82464 100644 --- a/pygmt/src/plot3d.py +++ b/pygmt/src/plot3d.py @@ -184,7 +184,7 @@ def plot3d( kind = data_kind(data) extra_arrays = [] - if kind == "vectors": # Add more columns for vectors input + if kind == "empty": # Add more columns for vectors input # Parameters for vector styles if ( kwargs.get("S") is not None diff --git a/pygmt/src/text.py b/pygmt/src/text.py index 0f734f6e284..24835fc1881 100644 --- a/pygmt/src/text.py +++ b/pygmt/src/text.py @@ -196,7 +196,7 @@ def text_( # noqa: PLR0912 raise GMTInvalidInput("'text' can't be None or array when 'position' is given.") if textfiles is not None and text is not None: raise GMTInvalidInput("'text' can't be specified when 'textfiles' is given.") - if kind == "vectors" and text is None: + if kind == "empty" and text is None: raise GMTInvalidInput("Must provide text with x/y pairs.") # Arguments that can accept arrays. @@ -220,7 +220,7 @@ def text_( # noqa: PLR0912 extra_arrays = [] confdict = {} - if kind == "vectors": + if kind == "empty": for arg, flag, name in array_args: if is_nonstr_iter(arg): kwargs["F"] += flag