Skip to content

Commit 653f6e1

Browse files
authored
Support passing np.timedelta64 to parameters that expect a sequence (e.g., 'region') (#4358)
1 parent 3175d52 commit 653f6e1

2 files changed

Lines changed: 40 additions & 11 deletions

File tree

pygmt/helpers/utils.py

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,28 @@ def sequence_join(
830830
... sep="/",
831831
... )
832832
'2010-03-01T00:00:00.000000/2015-01-01T12:00:00.123456/2005-01-01T08:00:00.000000000'
833+
834+
>>> # Join a sequence of timedelta64 objects into a string.
835+
>>> sequence_join(
836+
... [
837+
... np.timedelta64(0, "Y"),
838+
... np.timedelta64(1, "M"),
839+
... np.timedelta64(2, "W"),
840+
... np.timedelta64(3, "D"),
841+
... np.timedelta64(4, "h"),
842+
... np.timedelta64(5, "m"),
843+
... np.timedelta64(6, "s"),
844+
... np.timedelta64(7, "ms"),
845+
... np.timedelta64(8, "us"),
846+
... np.timedelta64(9, "ns"),
847+
... np.timedelta64(10, "ps"),
848+
... np.timedelta64(11, "fs"),
849+
... np.timedelta64(12, "as"),
850+
... np.timedelta64(13),
851+
... ],
852+
... sep="/",
853+
... )
854+
'0/1/2/3/4/5/6/7/8/9/10/11/12/13'
833855
"""
834856
# Return the original value if it is not a sequence (e.g., None, bool, or str).
835857
if not is_nonstr_iter(value):
@@ -854,16 +876,22 @@ def sequence_join(
854876
f"but got {len(value)} values."
855877
)
856878
raise GMTInvalidInput(msg)
879+
# Handle datetime-like or timedelta64 objects in the sequence.
857880
# 'str(v)' produces a string like '2024-01-01 00:00:00' for some datetime-like
858-
# objects (e.g., datetime.datetime, pandas.Timestamp), which contains a space.
859-
# If so, use np.datetime_as_string to convert it to ISO 8601 string format
860-
# YYYY-MM-DDThh:mm:ss.ffffff.
861-
_values = [
862-
np.datetime_as_string(np.asarray(item, dtype="datetime64"))
863-
if " " in (s := str(item))
864-
else s
865-
for item in value
866-
]
881+
# objects (e.g., datetime.datetime, pandas.Timestamp), and a string like
882+
# '0 days' for np.timedelta64 objects.
883+
# Need to convert them to ISO 8601 string format 'YYYY-MM-DDThh:mm:ss.ffffff'
884+
# or integer number for timedelta64.
885+
_values = []
886+
for item in value:
887+
if isinstance(item, np.timedelta64): # Convert timedelta64 to numeric value
888+
_values.append(str(item.astype(int)))
889+
elif " " in str(item):
890+
_values.append(
891+
np.datetime_as_string(np.asarray(item, dtype="datetime64")) # type: ignore[arg-type]
892+
)
893+
else:
894+
_values.append(str(item))
867895
return sep.join(_values) # type: ignore[arg-type]
868896

869897
# Now it must be a 2-D sequence.

pygmt/tests/test_plot.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,14 +483,15 @@ def test_plot_timedelta64():
483483
"""
484484
Test plotting numpy.timedelta64 input data.
485485
"""
486+
tmin, tmax = np.timedelta64(0, "D"), np.timedelta64(8, "D")
486487
fig = Figure()
487488
fig.basemap(
488489
projection="X8c/5c",
489-
region=[0, 8, 0, 10],
490+
region=[tmin, tmax, 0, 10],
490491
frame=["WSne", "xaf+lForecast Days", "yaf+lRMSE"],
491492
)
492493
fig.plot(
493-
x=np.arange(np.timedelta64(0, "D"), np.timedelta64(8, "D")),
494+
x=np.arange(tmin, tmax),
494495
y=np.geomspace(start=0.1, stop=9, num=8),
495496
style="c0.2c",
496497
pen="1p",

0 commit comments

Comments
 (0)