Skip to content

Commit 808755d

Browse files
committed
data_kind: Now 'matrix' represents a 2-D numpy array and unrecognizd data types fall back to 'vectors'
1 parent 0c82b3c commit 808755d

File tree

2 files changed

+37
-34
lines changed

2 files changed

+37
-34
lines changed

pygmt/clib/session.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,10 +1790,7 @@ def virtualfile_in( # noqa: PLR0912
17901790
"grid": self.virtualfile_from_grid,
17911791
"image": tempfile_from_image,
17921792
"stringio": self.virtualfile_from_stringio,
1793-
# Note: virtualfile_from_matrix is not used because a matrix can be
1794-
# converted to vectors instead, and using vectors allows for better
1795-
# handling of string type inputs (e.g. for datetime data types)
1796-
"matrix": self.virtualfile_from_vectors,
1793+
"matrix": self.virtualfile_from_matrix,
17971794
"vectors": self.virtualfile_from_vectors,
17981795
}[kind]
17991796

@@ -1810,29 +1807,32 @@ def virtualfile_in( # noqa: PLR0912
18101807
warnings.warn(message=msg, category=RuntimeWarning, stacklevel=2)
18111808
_data = (data,) if not isinstance(data, pathlib.PurePath) else (str(data),)
18121809
elif kind == "vectors":
1813-
_data = [np.atleast_1d(x), np.atleast_1d(y)]
1814-
if z is not None:
1815-
_data.append(np.atleast_1d(z))
1816-
if extra_arrays:
1817-
_data.extend(extra_arrays)
1818-
elif kind == "matrix": # turn 2-D arrays into list of vectors
1819-
if hasattr(data, "items") and not hasattr(data, "to_frame"):
1810+
if data is None:
1811+
# data is None, so data must be given via x/y/z.
1812+
_data = [np.atleast_1d(x), np.atleast_1d(y)]
1813+
if z is not None:
1814+
_data.append(np.atleast_1d(z))
1815+
if extra_arrays:
1816+
_data.extend(extra_arrays)
1817+
elif hasattr(data, "items") and not hasattr(data, "to_frame"):
18201818
# pandas.DataFrame or xarray.Dataset types.
18211819
# pandas.Series will be handled below like a 1-D numpy.ndarray.
18221820
_data = [array for _, array in data.items()]
1823-
elif hasattr(data, "ndim") and data.ndim == 2 and data.dtype.kind in "iuf":
1824-
# Just use virtualfile_from_matrix for 2-D numpy.ndarray
1825-
# which are signed integer (i), unsigned integer (u) or
1826-
# floating point (f) types
1827-
_virtualfile_from = self.virtualfile_from_matrix
1828-
_data = (data,)
18291821
else:
18301822
# Python list, tuple, numpy.ndarray, and pandas.Series types
18311823
_data = np.atleast_2d(np.asanyarray(data).T)
1824+
elif kind == "matrix":
1825+
# GMT can only accept a 2-D matrix which are signed integer (i), unsigned
1826+
# integer (u) or floating point (f) types. For other data types, we need to
1827+
# use virtualfile_from_vectors instead, which turns the matrix into list of
1828+
# vectors and allows for better handling of string type inputs (e.g. for
1829+
# datetime data types).
1830+
_data = (data,)
1831+
if data.dtype.kind not in "iuf":
1832+
_virtualfile_from = self.virtualfile_from_vectors
18321833

18331834
# Finally create the virtualfile from the data, to be passed into GMT
18341835
file_context = _virtualfile_from(*_data)
1835-
18361836
return file_context
18371837

18381838
def virtualfile_from_data(

pygmt/helpers/utils.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from collections.abc import Iterable, Sequence
1515
from typing import Any, Literal
1616

17+
import numpy as np
1718
import xarray as xr
1819
from pygmt.encodings import charset
1920
from pygmt.exceptions import GMTInvalidInput
@@ -205,8 +206,10 @@ def data_kind( # noqa: PLR0911
205206
(e.g., geopandas.GeoDataFrame or shapely.geometry)
206207
- ``"grid"``: a :class:`xarray.DataArray` object that is not 3-D
207208
- ``"image"``: a 3-D :class:`xarray.DataArray` object
208-
- ``"matrix"``: anything that is not None
209-
- ``"vectors"``: data is ``None`` and ``required=True``
209+
- ``"matrix"``: a 2-D :class:`numpy.ndarray` object
210+
- ``"vectors"``: fallback to ``"vectors"`` for any unrecognized data. Common data
211+
types include, a :class:`pandas.DataFrame` object, a dictionary with array-like
212+
values, a 1-D/3-D :class:`numpy.ndarray` object, or array-like objects.
210213
211214
Parameters
212215
----------
@@ -266,27 +269,27 @@ def data_kind( # noqa: PLR0911
266269
267270
The "matrix"`` kind:
268271
269-
>>> data_kind(data=np.arange(10)) # 1-D numpy.ndarray
270-
'matrix'
271272
>>> data_kind(data=np.arange(10).reshape((5, 2))) # 2-D numpy.ndarray
272273
'matrix'
274+
275+
The "vectors" kind:
276+
277+
>>> data_kind(data=np.arange(10)) # 1-D numpy.ndarray
278+
'vectors'
273279
>>> data_kind(data=np.arange(60).reshape((3, 4, 5))) # 3-D numpy.ndarray
274-
'matrix'
280+
'vectors'
275281
>>> data_kind(xr.DataArray(np.arange(12), name="x").to_dataset()) # xarray.Dataset
276-
'matrix'
282+
'vectors'
277283
>>> data_kind(data=[1, 2, 3]) # 1-D sequence
278-
'matrix'
284+
'vectors'
279285
>>> data_kind(data=[[1, 2, 3], [4, 5, 6]]) # sequence of sequences
280-
'matrix'
286+
'vectors'
281287
>>> data_kind(data={"x": [1, 2, 3], "y": [4, 5, 6]}) # dictionary
282-
'matrix'
288+
'vectors'
283289
>>> data_kind(data=pd.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})) # pd.DataFrame
284-
'matrix'
290+
'vectors'
285291
>>> data_kind(data=pd.Series([1, 2, 3], name="x")) # pd.Series
286-
'matrix'
287-
288-
The "vectors" kind:
289-
292+
'vectors'
290293
>>> data_kind(data=None)
291294
'vectors'
292295
"""
@@ -315,8 +318,8 @@ def data_kind( # noqa: PLR0911
315318
if hasattr(data, "__geo_interface__"):
316319
return "geojson"
317320

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

322325
return "vectors"

0 commit comments

Comments
 (0)