Skip to content

Support timedelta64 dtype as input #2884

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

Merged
merged 11 commits into from
Jan 8, 2024
1 change: 1 addition & 0 deletions pygmt/clib/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
np.float64: "GMT_DOUBLE",
np.str_: "GMT_TEXT",
np.datetime64: "GMT_DATETIME",
np.timedelta64: "GMT_LONG",
}

# Load the GMT library outside the Session class to avoid repeated loading.
Expand Down
5 changes: 5 additions & 0 deletions pygmt/tests/baseline/test_plot_timedelta64.png.dvc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
outs:
- md5: 8edddcec764d244053c4d675e98732b9
size: 13201
path: test_plot_timedelta64.png
hash: md5
31 changes: 31 additions & 0 deletions pygmt/tests/test_clib_put_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,37 @@ def test_put_vector_string_dtype():
npt.assert_array_equal(output["y"], expected_vectors[j])


def test_put_vector_timedelta64_dtype():
"""
Passing timedelta64 type vectors with various time units (year, month,
week, day, hour, minute, second, millisecond, microsecond) to a dataset.
"""
for unit in ["Y", "M", "W", "D", "h", "m", "s", "ms", "μs"]:
with clib.Session() as lib, GMTTempFile() as tmp_file:
dataset = lib.create_data(
family="GMT_IS_DATASET|GMT_VIA_VECTOR",
geometry="GMT_IS_POINT",
mode="GMT_CONTAINER_ONLY",
dim=[1, 5, 1, 0], # columns, rows, layers, dtype
)
timedata = np.arange(np.timedelta64(0, unit), np.timedelta64(5, unit))
lib.put_vector(dataset, column=0, vector=timedata)
# Turns out wesn doesn't matter for Datasets
wesn = [0] * 6
# Save the data to a file to see if it's being accessed correctly
lib.write_data(
family="GMT_IS_VECTOR",
geometry="GMT_IS_POINT",
mode="GMT_WRITE_SET",
wesn=wesn,
output=tmp_file.name,
data=dataset,
)
# Load the data and check that it's correct
newtimedata = tmp_file.loadtxt(unpack=True, dtype=f"timedelta64[{unit}]")
npt.assert_equal(actual=newtimedata, desired=timedata)


def test_put_vector_invalid_dtype():
"""
Check that it fails with an exception for invalid data types.
Expand Down
20 changes: 20 additions & 0 deletions pygmt/tests/test_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,26 @@ def test_plot_datetime():
return fig


@pytest.mark.mpl_image_compare
def test_plot_timedelta64():
"""
Test plotting numpy.timedelta64 input data.
"""
fig = Figure()
fig.basemap(
projection="X8c/5c",
region=[0, 8, 0, 10],
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, we could pass in np.timedelta64 into the region argument as mentioned at #2848 (comment).

Suggested change
region=[0, 8, 0, 10],
region=[np.timedelta64(0, "D"), np.timedelta64(8, "D"), 0, 10],

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, looks like I modified kwargs_to_strings 3 years ago at #562 to handle datetime objects in region, so could probably do something similar here for timedelta64.

frame=["WSne", "xaf+lForecast Days", "yaf+lRMSE"],
)
fig.plot(
x=np.arange(np.timedelta64(0, "D"), np.timedelta64(8, "D")),
y=np.geomspace(start=0.1, stop=9, num=8),
style="c0.2c",
pen="1p",
)
return fig


@pytest.mark.mpl_image_compare(
filename="test_plot_ogrgmt_file_multipoint_default_style.png"
)
Expand Down