-
Notifications
You must be signed in to change notification settings - Fork 229
Refactor the data_kind and validate_data_input functions #3335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
e79a7d0
e2a8ceb
008a56f
46fb307
d3854da
a9670aa
7ff0d9e
70962d0
b575591
c522e36
0bde17d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -12,74 +12,78 @@ | |||||
import warnings | ||||||
import webbrowser | ||||||
from collections.abc import Iterable, Sequence | ||||||
from typing import Any | ||||||
from typing import Any, Literal | ||||||
|
||||||
import xarray as xr | ||||||
from pygmt.encodings import charset | ||||||
from pygmt.exceptions import GMTInvalidInput | ||||||
|
||||||
|
||||||
def _validate_data_input( | ||||||
def validate_data_input( | ||||||
data=None, x=None, y=None, z=None, required_z=False, required_data=True, kind=None | ||||||
): | ||||||
""" | ||||||
Check if the combination of data/x/y/z is valid. | ||||||
|
||||||
Examples | ||||||
-------- | ||||||
>>> _validate_data_input(data="infile") | ||||||
>>> _validate_data_input(x=[1, 2, 3], y=[4, 5, 6]) | ||||||
>>> _validate_data_input(x=[1, 2, 3], y=[4, 5, 6], z=[7, 8, 9]) | ||||||
>>> _validate_data_input(data=None, required_data=False) | ||||||
>>> _validate_data_input() | ||||||
>>> validate_data_input(data="infile") | ||||||
>>> validate_data_input(x=[1, 2, 3], y=[4, 5, 6]) | ||||||
>>> validate_data_input(x=[1, 2, 3], y=[4, 5, 6], z=[7, 8, 9]) | ||||||
>>> validate_data_input(data=None, required_data=False) | ||||||
>>> validate_data_input() | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: No input data provided. | ||||||
>>> _validate_data_input(x=[1, 2, 3]) | ||||||
>>> validate_data_input(x=[1, 2, 3]) | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: Must provide both x and y. | ||||||
>>> _validate_data_input(y=[4, 5, 6]) | ||||||
>>> validate_data_input(y=[4, 5, 6]) | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: Must provide both x and y. | ||||||
>>> _validate_data_input(x=[1, 2, 3], y=[4, 5, 6], required_z=True) | ||||||
>>> validate_data_input(x=[1, 2, 3], y=[4, 5, 6], required_z=True) | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: Must provide x, y, and z. | ||||||
>>> import numpy as np | ||||||
>>> import pandas as pd | ||||||
>>> import xarray as xr | ||||||
>>> data = np.arange(8).reshape((4, 2)) | ||||||
>>> _validate_data_input(data=data, required_z=True, kind="matrix") | ||||||
>>> validate_data_input(data=data, required_z=True, kind="matrix") | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: data must provide x, y, and z columns. | ||||||
>>> _validate_data_input( | ||||||
>>> validate_data_input( | ||||||
... data=pd.DataFrame(data, columns=["x", "y"]), | ||||||
... required_z=True, | ||||||
... kind="matrix", | ||||||
... ) | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: data must provide x, y, and z columns. | ||||||
>>> _validate_data_input( | ||||||
>>> validate_data_input( | ||||||
... data=xr.Dataset(pd.DataFrame(data, columns=["x", "y"])), | ||||||
... required_z=True, | ||||||
... kind="matrix", | ||||||
... ) | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: data must provide x, y, and z columns. | ||||||
>>> _validate_data_input(data="infile", x=[1, 2, 3]) | ||||||
>>> validate_data_input(data="infile", x=[1, 2, 3]) | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: Too much data. Use either data or x/y/z. | ||||||
>>> _validate_data_input(data="infile", y=[4, 5, 6]) | ||||||
>>> validate_data_input(data="infile", y=[4, 5, 6]) | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: Too much data. Use either data or x/y/z. | ||||||
>>> _validate_data_input(data="infile", z=[7, 8, 9]) | ||||||
>>> validate_data_input(data="infile", x=[1, 2, 3], y=[4, 5, 6]) | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: Too much data. Use either data or x/y/z. | ||||||
>>> validate_data_input(data="infile", z=[7, 8, 9]) | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: Too much data. Use either data or x/y/z. | ||||||
|
@@ -111,7 +115,9 @@ def _validate_data_input( | |||||
raise GMTInvalidInput("data must provide x, y, and z columns.") | ||||||
|
||||||
|
||||||
def data_kind(data=None, x=None, y=None, z=None, required_z=False, required_data=True): | ||||||
def data_kind( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now this function only checks |
||||||
data: Any = None, required: bool = True | ||||||
) -> Literal["arg", "file", "geojson", "grid", "image", "matrix", "vectors"]: | ||||||
""" | ||||||
Check what kind of data is provided to a module. | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since x/y/z is no longer used, at L124-129, change the docstring to read:
|
||||||
|
@@ -124,50 +130,39 @@ def data_kind(data=None, x=None, y=None, z=None, required_z=False, required_data | |||||
* 1-D arrays x and y (and z, optionally) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Delete this line about x/y/z?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated the docstring at b575591. Currently, any unrecognized data type is taken as a |
||||||
* an optional argument (None, bool, int or float) provided as 'data' | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
Arguments should be ``None`` if not used. If doesn't fit any of these | ||||||
categories (or fits more than one), will raise an exception. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
data : str, pathlib.PurePath, None, bool, xarray.DataArray or {table-like} | ||||||
Pass in either a file name or :class:`pathlib.Path` to an ASCII data | ||||||
table, an :class:`xarray.DataArray`, a 1-D/2-D | ||||||
{table-classes} or an option argument. | ||||||
x/y : 1-D arrays or None | ||||||
x and y columns as numpy arrays. | ||||||
z : 1-D array or None | ||||||
z column as numpy array. To be used optionally when x and y are given. | ||||||
required_z : bool | ||||||
State whether the 'z' column is required. | ||||||
required_data : bool | ||||||
required | ||||||
Set to True when 'data' is required, or False when dealing with | ||||||
optional virtual files. [Default is True]. | ||||||
|
||||||
Returns | ||||||
------- | ||||||
kind : str | ||||||
One of ``'arg'``, ``'file'``, ``'grid'``, ``image``, ``'geojson'``, | ||||||
``'matrix'``, or ``'vectors'``. | ||||||
kind | ||||||
The data kind. | ||||||
|
||||||
Examples | ||||||
-------- | ||||||
|
||||||
>>> import numpy as np | ||||||
>>> import xarray as xr | ||||||
>>> import pathlib | ||||||
>>> data_kind(data=None, x=np.array([1, 2, 3]), y=np.array([4, 5, 6])) | ||||||
>>> data_kind(data=None) | ||||||
'vectors' | ||||||
>>> data_kind(data=np.arange(10).reshape((5, 2)), x=None, y=None) | ||||||
>>> data_kind(data=np.arange(10).reshape((5, 2))) | ||||||
'matrix' | ||||||
>>> data_kind(data="my-data-file.txt", x=None, y=None) | ||||||
>>> data_kind(data="my-data-file.txt") | ||||||
'file' | ||||||
>>> data_kind(data=pathlib.Path("my-data-file.txt"), x=None, y=None) | ||||||
>>> data_kind(data=pathlib.Path("my-data-file.txt")) | ||||||
'file' | ||||||
>>> data_kind(data=None, x=None, y=None, required_data=False) | ||||||
>>> data_kind(data=None, required=False) | ||||||
'arg' | ||||||
>>> data_kind(data=2.0, x=None, y=None, required_data=False) | ||||||
>>> data_kind(data=2.0, required=False) | ||||||
'arg' | ||||||
>>> data_kind(data=True, x=None, y=None, required_data=False) | ||||||
>>> data_kind(data=True, required=False) | ||||||
'arg' | ||||||
>>> data_kind(data=xr.DataArray(np.random.rand(4, 3))) | ||||||
'grid' | ||||||
|
@@ -181,7 +176,7 @@ def data_kind(data=None, x=None, y=None, z=None, required_z=False, required_data | |||||
): | ||||||
# One or more files | ||||||
kind = "file" | ||||||
elif isinstance(data, bool | int | float) or (data is None and not required_data): | ||||||
elif isinstance(data, bool | int | float) or (data is None and not required): | ||||||
kind = "arg" | ||||||
elif isinstance(data, xr.DataArray): | ||||||
kind = "image" if len(data.dims) == 3 else "grid" | ||||||
|
@@ -193,15 +188,6 @@ def data_kind(data=None, x=None, y=None, z=None, required_z=False, required_data | |||||
kind = "matrix" | ||||||
else: | ||||||
kind = "vectors" | ||||||
_validate_data_input( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed from here and moved to |
||||||
data=data, | ||||||
x=x, | ||||||
y=y, | ||||||
z=z, | ||||||
required_z=required_z, | ||||||
required_data=required_data, | ||||||
kind=kind, | ||||||
) | ||||||
return kind | ||||||
|
||||||
|
||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,18 +4,11 @@ | |
|
||
from pathlib import Path | ||
|
||
import numpy as np | ||
import pytest | ||
import xarray as xr | ||
from pygmt import Figure | ||
from pygmt.exceptions import GMTInvalidInput | ||
from pygmt.helpers import ( | ||
GMTTempFile, | ||
args_in_kwargs, | ||
data_kind, | ||
kwargs_to_strings, | ||
unique_name, | ||
) | ||
from pygmt.helpers import GMTTempFile, args_in_kwargs, kwargs_to_strings, unique_name | ||
from pygmt.helpers.testing import load_static_earth_relief, skip_if_no | ||
|
||
|
||
|
@@ -32,25 +25,6 @@ def test_load_static_earth_relief(): | |
assert isinstance(data, xr.DataArray) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test is removed because:
|
||
("data", "x", "y"), | ||
[ | ||
(None, None, None), | ||
("data.txt", np.array([1, 2]), np.array([4, 5])), | ||
("data.txt", np.array([1, 2]), None), | ||
("data.txt", None, np.array([4, 5])), | ||
(None, np.array([1, 2]), None), | ||
(None, None, np.array([4, 5])), | ||
], | ||
) | ||
def test_data_kind_fails(data, x, y): | ||
""" | ||
Make sure data_kind raises exceptions when it should. | ||
""" | ||
with pytest.raises(GMTInvalidInput): | ||
data_kind(data=data, x=x, y=y) | ||
|
||
|
||
def test_unique_name(): | ||
""" | ||
Make sure the names are really unique. | ||
|
Uh oh!
There was an error while loading. Please reload this page.