Skip to content

Commit

Permalink
**Breaking**: data_kind: data is None and required now returns the 'e…
Browse files Browse the repository at this point in the history
…mpty' kind (#3482)

Co-authored-by: Wei Ji <[email protected]>
  • Loading branch information
seisman and weiji14 authored Oct 16, 2024
1 parent a5c0aa2 commit d41922c
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 22 deletions.
21 changes: 11 additions & 10 deletions pygmt/clib/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -1773,16 +1773,17 @@ 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)}"
)

# 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,
Expand All @@ -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()]
Expand Down
20 changes: 13 additions & 7 deletions pygmt/helpers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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__``
Expand All @@ -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
----------
Expand Down Expand Up @@ -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"))]
Expand Down Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion pygmt/src/legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.")
Expand Down
2 changes: 1 addition & 1 deletion pygmt/src/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion pygmt/src/plot3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down

0 comments on commit d41922c

Please sign in to comment.