-
Notifications
You must be signed in to change notification settings - Fork 225
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
Allow datetime inputs to region argument #562
Changes from 1 commit
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 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -8,6 +8,8 @@ | |||||||||||||
import textwrap | ||||||||||||||
import functools | ||||||||||||||
|
||||||||||||||
import numpy as np | ||||||||||||||
|
||||||||||||||
from .utils import is_nonstr_iter | ||||||||||||||
from ..exceptions import GMTInvalidInput | ||||||||||||||
|
||||||||||||||
|
@@ -302,6 +304,23 @@ def kwargs_to_strings(convert_bools=True, **conversions): | |||||||||||||
>>> module(123, bla=(1, 2, 3), foo=True, A=False, i=(5, 6)) | ||||||||||||||
{'bla': (1, 2, 3), 'foo': '', 'i': '5,6'} | ||||||||||||||
args: 123 | ||||||||||||||
>>> import datetime | ||||||||||||||
>>> module( | ||||||||||||||
... R=[ | ||||||||||||||
... np.datetime64("2010-01-01T16:00:00"), | ||||||||||||||
... datetime.datetime(2020, 1, 1, 12, 23, 45), | ||||||||||||||
... ] | ||||||||||||||
... ) | ||||||||||||||
{'R': '2010-01-01T16:00:00/2020-01-01T12:23:45.000000'} | ||||||||||||||
>>> import pandas as pd | ||||||||||||||
>>> import xarray as xr | ||||||||||||||
>>> module( | ||||||||||||||
... R=[ | ||||||||||||||
... xr.DataArray(data=np.datetime64("2005-01-01T08:00:00")), | ||||||||||||||
... pd.Timestamp("2015-01-01T12:00:00.123456789"), | ||||||||||||||
... ] | ||||||||||||||
... ) | ||||||||||||||
{'R': '2005-01-01T08:00:00.000000000/2015-01-01T12:00:00.123456'} | ||||||||||||||
|
||||||||||||||
""" | ||||||||||||||
valid_conversions = [ | ||||||||||||||
|
@@ -338,9 +357,15 @@ def new_module(*args, **kwargs): | |||||||||||||
value = kwargs[arg] | ||||||||||||||
issequence = fmt in separators | ||||||||||||||
if issequence and is_nonstr_iter(value): | ||||||||||||||
kwargs[arg] = separators[fmt].join( | ||||||||||||||
"{}".format(item) for item in value | ||||||||||||||
) | ||||||||||||||
for index, item in enumerate(value): | ||||||||||||||
try: | ||||||||||||||
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.
Please add it near line 360 to make the |
||||||||||||||
assert " " not in str(item) | ||||||||||||||
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. I'm a little confused how the 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. Sorry that this isn't very readable, it's following the EAFP style, usually used when we're handling only a few exceptional cases. The original reason that we can't pass in 'datetime'-like values to the 'region' argument is because there's a space import pandas as pd
str(pd.Timestamp("2015-01-01T12:00:00.123456789"))
# '2015-01-01 12:00:00.123456789' This also applies to |
||||||||||||||
except AssertionError: | ||||||||||||||
# convert datetime-like items to string format | ||||||||||||||
value[index] = np.datetime_as_string( | ||||||||||||||
np.asarray(item, dtype=np.datetime64) | ||||||||||||||
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. We use Lines 778 to 782 in 2ddbb0e
The array_to_datetime function uses pd.to_datetime(array) pygmt/pygmt/clib/conversion.py Line 324 in 2ddbb0e
Any specific reason to use 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. Main reason is to handle import pandas as pd
import xarray as xr
pd.to_datetime(xr.DataArray(data=np.datetime64("2005-01-01")))
# TypeError: len() of unsized object but this does: import numpy as np
import xarray as xr
np.asarray(xr.DataArray(data=np.datetime64("2005-01-01")))
# array('2005-01-01T00:00:00.000000000', dtype='datetime64[ns]') We actually came across this before in #464 (comment). |
||||||||||||||
) | ||||||||||||||
kwargs[arg] = separators[fmt].join(f"{item}" for item in value) | ||||||||||||||
# Execute the original function and return its output | ||||||||||||||
return module_func(*args, **kwargs) | ||||||||||||||
|
||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if I understand your codes correctly. It seems the codes check all arguments. For example, perspective=[30, 50] is converted to -p30/50, and the codes also check if
30
and50
are datetime-like, right?However, -p doesn't accept any datetime-like values. It looks a waste of time. Perhaps we should check whether
arg="B"
(maybe arg="region")?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we do check every item using
assert " " not in str(item)
, but this is quite a fast string parsing check (see also the other comment on EAFP syntax). It is not explictily checking for datetime-like (which would be a slower check) using something likeisinstance(item, (pd.Timestamp, datetime.datetime, etc))
.This would be an extra check on top of the (rather fast)
assert " " not in str(item)
, and yes, we could add it I suppose. But really, there's usually not very many items to parse here, only 4 if using[xmin, xmax, ymin, ymax]
, maybe 6 if using[xmin, xmax, ymin, ymax, zmin, zmax]
.Happy to consider an alternative way though if you have any ideas, I definitely think there's a better way to do this. The unit tests are all there, so feel free to refactor/change the code as long as it passes the tests!