Closed seisman closed 3 years ago
I have a similar issue when passing pandas columns to text()
.
Full code that generated the error
The script works with PyGMT v0.1.2, but fails with PyGMT v0.2.0 (and master). Here is the example input file used in the script: input.txt
import pandas as pd
import pygmt
data = pd.read_csv("input.txt", names=("id", "longitude", "latitude"), delim_whitespace=True)
fig = pygmt.Figure()
fig.basemap(region=[0, 100, 0, 100], projection='X10c', frame=True)
fig.plot(x=data.longitude, y=data.latitude, style='c0.2c', color='red')
fig.text(x=data.longitude, y=data.latitude, text=data.id, font='16p,red', offset='0.25c')
fig.show()
Full error message
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~/Gits/gmt/pygmt/pygmt/clib/session.py in _check_dtype_and_dim(self, array, ndim)
726 # Try to convert any unknown numpy data types to np.datetime64
--> 727 array = np.asarray(array, dtype=np.datetime64)
728 except ValueError as e:
~/.anaconda/lib/python3.8/site-packages/numpy/core/_asarray.py in asarray(a, dtype, order)
84 """
---> 85 return array(a, dtype, copy=False, order=order)
86
ValueError: Cannot create a NumPy datetime other than NaT with generic units
The above exception was the direct cause of the following exception:
GMTInvalidInput Traceback (most recent call last)
<ipython-input-7-b64e448be657> in <module>
6 fig.basemap(region=[0, 100, 0, 100], projection='X10c', frame=True)
7 fig.plot(x=data.longitude, y=data.latitude, style='c0.2c', color='red')
----> 8 fig.text(x=data.longitude, y=data.latitude, text=data.id, font='16p,red', offset='0.25c')
9 fig.show()
~/Gits/gmt/pygmt/pygmt/helpers/decorators.py in new_module(*args, **kwargs)
268 if alias in kwargs:
269 kwargs[arg] = kwargs.pop(alias)
--> 270 return module_func(*args, **kwargs)
271
272 new_module.aliases = aliases
~/Gits/gmt/pygmt/pygmt/helpers/decorators.py in new_module(*args, **kwargs)
405 kwargs[arg] = separators[fmt].join(f"{item}" for item in value)
406 # Execute the original function and return its output
--> 407 return module_func(*args, **kwargs)
408
409 return new_module
~/Gits/gmt/pygmt/pygmt/base_plotting.py in text(self, textfiles, x, y, position, text, angle, font, justify, **kwargs)
1211 np.atleast_1d(x), np.atleast_1d(y), np.atleast_1d(text)
1212 )
-> 1213 with file_context as fname:
1214 arg_str = " ".join([fname, build_arg_string(kwargs)])
1215 lib.call_module("text", arg_str)
~/.anaconda/lib/python3.8/contextlib.py in __enter__(self)
111 del self.args, self.kwds, self.func
112 try:
--> 113 return next(self.gen)
114 except StopIteration:
115 raise RuntimeError("generator didn't yield") from None
~/Gits/gmt/pygmt/pygmt/clib/session.py in virtualfile_from_vectors(self, *vectors)
1171 # Use put_vector for columns with numerical type data
1172 for col, array in enumerate(arrays[:columns]):
-> 1173 self.put_vector(dataset, column=col, vector=array)
1174
1175 # Use put_strings for last column(s) with string type data
~/Gits/gmt/pygmt/pygmt/clib/session.py in put_vector(self, dataset, column, vector)
775 )
776
--> 777 gmt_type = self._check_dtype_and_dim(vector, ndim=1)
778 if gmt_type == self["GMT_DATETIME"]:
779 vector_pointer = (ctp.c_char_p * len(vector))()
~/Gits/gmt/pygmt/pygmt/clib/session.py in _check_dtype_and_dim(self, array, ndim)
727 array = np.asarray(array, dtype=np.datetime64)
728 except ValueError as e:
--> 729 raise GMTInvalidInput(
730 f"Unsupported numpy data type '{array.dtype.type}'."
731 ) from e
GMTInvalidInput: Unsupported numpy data type '<class 'numpy.object_'>'.
PR #480 mention that, x and y of the
text()
function can accept int, float or str. It's true for PyGMT v0.1.2, but since PyGMT v0.2.0, it's no longer possible to pass string-type x or y.
This is because we refactored text
in #559. String types work before because we would just read from a temporary intermediate csv file, but now we're passing the xy coordinates directly via the GMT C API.
The question is, do we want to accept string-type x and y coordinates?
Probably not, unless someone uses Degrees/Minutes/Seconds format (does GMT support this)? Our documentation for `text currently says:
So we're somewhat hinting that only numerical types are used. We could try to support string types (that are actually numbers) but that will take a bit of work.
The question is, do we want to accept string-type x and y coordinates?
Probably not, unless someone uses Degrees/Minutes/Seconds format (does GMT support this)?
That's a good point. GMT CLI supports different input format for geographic coordinates. For example:
echo 20:30W 30:15S | gmt plot -JM10c -Baf -R-22/-18/-32/-28 -Sc2c -Gred -pdf map
Description of the problem
PR #480 mention that, x and y of the
text()
function can accept int, float or str. It's true for PyGMT v0.1.2, but since PyGMT v0.2.0, it's no longer possible to pass string-type x or y.I haven't looked into the codes to check why it works for v0.1.2. The question is, do we want to accept string-type x and y coordinates?
Full code that generated the error
Full error message
System information
Please paste the output of
python -c "import pygmt; pygmt.show_versions()"
: