Skip to content

Commit

Permalink
data_kind: Now 'matrix' represents a 2-D numpy array and unrecognizd …
Browse files Browse the repository at this point in the history
…data types fall back to 'vectors'
  • Loading branch information
seisman committed Oct 3, 2024
1 parent 0c82b3c commit 808755d
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 34 deletions.
36 changes: 18 additions & 18 deletions pygmt/clib/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -1790,10 +1790,7 @@ def virtualfile_in( # noqa: PLR0912
"grid": self.virtualfile_from_grid,
"image": tempfile_from_image,
"stringio": self.virtualfile_from_stringio,
# Note: virtualfile_from_matrix is not used because a matrix can be
# converted to vectors instead, and using vectors allows for better
# handling of string type inputs (e.g. for datetime data types)
"matrix": self.virtualfile_from_vectors,
"matrix": self.virtualfile_from_matrix,
"vectors": self.virtualfile_from_vectors,
}[kind]

Expand All @@ -1810,29 +1807,32 @@ 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 == "vectors":
_data = [np.atleast_1d(x), np.atleast_1d(y)]
if z is not None:
_data.append(np.atleast_1d(z))
if extra_arrays:
_data.extend(extra_arrays)
elif kind == "matrix": # turn 2-D arrays into list of vectors
if hasattr(data, "items") and not hasattr(data, "to_frame"):
if data is None:
# data is None, so data must be given via x/y/z.
_data = [np.atleast_1d(x), np.atleast_1d(y)]
if z is not None:
_data.append(np.atleast_1d(z))
if extra_arrays:
_data.extend(extra_arrays)
elif 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()]
elif hasattr(data, "ndim") and data.ndim == 2 and data.dtype.kind in "iuf":
# Just use virtualfile_from_matrix for 2-D numpy.ndarray
# which are signed integer (i), unsigned integer (u) or
# floating point (f) types
_virtualfile_from = self.virtualfile_from_matrix
_data = (data,)
else:
# Python list, tuple, numpy.ndarray, and pandas.Series types
_data = np.atleast_2d(np.asanyarray(data).T)
elif kind == "matrix":
# GMT can only accept a 2-D matrix which are signed integer (i), unsigned
# integer (u) or floating point (f) types. For other data types, we need to
# use virtualfile_from_vectors instead, which turns the matrix into list of
# vectors and allows for better handling of string type inputs (e.g. for
# datetime data types).
_data = (data,)
if data.dtype.kind not in "iuf":
_virtualfile_from = self.virtualfile_from_vectors

Check warning on line 1832 in pygmt/clib/session.py

View check run for this annotation

Codecov / codecov/patch

pygmt/clib/session.py#L1832

Added line #L1832 was not covered by tests

# Finally create the virtualfile from the data, to be passed into GMT
file_context = _virtualfile_from(*_data)

return file_context

def virtualfile_from_data(
Expand Down
35 changes: 19 additions & 16 deletions pygmt/helpers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from collections.abc import Iterable, Sequence
from typing import Any, Literal

import numpy as np
import xarray as xr
from pygmt.encodings import charset
from pygmt.exceptions import GMTInvalidInput
Expand Down Expand Up @@ -205,8 +206,10 @@ def data_kind( # noqa: PLR0911
(e.g., geopandas.GeoDataFrame or shapely.geometry)
- ``"grid"``: a :class:`xarray.DataArray` object that is not 3-D
- ``"image"``: a 3-D :class:`xarray.DataArray` object
- ``"matrix"``: anything that is not None
- ``"vectors"``: data is ``None`` and ``required=True``
- ``"matrix"``: a 2-D :class:`numpy.ndarray` object
- ``"vectors"``: fallback to ``"vectors"`` for 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 @@ -266,27 +269,27 @@ def data_kind( # noqa: PLR0911
The "matrix"`` kind:
>>> data_kind(data=np.arange(10)) # 1-D numpy.ndarray
'matrix'
>>> data_kind(data=np.arange(10).reshape((5, 2))) # 2-D numpy.ndarray
'matrix'
The "vectors" kind:
>>> data_kind(data=np.arange(10)) # 1-D numpy.ndarray
'vectors'
>>> data_kind(data=np.arange(60).reshape((3, 4, 5))) # 3-D numpy.ndarray
'matrix'
'vectors'
>>> data_kind(xr.DataArray(np.arange(12), name="x").to_dataset()) # xarray.Dataset
'matrix'
'vectors'
>>> data_kind(data=[1, 2, 3]) # 1-D sequence
'matrix'
'vectors'
>>> data_kind(data=[[1, 2, 3], [4, 5, 6]]) # sequence of sequences
'matrix'
'vectors'
>>> data_kind(data={"x": [1, 2, 3], "y": [4, 5, 6]}) # dictionary
'matrix'
'vectors'
>>> data_kind(data=pd.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})) # pd.DataFrame
'matrix'
'vectors'
>>> data_kind(data=pd.Series([1, 2, 3], name="x")) # pd.Series
'matrix'
The "vectors" kind:
'vectors'
>>> data_kind(data=None)
'vectors'
"""
Expand Down Expand Up @@ -315,8 +318,8 @@ def data_kind( # noqa: PLR0911
if hasattr(data, "__geo_interface__"):
return "geojson"

# Any not-None is considered as a matrix.
if data is not None:
# A 2-D numpy.ndarray.
if isinstance(data, np.ndarray) and data.ndim == 2:
return "matrix"

return "vectors"
Expand Down

0 comments on commit 808755d

Please sign in to comment.