Skip to content

Commit 2bc6d24

Browse files
authored
pygmt.project: Add 'output_type' parameter for output in pandas/numpy/file formats (#3110)
1 parent 4f3c5e4 commit 2bc6d24

File tree

1 file changed

+49
-38
lines changed

1 file changed

+49
-38
lines changed

pygmt/src/project.py

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22
project - Project data onto lines or great circles, or generate tracks.
33
"""
44

5+
from typing import Literal
6+
7+
import numpy as np
58
import pandas as pd
69
from pygmt.clib import Session
710
from pygmt.exceptions import GMTInvalidInput
811
from pygmt.helpers import (
9-
GMTTempFile,
1012
build_arg_string,
1113
fmt_docstring,
1214
kwargs_to_strings,
1315
use_alias,
16+
validate_output_table_type,
1417
)
1518

1619

@@ -32,7 +35,15 @@
3235
f="coltypes",
3336
)
3437
@kwargs_to_strings(E="sequence", L="sequence", T="sequence", W="sequence", C="sequence")
35-
def project(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
38+
def project(
39+
data=None,
40+
x=None,
41+
y=None,
42+
z=None,
43+
output_type: Literal["pandas", "numpy", "file"] = "pandas",
44+
outfile: str | None = None,
45+
**kwargs,
46+
) -> pd.DataFrame | np.ndarray | None:
3647
r"""
3748
Project data onto lines or great circles, or generate tracks.
3849
@@ -105,6 +116,8 @@ def project(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
105116
Pass in (x, y, z) or (longitude, latitude, elevation) values by
106117
providing a file name to an ASCII data table, a 2-D
107118
{table-classes}.
119+
{output_type}
120+
{outfile}
108121
109122
center : str or list
110123
*cx*/*cy*.
@@ -196,22 +209,18 @@ def project(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
196209
*direction* is counter-clockwise from the horizontal instead of an
197210
*azimuth*.
198211
199-
outfile : str
200-
The file name for the output ASCII file.
201-
202212
{coltypes}
203213
204214
Returns
205215
-------
206-
track: pandas.DataFrame or None
207-
Return type depends on whether the ``outfile`` parameter is set:
216+
ret
217+
Return type depends on ``outfile`` and ``output_type``:
208218
209-
- :class:`pandas.DataFrame` table with (x, y, ..., newcolname) if
210-
``outfile`` is not set
211-
- None if ``outfile`` is set (output will be stored in file set
212-
by ``outfile``)
219+
- ``None`` if ``outfile`` is set (output will be stored in file set by
220+
``outfile``)
221+
- :class:`pandas.DataFrame` or :class:`numpy.ndarray` if ``outfile`` is not set
222+
(depends on ``output_type``)
213223
"""
214-
215224
if kwargs.get("C") is None:
216225
raise GMTInvalidInput("The `center` parameter must be specified.")
217226
if kwargs.get("G") is None and data is None:
@@ -223,29 +232,31 @@ def project(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
223232
"The `convention` parameter is not allowed with `generate`."
224233
)
225234

226-
with GMTTempFile(suffix=".csv") as tmpfile:
227-
if outfile is None: # Output to tmpfile if outfile is not set
228-
outfile = tmpfile.name
229-
with Session() as lib:
230-
if kwargs.get("G") is None:
231-
with lib.virtualfile_in(
232-
check_kind="vector", data=data, x=x, y=y, z=z, required_z=False
233-
) as vintbl:
234-
# Run project on the temporary (csv) data table
235-
arg_str = build_arg_string(kwargs, infile=vintbl, outfile=outfile)
236-
else:
237-
arg_str = build_arg_string(kwargs, outfile=outfile)
238-
lib.call_module(module="project", args=arg_str)
239-
240-
# if user did not set outfile, return pd.DataFrame
241-
if outfile == tmpfile.name:
242-
if kwargs.get("G") is not None:
243-
column_names = list("rsp")
244-
result = pd.read_csv(tmpfile.name, sep="\t", names=column_names)
245-
else:
246-
result = pd.read_csv(tmpfile.name, sep="\t", header=None, comment=">")
247-
# return None if outfile set, output in outfile
248-
elif outfile != tmpfile.name:
249-
result = None
250-
251-
return result
235+
output_type = validate_output_table_type(output_type, outfile=outfile)
236+
237+
column_names = None
238+
if output_type == "pandas" and kwargs.get("G") is not None:
239+
column_names = list("rsp")
240+
241+
with Session() as lib:
242+
with (
243+
lib.virtualfile_in(
244+
check_kind="vector",
245+
data=data,
246+
x=x,
247+
y=y,
248+
z=z,
249+
required_z=False,
250+
required_data=False,
251+
) as vintbl,
252+
lib.virtualfile_out(kind="dataset", fname=outfile) as vouttbl,
253+
):
254+
lib.call_module(
255+
module="project",
256+
args=build_arg_string(kwargs, infile=vintbl, outfile=vouttbl),
257+
)
258+
return lib.virtualfile_to_dataset(
259+
output_type=output_type,
260+
vfname=vouttbl,
261+
column_names=column_names,
262+
)

0 commit comments

Comments
 (0)