Skip to content

Commit

Permalink
Allow np.timedelta64 inputs to region parameter
Browse files Browse the repository at this point in the history
Cast np.timedelta64 inputs to int, so that they can be understood by GMT.
  • Loading branch information
weiji14 committed Dec 16, 2023
1 parent 49dbe83 commit d5bedc2
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
34 changes: 25 additions & 9 deletions pygmt/helpers/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
arguments, insert common text into docstrings, transform arguments to strings,
etc.
"""
import datetime
import functools
import textwrap
import warnings
Expand Down Expand Up @@ -673,14 +674,19 @@ def kwargs_to_strings(**conversions):
>>> module(123, bla=(1, 2, 3), foo=True, A=False, i=(5, 6))
{'A': False, 'bla': (1, 2, 3), 'foo': True, 'i': '5,6'}
args: 123
>>> # Test that region accepts arguments with datetime or timedelta type
>>> import datetime
>>> module(
... R=[
... np.datetime64("2010-01-01T16:00:00"),
... datetime.datetime(2020, 1, 1, 12, 23, 45),
... np.timedelta64(0, "h"),
... np.timedelta64(24, "h"),
... ]
... )
{'R': '2010-01-01T16:00:00/2020-01-01T12:23:45.000000'}
{'R': '2010-01-01T16:00:00/2020-01-01T12:23:45.000000/0/24'}
>>> import pandas as pd
>>> import xarray as xr
>>> module(
Expand All @@ -690,6 +696,7 @@ def kwargs_to_strings(**conversions):
... ]
... )
{'R': '2005-01-01T08:00:00.000000000/2015-01-01T12:00:00.123456'}
>>> # Here is a more realistic example
>>> # See https://github.com/GenericMappingTools/pygmt/issues/2361
>>> @kwargs_to_strings(
Expand Down Expand Up @@ -760,14 +767,23 @@ def new_module(*args, **kwargs):
if fmt in separators and is_nonstr_iter(value):
for index, item in enumerate(value):
if " " in str(item):
# Check if there is a space " " when converting
# a pandas.Timestamp/xr.DataArray to a string.
# If so, use np.datetime_as_string instead.
# Convert datetime-like item to ISO 8601
# string format like YYYY-MM-DDThh:mm:ss.ffffff.
value[index] = np.datetime_as_string(
np.asarray(item, dtype=np.datetime64)
)
# Check if there is a space " " in the item, which
# is typically present in objects such as
# np.timedelta64, pd.Timestamp, or xr.DataArray.
# If so, convert the item to a numerical or string
# type that is understood by GMT as follows:
if getattr(
getattr(item, "dtype", ""), "name", ""
).startswith("timedelta"):
# A np.timedelta64 item is cast to integer
value[index] = item.astype("int")
else:
# A pandas.Timestamp/xr.DataArray containing
# a datetime-like object is cast to ISO 8601
# string format like YYYY-MM-DDThh:mm:ss.ffffff
value[index] = np.datetime_as_string(
np.asarray(item, dtype=np.datetime64)
)
newvalue = separators[fmt].join(f"{item}" for item in value)
# Changes in bound.arguments will reflect in bound.args
# and bound.kwargs.
Expand Down
2 changes: 1 addition & 1 deletion pygmt/tests/test_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ def test_plot_timedelta64():
fig = Figure()
fig.basemap(
projection="X8c/5c",
region=[0, 8, 0, 10],
region=[np.timedelta64(0, "D"), np.timedelta64(8, "D"), 0, 10],
frame=["WSne", "xaf+lForecast Days", "yaf+lRMSE"],
)
fig.plot(
Expand Down

0 comments on commit d5bedc2

Please sign in to comment.