From 17a86be1a280efe21f72ab034ad039e1927ae237 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Sat, 22 May 2021 11:20:09 +0100 Subject: [PATCH 01/56] add grd2xyz import/doc link --- doc/api/index.rst | 1 + pygmt/__init__.py | 1 + pygmt/src/__init__.py | 1 + 3 files changed, 3 insertions(+) diff --git a/doc/api/index.rst b/doc/api/index.rst index fc69a95d1e2..9ded0f5a7d6 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -88,6 +88,7 @@ Operations on grids: .. autosummary:: :toctree: generated + grd2xyz grdclip grdcut grdfill diff --git a/pygmt/__init__.py b/pygmt/__init__.py index 5cbea0fc853..093eed8d9ba 100644 --- a/pygmt/__init__.py +++ b/pygmt/__init__.py @@ -32,6 +32,7 @@ blockmean, blockmedian, config, + grd2xyz, grd2cpt, grdclip, grdcut, diff --git a/pygmt/src/__init__.py b/pygmt/src/__init__.py index b4855a37737..9b227b0a6fb 100644 --- a/pygmt/src/__init__.py +++ b/pygmt/src/__init__.py @@ -10,6 +10,7 @@ from pygmt.src.config import config from pygmt.src.contour import contour from pygmt.src.grd2cpt import grd2cpt +from pygmt.src.grd2xyz import grd2xyz from pygmt.src.grdclip import grdclip from pygmt.src.grdcontour import grdcontour from pygmt.src.grdcut import grdcut From 7e7a7fae065b541d8fb8543bb118fdcd283c1daa Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Sat, 22 May 2021 11:22:15 +0100 Subject: [PATCH 02/56] format fix --- pygmt/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/__init__.py b/pygmt/__init__.py index 093eed8d9ba..267bc5a2681 100644 --- a/pygmt/__init__.py +++ b/pygmt/__init__.py @@ -32,8 +32,8 @@ blockmean, blockmedian, config, - grd2xyz, grd2cpt, + grd2xyz, grdclip, grdcut, grdfill, From 6525ff38167215c06780f75ee935c73e8d8d335c Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Sat, 22 May 2021 11:22:42 +0100 Subject: [PATCH 03/56] create grd2xyz.py --- pygmt/src/grd2xyz.py | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 pygmt/src/grd2xyz.py diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py new file mode 100644 index 00000000000..cd47c87a5ab --- /dev/null +++ b/pygmt/src/grd2xyz.py @@ -0,0 +1,53 @@ +""" +grd2xyz - Convert grid to data table +""" +from pygmt.clib import Session +from pygmt.helpers import ( + GMTTempFile, + build_arg_string, + fmt_docstring, + kwargs_to_strings, + use_alias, +) + + +@fmt_docstring +@use_alias( + R="region", + V="verbose", +) +@kwargs_to_strings(R="sequence") +def grd2xyz(grid, **kwargs): + r""" + Create xyz table from grid files. + + Read one or more binary 2-D grid files and write out + xyz-triplets in ASCII [or binary] format to standard output. + + Full option list at :gmt-docs:`grd2xyz.html` + + {aliases} + + Parameters + ---------- + grid : str or xarray.DataArray + The file name of the input grid or the grid loaded as a DataArray. + This is the only required parameter. + {R} + {V} + + Returns + ------- + info : str + A string with information about the grid. + """ + with GMTTempFile() as outfile: + with Session() as lib: + file_context = lib.virtualfile_from_data(check_kind="raster", data=grid) + with file_context as infile: + arg_str = " ".join( + [infile, build_arg_string(kwargs), "->" + outfile.name] + ) + lib.call_module("grd2xyz", arg_str) + result = outfile.read() + return result From 13e309c7f9b93c277f9a80bbe8faac0cd095f94c Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Sat, 22 May 2021 11:36:25 +0100 Subject: [PATCH 04/56] create test_grd2xyz.py --- pygmt/tests/test_grd2xyz.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 pygmt/tests/test_grd2xyz.py diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py new file mode 100644 index 00000000000..fb2f0fb9337 --- /dev/null +++ b/pygmt/tests/test_grd2xyz.py @@ -0,0 +1,27 @@ +""" +Tests for grd2xyz. +""" +import pytest +from pygmt import grd2xyz +from pygmt.datasets import load_earth_relief + + +@pytest.fixture(scope="module", name="grid") +def fixture_grid(): + """ + Load the grid data from the sample earth_relief file. + """ + return load_earth_relief(resolution="01d", region=[-1, 1, -1, 1]) + + +def test_grd2xyz(grid): + """ + Make sure grd2xyz works as expected. + """ + xyz_data = grd2xyz(grid=grid) + assert xyz_data.strip().split("\n") == [ + "-0.5 0.5 -4967", + "0.5 0.5 -4852", + "-0.5 -0.5 -4917", + "0.5 -0.5 -4747.5", + ] From c08d717986e829c6c1de5eeb297fd31027e55b50 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Sat, 22 May 2021 12:45:31 +0100 Subject: [PATCH 05/56] spelling fix; change docstring --- pygmt/src/grd2xyz.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index cd47c87a5ab..b1b25abead2 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -19,10 +19,10 @@ @kwargs_to_strings(R="sequence") def grd2xyz(grid, **kwargs): r""" - Create xyz table from grid files. + Create xyz tables from grid files. - Read one or more binary 2-D grid files and write out - xyz-triplets in ASCII [or binary] format to standard output. + Read a binary 2-D grid files and write out + xyz-triplets in ASCII [or binary] format to a standard output. Full option list at :gmt-docs:`grd2xyz.html` From bf58dc2defc3b6ff67e4769322505d63e4ad941d Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 25 May 2021 07:52:22 +0100 Subject: [PATCH 06/56] allow specifiying format for returned xyz data --- pygmt/src/grd2xyz.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index b1b25abead2..04bc2d2733a 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -1,7 +1,10 @@ """ grd2xyz - Convert grid to data table """ +import numpy as np +import pandas as pd from pygmt.clib import Session +from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import ( GMTTempFile, build_arg_string, @@ -17,7 +20,7 @@ V="verbose", ) @kwargs_to_strings(R="sequence") -def grd2xyz(grid, **kwargs): +def grd2xyz(grid, format="a", **kwargs): r""" Create xyz tables from grid files. @@ -33,6 +36,12 @@ def grd2xyz(grid, **kwargs): grid : str or xarray.DataArray The file name of the input grid or the grid loaded as a DataArray. This is the only required parameter. + format : str + Determine the format the xyz data will be returned in: + **a**: numpy array [Default option] + **d**: pandas DataFrame + **s**: string + {R} {V} @@ -50,4 +59,20 @@ def grd2xyz(grid, **kwargs): ) lib.call_module("grd2xyz", arg_str) result = outfile.read() + if format == "s": + return result + data_list = [] + for string_entry in result.strip().split("\n"): + float_entry = [] + string_list = string_entry.strip().split() + for i in string_list: + float_entry.append(float(i)) + data_list.append(float_entry) + data_array = np.array(data_list) + if format == "a": + result = data_array + elif format == "d": + result = pd.DataFrame(data_array) + else: + raise GMTInvalidInput("""Must specify format as either a, d, or s.""") return result From 7f100d5a7b85a5f642669903f9146342c36f1cb2 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 25 May 2021 07:58:31 +0100 Subject: [PATCH 07/56] add format tests in test_grd2xyz.py --- pygmt/tests/test_grd2xyz.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index fb2f0fb9337..973f7c03b95 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -1,9 +1,12 @@ """ Tests for grd2xyz. """ +import numpy as np +import pandas as pd import pytest from pygmt import grd2xyz from pygmt.datasets import load_earth_relief +from pygmt.exceptions import GMTInvalidInput @pytest.fixture(scope="module", name="grid") @@ -18,10 +21,30 @@ def test_grd2xyz(grid): """ Make sure grd2xyz works as expected. """ - xyz_data = grd2xyz(grid=grid) + xyz_data = grd2xyz(grid=grid, format="s") assert xyz_data.strip().split("\n") == [ "-0.5 0.5 -4967", "0.5 0.5 -4852", "-0.5 -0.5 -4917", "0.5 -0.5 -4747.5", ] + + +def test_grd2xyz_format(grid): + """ + Test that correct formats are returned. + """ + xyz_array = grd2xyz(grid=grid) + assert isinstance(xyz_array, np.ndarray) + xyz_df = grd2xyz(grid=grid, format="d") + assert isinstance(xyz_df, pd.DataFrame) + xyz_string = grd2xyz(grid=grid, format="s") + assert isinstance(xyz_string, str) + + +def test_grd2xyz_invalid_format(grid): + """ + Test that grd2xyz fails with incorrect format. + """ + with pytest.raises(GMTInvalidInput): + grd2xyz(grid=grid, format=1) From 0701d6269188f4f9366eb49dea7858a104bc9a3d Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 25 May 2021 08:02:01 +0100 Subject: [PATCH 08/56] change format parameter to xyz_format --- pygmt/src/grd2xyz.py | 10 +++++----- pygmt/tests/test_grd2xyz.py | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 04bc2d2733a..b1c07482008 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -20,7 +20,7 @@ V="verbose", ) @kwargs_to_strings(R="sequence") -def grd2xyz(grid, format="a", **kwargs): +def grd2xyz(grid, xyz_format="a", **kwargs): r""" Create xyz tables from grid files. @@ -36,7 +36,7 @@ def grd2xyz(grid, format="a", **kwargs): grid : str or xarray.DataArray The file name of the input grid or the grid loaded as a DataArray. This is the only required parameter. - format : str + xyz_format : str Determine the format the xyz data will be returned in: **a**: numpy array [Default option] **d**: pandas DataFrame @@ -59,7 +59,7 @@ def grd2xyz(grid, format="a", **kwargs): ) lib.call_module("grd2xyz", arg_str) result = outfile.read() - if format == "s": + if xyz_format == "s": return result data_list = [] for string_entry in result.strip().split("\n"): @@ -69,9 +69,9 @@ def grd2xyz(grid, format="a", **kwargs): float_entry.append(float(i)) data_list.append(float_entry) data_array = np.array(data_list) - if format == "a": + if xyz_format == "a": result = data_array - elif format == "d": + elif xyz_format == "d": result = pd.DataFrame(data_array) else: raise GMTInvalidInput("""Must specify format as either a, d, or s.""") diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index 973f7c03b95..d41e2d94622 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -21,7 +21,7 @@ def test_grd2xyz(grid): """ Make sure grd2xyz works as expected. """ - xyz_data = grd2xyz(grid=grid, format="s") + xyz_data = grd2xyz(grid=grid, xyz_format="s") assert xyz_data.strip().split("\n") == [ "-0.5 0.5 -4967", "0.5 0.5 -4852", @@ -36,9 +36,9 @@ def test_grd2xyz_format(grid): """ xyz_array = grd2xyz(grid=grid) assert isinstance(xyz_array, np.ndarray) - xyz_df = grd2xyz(grid=grid, format="d") + xyz_df = grd2xyz(grid=grid, xyz_format="d") assert isinstance(xyz_df, pd.DataFrame) - xyz_string = grd2xyz(grid=grid, format="s") + xyz_string = grd2xyz(grid=grid, xyz_format="s") assert isinstance(xyz_string, str) @@ -47,4 +47,4 @@ def test_grd2xyz_invalid_format(grid): Test that grd2xyz fails with incorrect format. """ with pytest.raises(GMTInvalidInput): - grd2xyz(grid=grid, format=1) + grd2xyz(grid=grid, xyz_format=1) From 6ac279ca75259a6c038c4cfa994efac26fee46e9 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 6 Jul 2021 15:49:46 +0100 Subject: [PATCH 09/56] Update pygmt/src/grd2xyz.py Co-authored-by: Meghan Jones --- pygmt/src/grd2xyz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index b1c07482008..640d00cff1f 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -36,7 +36,7 @@ def grd2xyz(grid, xyz_format="a", **kwargs): grid : str or xarray.DataArray The file name of the input grid or the grid loaded as a DataArray. This is the only required parameter. - xyz_format : str + output_type : str Determine the format the xyz data will be returned in: **a**: numpy array [Default option] **d**: pandas DataFrame From a226f34f12e6502483b45fd92c49ec1bcd8c08a2 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 6 Jul 2021 15:52:47 +0100 Subject: [PATCH 10/56] change xyz_format to output_type --- pygmt/src/grd2xyz.py | 8 ++++---- pygmt/tests/test_grd2xyz.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 640d00cff1f..1062cc27512 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -20,7 +20,7 @@ V="verbose", ) @kwargs_to_strings(R="sequence") -def grd2xyz(grid, xyz_format="a", **kwargs): +def grd2xyz(grid, output_type="a", **kwargs): r""" Create xyz tables from grid files. @@ -59,7 +59,7 @@ def grd2xyz(grid, xyz_format="a", **kwargs): ) lib.call_module("grd2xyz", arg_str) result = outfile.read() - if xyz_format == "s": + if output_type == "s": return result data_list = [] for string_entry in result.strip().split("\n"): @@ -69,9 +69,9 @@ def grd2xyz(grid, xyz_format="a", **kwargs): float_entry.append(float(i)) data_list.append(float_entry) data_array = np.array(data_list) - if xyz_format == "a": + if output_type == "a": result = data_array - elif xyz_format == "d": + elif output_type == "d": result = pd.DataFrame(data_array) else: raise GMTInvalidInput("""Must specify format as either a, d, or s.""") diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index d41e2d94622..d29dad0e56f 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -21,7 +21,7 @@ def test_grd2xyz(grid): """ Make sure grd2xyz works as expected. """ - xyz_data = grd2xyz(grid=grid, xyz_format="s") + xyz_data = grd2xyz(grid=grid, output_type="s") assert xyz_data.strip().split("\n") == [ "-0.5 0.5 -4967", "0.5 0.5 -4852", @@ -36,9 +36,9 @@ def test_grd2xyz_format(grid): """ xyz_array = grd2xyz(grid=grid) assert isinstance(xyz_array, np.ndarray) - xyz_df = grd2xyz(grid=grid, xyz_format="d") + xyz_df = grd2xyz(grid=grid, output_type="d") assert isinstance(xyz_df, pd.DataFrame) - xyz_string = grd2xyz(grid=grid, xyz_format="s") + xyz_string = grd2xyz(grid=grid, output_type="s") assert isinstance(xyz_string, str) @@ -47,4 +47,4 @@ def test_grd2xyz_invalid_format(grid): Test that grd2xyz fails with incorrect format. """ with pytest.raises(GMTInvalidInput): - grd2xyz(grid=grid, xyz_format=1) + grd2xyz(grid=grid, output_type=1) From 0b52451dbb28b5ad7e76fca0ab61c20dd6f0a945 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 6 Jul 2021 15:54:04 +0100 Subject: [PATCH 11/56] change default output to DataFrame --- pygmt/src/grd2xyz.py | 2 +- pygmt/tests/test_grd2xyz.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 1062cc27512..effd8ed3b74 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -20,7 +20,7 @@ V="verbose", ) @kwargs_to_strings(R="sequence") -def grd2xyz(grid, output_type="a", **kwargs): +def grd2xyz(grid, output_type="d", **kwargs): r""" Create xyz tables from grid files. diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index d29dad0e56f..bc2230b2f93 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -34,7 +34,9 @@ def test_grd2xyz_format(grid): """ Test that correct formats are returned. """ - xyz_array = grd2xyz(grid=grid) + xyz_default = grd2xyz(grid=grid) + assert isinstance(xyz_default, pd.DataFrame) + xyz_array = grd2xyz(grid=grid, output_type="a") assert isinstance(xyz_array, np.ndarray) xyz_df = grd2xyz(grid=grid, output_type="d") assert isinstance(xyz_df, pd.DataFrame) From 37d366dac36b94cc0420d23962501d12c56442b0 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 6 Jul 2021 15:56:00 +0100 Subject: [PATCH 12/56] update info return options --- pygmt/src/grd2xyz.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index effd8ed3b74..93374eff707 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -38,8 +38,8 @@ def grd2xyz(grid, output_type="d", **kwargs): This is the only required parameter. output_type : str Determine the format the xyz data will be returned in: - **a**: numpy array [Default option] - **d**: pandas DataFrame + **a**: numpy array + **d**: pandas DataFrame [Default option] **s**: string {R} @@ -47,8 +47,8 @@ def grd2xyz(grid, output_type="d", **kwargs): Returns ------- - info : str - A string with information about the grid. + info : pandas.DataFrame or numpy.array or str + The xyz triplet data in a pandas DataFrame, numpy array, or string. """ with GMTTempFile() as outfile: with Session() as lib: From b27699a8140b175c8958c4dd66088d999ffe9d48 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Sat, 22 May 2021 11:20:09 +0100 Subject: [PATCH 13/56] add grd2xyz import/doc link --- doc/api/index.rst | 1 + pygmt/__init__.py | 1 + pygmt/src/__init__.py | 1 + 3 files changed, 3 insertions(+) diff --git a/doc/api/index.rst b/doc/api/index.rst index 40ab49ac430..a7f5e6f4fae 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -88,6 +88,7 @@ Operations on grids: .. autosummary:: :toctree: generated + grd2xyz grdclip grdcut grdfill diff --git a/pygmt/__init__.py b/pygmt/__init__.py index 972f6474286..7b7895cd89a 100644 --- a/pygmt/__init__.py +++ b/pygmt/__init__.py @@ -32,6 +32,7 @@ blockmean, blockmedian, config, + grd2xyz, grd2cpt, grdclip, grdcut, diff --git a/pygmt/src/__init__.py b/pygmt/src/__init__.py index f8bae667f02..c20e6053d1e 100644 --- a/pygmt/src/__init__.py +++ b/pygmt/src/__init__.py @@ -10,6 +10,7 @@ from pygmt.src.config import config from pygmt.src.contour import contour from pygmt.src.grd2cpt import grd2cpt +from pygmt.src.grd2xyz import grd2xyz from pygmt.src.grdclip import grdclip from pygmt.src.grdcontour import grdcontour from pygmt.src.grdcut import grdcut From 036138105c10bae966d9d19c26e3d0d73f0177b6 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Sat, 22 May 2021 11:22:15 +0100 Subject: [PATCH 14/56] format fix --- pygmt/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/__init__.py b/pygmt/__init__.py index 7b7895cd89a..c590c1f736e 100644 --- a/pygmt/__init__.py +++ b/pygmt/__init__.py @@ -32,8 +32,8 @@ blockmean, blockmedian, config, - grd2xyz, grd2cpt, + grd2xyz, grdclip, grdcut, grdfill, From a9fef0737ddf773387c8dc78a869bfb2a5dbd35e Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Sat, 22 May 2021 11:22:42 +0100 Subject: [PATCH 15/56] create grd2xyz.py --- pygmt/src/grd2xyz.py | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 pygmt/src/grd2xyz.py diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py new file mode 100644 index 00000000000..cd47c87a5ab --- /dev/null +++ b/pygmt/src/grd2xyz.py @@ -0,0 +1,53 @@ +""" +grd2xyz - Convert grid to data table +""" +from pygmt.clib import Session +from pygmt.helpers import ( + GMTTempFile, + build_arg_string, + fmt_docstring, + kwargs_to_strings, + use_alias, +) + + +@fmt_docstring +@use_alias( + R="region", + V="verbose", +) +@kwargs_to_strings(R="sequence") +def grd2xyz(grid, **kwargs): + r""" + Create xyz table from grid files. + + Read one or more binary 2-D grid files and write out + xyz-triplets in ASCII [or binary] format to standard output. + + Full option list at :gmt-docs:`grd2xyz.html` + + {aliases} + + Parameters + ---------- + grid : str or xarray.DataArray + The file name of the input grid or the grid loaded as a DataArray. + This is the only required parameter. + {R} + {V} + + Returns + ------- + info : str + A string with information about the grid. + """ + with GMTTempFile() as outfile: + with Session() as lib: + file_context = lib.virtualfile_from_data(check_kind="raster", data=grid) + with file_context as infile: + arg_str = " ".join( + [infile, build_arg_string(kwargs), "->" + outfile.name] + ) + lib.call_module("grd2xyz", arg_str) + result = outfile.read() + return result From 957d8fef582fc230fdb78cdcdf29c0ee3606f2df Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Sat, 22 May 2021 11:36:25 +0100 Subject: [PATCH 16/56] create test_grd2xyz.py --- pygmt/tests/test_grd2xyz.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 pygmt/tests/test_grd2xyz.py diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py new file mode 100644 index 00000000000..fb2f0fb9337 --- /dev/null +++ b/pygmt/tests/test_grd2xyz.py @@ -0,0 +1,27 @@ +""" +Tests for grd2xyz. +""" +import pytest +from pygmt import grd2xyz +from pygmt.datasets import load_earth_relief + + +@pytest.fixture(scope="module", name="grid") +def fixture_grid(): + """ + Load the grid data from the sample earth_relief file. + """ + return load_earth_relief(resolution="01d", region=[-1, 1, -1, 1]) + + +def test_grd2xyz(grid): + """ + Make sure grd2xyz works as expected. + """ + xyz_data = grd2xyz(grid=grid) + assert xyz_data.strip().split("\n") == [ + "-0.5 0.5 -4967", + "0.5 0.5 -4852", + "-0.5 -0.5 -4917", + "0.5 -0.5 -4747.5", + ] From 5a4baa543555f9791b6b694e824596267533214e Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Sat, 22 May 2021 12:45:31 +0100 Subject: [PATCH 17/56] spelling fix; change docstring --- pygmt/src/grd2xyz.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index cd47c87a5ab..b1b25abead2 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -19,10 +19,10 @@ @kwargs_to_strings(R="sequence") def grd2xyz(grid, **kwargs): r""" - Create xyz table from grid files. + Create xyz tables from grid files. - Read one or more binary 2-D grid files and write out - xyz-triplets in ASCII [or binary] format to standard output. + Read a binary 2-D grid files and write out + xyz-triplets in ASCII [or binary] format to a standard output. Full option list at :gmt-docs:`grd2xyz.html` From 1cf9e56db9514dffc5d27102dcd01214b1d177d6 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 25 May 2021 07:52:22 +0100 Subject: [PATCH 18/56] allow specifiying format for returned xyz data --- pygmt/src/grd2xyz.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index b1b25abead2..04bc2d2733a 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -1,7 +1,10 @@ """ grd2xyz - Convert grid to data table """ +import numpy as np +import pandas as pd from pygmt.clib import Session +from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import ( GMTTempFile, build_arg_string, @@ -17,7 +20,7 @@ V="verbose", ) @kwargs_to_strings(R="sequence") -def grd2xyz(grid, **kwargs): +def grd2xyz(grid, format="a", **kwargs): r""" Create xyz tables from grid files. @@ -33,6 +36,12 @@ def grd2xyz(grid, **kwargs): grid : str or xarray.DataArray The file name of the input grid or the grid loaded as a DataArray. This is the only required parameter. + format : str + Determine the format the xyz data will be returned in: + **a**: numpy array [Default option] + **d**: pandas DataFrame + **s**: string + {R} {V} @@ -50,4 +59,20 @@ def grd2xyz(grid, **kwargs): ) lib.call_module("grd2xyz", arg_str) result = outfile.read() + if format == "s": + return result + data_list = [] + for string_entry in result.strip().split("\n"): + float_entry = [] + string_list = string_entry.strip().split() + for i in string_list: + float_entry.append(float(i)) + data_list.append(float_entry) + data_array = np.array(data_list) + if format == "a": + result = data_array + elif format == "d": + result = pd.DataFrame(data_array) + else: + raise GMTInvalidInput("""Must specify format as either a, d, or s.""") return result From 948ca7334407449e15ebd90a07b2e6e5f3a6b415 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 25 May 2021 07:58:31 +0100 Subject: [PATCH 19/56] add format tests in test_grd2xyz.py --- pygmt/tests/test_grd2xyz.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index fb2f0fb9337..973f7c03b95 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -1,9 +1,12 @@ """ Tests for grd2xyz. """ +import numpy as np +import pandas as pd import pytest from pygmt import grd2xyz from pygmt.datasets import load_earth_relief +from pygmt.exceptions import GMTInvalidInput @pytest.fixture(scope="module", name="grid") @@ -18,10 +21,30 @@ def test_grd2xyz(grid): """ Make sure grd2xyz works as expected. """ - xyz_data = grd2xyz(grid=grid) + xyz_data = grd2xyz(grid=grid, format="s") assert xyz_data.strip().split("\n") == [ "-0.5 0.5 -4967", "0.5 0.5 -4852", "-0.5 -0.5 -4917", "0.5 -0.5 -4747.5", ] + + +def test_grd2xyz_format(grid): + """ + Test that correct formats are returned. + """ + xyz_array = grd2xyz(grid=grid) + assert isinstance(xyz_array, np.ndarray) + xyz_df = grd2xyz(grid=grid, format="d") + assert isinstance(xyz_df, pd.DataFrame) + xyz_string = grd2xyz(grid=grid, format="s") + assert isinstance(xyz_string, str) + + +def test_grd2xyz_invalid_format(grid): + """ + Test that grd2xyz fails with incorrect format. + """ + with pytest.raises(GMTInvalidInput): + grd2xyz(grid=grid, format=1) From b050cd8a2cfe1103786ba50d7014b187ca745650 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 25 May 2021 08:02:01 +0100 Subject: [PATCH 20/56] change format parameter to xyz_format --- pygmt/src/grd2xyz.py | 10 +++++----- pygmt/tests/test_grd2xyz.py | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 04bc2d2733a..b1c07482008 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -20,7 +20,7 @@ V="verbose", ) @kwargs_to_strings(R="sequence") -def grd2xyz(grid, format="a", **kwargs): +def grd2xyz(grid, xyz_format="a", **kwargs): r""" Create xyz tables from grid files. @@ -36,7 +36,7 @@ def grd2xyz(grid, format="a", **kwargs): grid : str or xarray.DataArray The file name of the input grid or the grid loaded as a DataArray. This is the only required parameter. - format : str + xyz_format : str Determine the format the xyz data will be returned in: **a**: numpy array [Default option] **d**: pandas DataFrame @@ -59,7 +59,7 @@ def grd2xyz(grid, format="a", **kwargs): ) lib.call_module("grd2xyz", arg_str) result = outfile.read() - if format == "s": + if xyz_format == "s": return result data_list = [] for string_entry in result.strip().split("\n"): @@ -69,9 +69,9 @@ def grd2xyz(grid, format="a", **kwargs): float_entry.append(float(i)) data_list.append(float_entry) data_array = np.array(data_list) - if format == "a": + if xyz_format == "a": result = data_array - elif format == "d": + elif xyz_format == "d": result = pd.DataFrame(data_array) else: raise GMTInvalidInput("""Must specify format as either a, d, or s.""") diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index 973f7c03b95..d41e2d94622 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -21,7 +21,7 @@ def test_grd2xyz(grid): """ Make sure grd2xyz works as expected. """ - xyz_data = grd2xyz(grid=grid, format="s") + xyz_data = grd2xyz(grid=grid, xyz_format="s") assert xyz_data.strip().split("\n") == [ "-0.5 0.5 -4967", "0.5 0.5 -4852", @@ -36,9 +36,9 @@ def test_grd2xyz_format(grid): """ xyz_array = grd2xyz(grid=grid) assert isinstance(xyz_array, np.ndarray) - xyz_df = grd2xyz(grid=grid, format="d") + xyz_df = grd2xyz(grid=grid, xyz_format="d") assert isinstance(xyz_df, pd.DataFrame) - xyz_string = grd2xyz(grid=grid, format="s") + xyz_string = grd2xyz(grid=grid, xyz_format="s") assert isinstance(xyz_string, str) @@ -47,4 +47,4 @@ def test_grd2xyz_invalid_format(grid): Test that grd2xyz fails with incorrect format. """ with pytest.raises(GMTInvalidInput): - grd2xyz(grid=grid, format=1) + grd2xyz(grid=grid, xyz_format=1) From 9ab970162e18b26abde61641271e8444bb6477ab Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 6 Jul 2021 15:49:46 +0100 Subject: [PATCH 21/56] Update pygmt/src/grd2xyz.py Co-authored-by: Meghan Jones --- pygmt/src/grd2xyz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index b1c07482008..640d00cff1f 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -36,7 +36,7 @@ def grd2xyz(grid, xyz_format="a", **kwargs): grid : str or xarray.DataArray The file name of the input grid or the grid loaded as a DataArray. This is the only required parameter. - xyz_format : str + output_type : str Determine the format the xyz data will be returned in: **a**: numpy array [Default option] **d**: pandas DataFrame From 891ff6c38a4f85df3d32b815d2c457c7c813dfed Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 6 Jul 2021 15:52:47 +0100 Subject: [PATCH 22/56] change xyz_format to output_type --- pygmt/src/grd2xyz.py | 8 ++++---- pygmt/tests/test_grd2xyz.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 640d00cff1f..1062cc27512 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -20,7 +20,7 @@ V="verbose", ) @kwargs_to_strings(R="sequence") -def grd2xyz(grid, xyz_format="a", **kwargs): +def grd2xyz(grid, output_type="a", **kwargs): r""" Create xyz tables from grid files. @@ -59,7 +59,7 @@ def grd2xyz(grid, xyz_format="a", **kwargs): ) lib.call_module("grd2xyz", arg_str) result = outfile.read() - if xyz_format == "s": + if output_type == "s": return result data_list = [] for string_entry in result.strip().split("\n"): @@ -69,9 +69,9 @@ def grd2xyz(grid, xyz_format="a", **kwargs): float_entry.append(float(i)) data_list.append(float_entry) data_array = np.array(data_list) - if xyz_format == "a": + if output_type == "a": result = data_array - elif xyz_format == "d": + elif output_type == "d": result = pd.DataFrame(data_array) else: raise GMTInvalidInput("""Must specify format as either a, d, or s.""") diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index d41e2d94622..d29dad0e56f 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -21,7 +21,7 @@ def test_grd2xyz(grid): """ Make sure grd2xyz works as expected. """ - xyz_data = grd2xyz(grid=grid, xyz_format="s") + xyz_data = grd2xyz(grid=grid, output_type="s") assert xyz_data.strip().split("\n") == [ "-0.5 0.5 -4967", "0.5 0.5 -4852", @@ -36,9 +36,9 @@ def test_grd2xyz_format(grid): """ xyz_array = grd2xyz(grid=grid) assert isinstance(xyz_array, np.ndarray) - xyz_df = grd2xyz(grid=grid, xyz_format="d") + xyz_df = grd2xyz(grid=grid, output_type="d") assert isinstance(xyz_df, pd.DataFrame) - xyz_string = grd2xyz(grid=grid, xyz_format="s") + xyz_string = grd2xyz(grid=grid, output_type="s") assert isinstance(xyz_string, str) @@ -47,4 +47,4 @@ def test_grd2xyz_invalid_format(grid): Test that grd2xyz fails with incorrect format. """ with pytest.raises(GMTInvalidInput): - grd2xyz(grid=grid, xyz_format=1) + grd2xyz(grid=grid, output_type=1) From 02cd02fb886e4e5290f8c245a2ad8a5f9199a37e Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 6 Jul 2021 15:54:04 +0100 Subject: [PATCH 23/56] change default output to DataFrame --- pygmt/src/grd2xyz.py | 2 +- pygmt/tests/test_grd2xyz.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 1062cc27512..effd8ed3b74 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -20,7 +20,7 @@ V="verbose", ) @kwargs_to_strings(R="sequence") -def grd2xyz(grid, output_type="a", **kwargs): +def grd2xyz(grid, output_type="d", **kwargs): r""" Create xyz tables from grid files. diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index d29dad0e56f..bc2230b2f93 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -34,7 +34,9 @@ def test_grd2xyz_format(grid): """ Test that correct formats are returned. """ - xyz_array = grd2xyz(grid=grid) + xyz_default = grd2xyz(grid=grid) + assert isinstance(xyz_default, pd.DataFrame) + xyz_array = grd2xyz(grid=grid, output_type="a") assert isinstance(xyz_array, np.ndarray) xyz_df = grd2xyz(grid=grid, output_type="d") assert isinstance(xyz_df, pd.DataFrame) From 00bece0c12e91079948ec766ce1c02739f5fc1e8 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 6 Jul 2021 15:56:00 +0100 Subject: [PATCH 24/56] update info return options --- pygmt/src/grd2xyz.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index effd8ed3b74..93374eff707 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -38,8 +38,8 @@ def grd2xyz(grid, output_type="d", **kwargs): This is the only required parameter. output_type : str Determine the format the xyz data will be returned in: - **a**: numpy array [Default option] - **d**: pandas DataFrame + **a**: numpy array + **d**: pandas DataFrame [Default option] **s**: string {R} @@ -47,8 +47,8 @@ def grd2xyz(grid, output_type="d", **kwargs): Returns ------- - info : str - A string with information about the grid. + info : pandas.DataFrame or numpy.array or str + The xyz triplet data in a pandas DataFrame, numpy array, or string. """ with GMTTempFile() as outfile: with Session() as lib: From 01613ff8e0017374e0c60ca7abff088cd09bc217 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Fri, 16 Jul 2021 16:32:44 +0100 Subject: [PATCH 25/56] change output name to "data" from "info" --- pygmt/src/grd2xyz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 93374eff707..e423dfb9ee6 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -47,7 +47,7 @@ def grd2xyz(grid, output_type="d", **kwargs): Returns ------- - info : pandas.DataFrame or numpy.array or str + data : pandas.DataFrame or numpy.array or str The xyz triplet data in a pandas DataFrame, numpy array, or string. """ with GMTTempFile() as outfile: From 3da6dda19284acbd6c0a88bacabc06617e77bd36 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Fri, 16 Jul 2021 16:37:22 +0100 Subject: [PATCH 26/56] Apply suggestions from code review Co-authored-by: Meghan Jones --- pygmt/src/grd2xyz.py | 50 +++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index e423dfb9ee6..de4cbc06bc4 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -20,12 +20,12 @@ V="verbose", ) @kwargs_to_strings(R="sequence") -def grd2xyz(grid, output_type="d", **kwargs): +def grd2xyz(grid, output_type="d", outfile=None, **kwargs): r""" - Create xyz tables from grid files. + Convert grid to data table. - Read a binary 2-D grid files and write out - xyz-triplets in ASCII [or binary] format to a standard output. + Read a grid and output xyz-triplets as a numpy array, + pandas DataFrame, string, or ASCII [or binary] file. Full option list at :gmt-docs:`grd2xyz.html` @@ -41,7 +41,8 @@ def grd2xyz(grid, output_type="d", **kwargs): **a**: numpy array **d**: pandas DataFrame [Default option] **s**: string - + outfile : str + The file name for the output ASCII file. {R} {V} @@ -50,29 +51,26 @@ def grd2xyz(grid, output_type="d", **kwargs): data : pandas.DataFrame or numpy.array or str The xyz triplet data in a pandas DataFrame, numpy array, or string. """ - with GMTTempFile() as outfile: + if output_type not in ["a", "d", "s"]: + raise GMTInvalidInput("""Must specify format as either a, d, or s.""") + if output_type == "s" and outfile is None: + raise GMTInvalidInput("""Must specify outfile for ASCII output.""") + + with GMTTempFile() as tmpfile: with Session() as lib: file_context = lib.virtualfile_from_data(check_kind="raster", data=grid) with file_context as infile: - arg_str = " ".join( - [infile, build_arg_string(kwargs), "->" + outfile.name] - ) + if outfile is None: + outfile = tmpfile.name + arg_str = " ".join([infile, build_arg_string(kwargs), "->" + outfile]) lib.call_module("grd2xyz", arg_str) - result = outfile.read() - if output_type == "s": - return result - data_list = [] - for string_entry in result.strip().split("\n"): - float_entry = [] - string_list = string_entry.strip().split() - for i in string_list: - float_entry.append(float(i)) - data_list.append(float_entry) - data_array = np.array(data_list) - if output_type == "a": - result = data_array - elif output_type == "d": - result = pd.DataFrame(data_array) - else: - raise GMTInvalidInput("""Must specify format as either a, d, or s.""") + + # Read temporary csv output to a pandas table + if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame + result = pd.read_csv(tmpfile.name, sep="\t", header=None, comment=">") + elif outfile != tmpfile.name: # return None if outfile set, output in outfile + result = None + + if output_type == "a": + result = result.to_numpy() return result From 2dcf859b094d2a33f985c610872a9a8e3b62b13d Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Fri, 16 Jul 2021 16:53:32 +0100 Subject: [PATCH 27/56] remove numpy import --- pygmt/src/grd2xyz.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index de4cbc06bc4..3eeb9fc02e3 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -1,7 +1,6 @@ """ grd2xyz - Convert grid to data table """ -import numpy as np import pandas as pd from pygmt.clib import Session from pygmt.exceptions import GMTInvalidInput From 283d5156c2638f3d34708ad5a08ff6c4d65ee3a3 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Fri, 16 Jul 2021 16:54:38 +0100 Subject: [PATCH 28/56] update test_grd2xyz.py --- pygmt/tests/test_grd2xyz.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index bc2230b2f93..08861765c0f 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -21,13 +21,8 @@ def test_grd2xyz(grid): """ Make sure grd2xyz works as expected. """ - xyz_data = grd2xyz(grid=grid, output_type="s") - assert xyz_data.strip().split("\n") == [ - "-0.5 0.5 -4967", - "0.5 0.5 -4852", - "-0.5 -0.5 -4917", - "0.5 -0.5 -4747.5", - ] + xyz_data = grd2xyz(grid=grid, output_type="a") + assert xyz_data.shape == (4, 3) def test_grd2xyz_format(grid): @@ -40,8 +35,6 @@ def test_grd2xyz_format(grid): assert isinstance(xyz_array, np.ndarray) xyz_df = grd2xyz(grid=grid, output_type="d") assert isinstance(xyz_df, pd.DataFrame) - xyz_string = grd2xyz(grid=grid, output_type="s") - assert isinstance(xyz_string, str) def test_grd2xyz_invalid_format(grid): @@ -50,3 +43,11 @@ def test_grd2xyz_invalid_format(grid): """ with pytest.raises(GMTInvalidInput): grd2xyz(grid=grid, output_type=1) + + +def test_grd2xyz_no_outfile(grid): + """ + Test that grd2xyz fails when a string output is set with no outfile. + """ + with pytest.raises(GMTInvalidInput): + grd2xyz(grid=grid, output_type="s") From 29c8be6a6255120cf5b277f34b812a226ee69da3 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Wed, 25 Aug 2021 18:16:23 +0100 Subject: [PATCH 29/56] Apply suggestions from code review Co-authored-by: Meghan Jones --- pygmt/src/grd2xyz.py | 41 +++++++++++++++++++++++-------------- pygmt/tests/test_grd2xyz.py | 8 ++++---- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 3eeb9fc02e3..a6ce1da08b5 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -19,12 +19,12 @@ V="verbose", ) @kwargs_to_strings(R="sequence") -def grd2xyz(grid, output_type="d", outfile=None, **kwargs): +def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): r""" Convert grid to data table. - Read a grid and output xyz-triplets as a numpy array, - pandas DataFrame, string, or ASCII [or binary] file. + Read a grid and output xyz-triplets as a :class:`numpy.ndarray`, + :class:`pandas.DataFrame`, or ASCII file. Full option list at :gmt-docs:`grd2xyz.html` @@ -33,13 +33,15 @@ def grd2xyz(grid, output_type="d", outfile=None, **kwargs): Parameters ---------- grid : str or xarray.DataArray - The file name of the input grid or the grid loaded as a DataArray. - This is the only required parameter. + The file name of the input grid or the grid loaded as a + :class:`xarray.DataArray`. This is the only required parameter. output_type : str - Determine the format the xyz data will be returned in: - **a**: numpy array - **d**: pandas DataFrame [Default option] - **s**: string + Determine the format the xyz data will be returned in [Default is + ``pandas``]: + + - ``numpy`` - :class:`numpy.ndarray` + - ``pandas``- :class:`pandas.DataFrame` + - ``file`` - ASCII file (requires ``outfile``) outfile : str The file name for the output ASCII file. {R} @@ -47,12 +49,21 @@ def grd2xyz(grid, output_type="d", outfile=None, **kwargs): Returns ------- - data : pandas.DataFrame or numpy.array or str - The xyz triplet data in a pandas DataFrame, numpy array, or string. + ret : pandas.DataFrame or numpy.ndarray or None + Return type depends on ``outfile`` and ``output_type``: + + - None if ``outfile`` is set (output will be stored in file set by + ``outfile``) + - :class:`pandas.DataFrame` or :class:`numpy.ndarray` if ``outfile`` is + not set (depends on ``output_type`` [Default is + :class:`pandas.DataFrame`]) + """ - if output_type not in ["a", "d", "s"]: - raise GMTInvalidInput("""Must specify format as either a, d, or s.""") - if output_type == "s" and outfile is None: + if output_type not in ["numpy", "pandas", "file"]: + raise GMTInvalidInput( + """Must specify format as either numpy, pandas, or file.""" + ) + if output_type == "file" and outfile is None: raise GMTInvalidInput("""Must specify outfile for ASCII output.""") with GMTTempFile() as tmpfile: @@ -70,6 +81,6 @@ def grd2xyz(grid, output_type="d", outfile=None, **kwargs): elif outfile != tmpfile.name: # return None if outfile set, output in outfile result = None - if output_type == "a": + if output_type == "numpy": result = result.to_numpy() return result diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index 08861765c0f..32df9886f16 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -21,7 +21,7 @@ def test_grd2xyz(grid): """ Make sure grd2xyz works as expected. """ - xyz_data = grd2xyz(grid=grid, output_type="a") + xyz_data = grd2xyz(grid=grid, output_type="numpy") assert xyz_data.shape == (4, 3) @@ -31,9 +31,9 @@ def test_grd2xyz_format(grid): """ xyz_default = grd2xyz(grid=grid) assert isinstance(xyz_default, pd.DataFrame) - xyz_array = grd2xyz(grid=grid, output_type="a") + xyz_array = grd2xyz(grid=grid, output_type="numpy") assert isinstance(xyz_array, np.ndarray) - xyz_df = grd2xyz(grid=grid, output_type="d") + xyz_df = grd2xyz(grid=grid, output_type="pandas") assert isinstance(xyz_df, pd.DataFrame) @@ -50,4 +50,4 @@ def test_grd2xyz_no_outfile(grid): Test that grd2xyz fails when a string output is set with no outfile. """ with pytest.raises(GMTInvalidInput): - grd2xyz(grid=grid, output_type="s") + grd2xyz(grid=grid, output_type="file") From c4549e418f406495e91f147fdfa0834dadc3d0cc Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Mon, 30 Aug 2021 11:32:38 +0100 Subject: [PATCH 30/56] Apply suggestions from code review Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> --- pygmt/src/grd2xyz.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index a6ce1da08b5..baee7cb3c16 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -1,6 +1,8 @@ """ grd2xyz - Convert grid to data table """ +import warnings + import pandas as pd from pygmt.clib import Session from pygmt.exceptions import GMTInvalidInput @@ -40,7 +42,7 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): ``pandas``]: - ``numpy`` - :class:`numpy.ndarray` - - ``pandas``- :class:`pandas.DataFrame` + - ``pandas``- :class:`pandas.DataFrame` - ``file`` - ASCII file (requires ``outfile``) outfile : str The file name for the output ASCII file. @@ -63,6 +65,13 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): raise GMTInvalidInput( """Must specify format as either numpy, pandas, or file.""" ) + if outfile is not None and output_type != "file": + msg = ( + f"Changing `output_type` of grd2xyz from '{output_type}' to 'file' " + "since `outfile` parameter is set. Please use `output_type='file'` " + "to silence this warning." + ) + warnings.warn(msg, category=RuntimeWarning, stacklevel=2) if output_type == "file" and outfile is None: raise GMTInvalidInput("""Must specify outfile for ASCII output.""") From 66761a8e0ad41a0be610138e02270e9665611f2d Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Mon, 30 Aug 2021 18:25:47 +0100 Subject: [PATCH 31/56] Apply suggestions from code review Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> --- pygmt/src/grd2xyz.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index baee7cb3c16..b69c65ceca2 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -72,7 +72,8 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): "to silence this warning." ) warnings.warn(msg, category=RuntimeWarning, stacklevel=2) - if output_type == "file" and outfile is None: + output_type = "file" + elif output_type == "file" and outfile is None: raise GMTInvalidInput("""Must specify outfile for ASCII output.""") with GMTTempFile() as tmpfile: From 0a525b623e5dcb6deb56a0a09cc5c78dba6f390c Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Mon, 30 Aug 2021 18:57:35 +0100 Subject: [PATCH 32/56] add test_grd2xyz_file_output() --- pygmt/tests/test_grd2xyz.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index 32df9886f16..e3574161756 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -1,12 +1,15 @@ """ Tests for grd2xyz. """ +import os + import numpy as np import pandas as pd import pytest from pygmt import grd2xyz from pygmt.datasets import load_earth_relief from pygmt.exceptions import GMTInvalidInput +from pygmt.helpers import GMTTempFile @pytest.fixture(scope="module", name="grid") @@ -37,6 +40,16 @@ def test_grd2xyz_format(grid): assert isinstance(xyz_df, pd.DataFrame) +def test_grd2xyz_file_output(grid): + """ + Test that grd2xyz returns a file output when it is specified. + """ + with GMTTempFile(suffix=".xyz") as tmpfile: + result = grd2xyz(grid=grid, outfile=tmpfile.name, output_type="file") + assert result is None # return value is None + assert os.path.exists(path=tmpfile.name) # check that outfile exists + + def test_grd2xyz_invalid_format(grid): """ Test that grd2xyz fails with incorrect format. From 8de23a8f90fef1a2aa18b5df6d27590321d8a9b9 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 31 Aug 2021 17:46:13 +0100 Subject: [PATCH 33/56] assign column names in dataframe --- pygmt/src/grd2xyz.py | 9 ++++++++- pygmt/tests/test_grd2xyz.py | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index b69c65ceca2..62d6f996c16 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -4,6 +4,7 @@ import warnings import pandas as pd +import xarray as xr from pygmt.clib import Session from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import ( @@ -75,6 +76,10 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): output_type = "file" elif output_type == "file" and outfile is None: raise GMTInvalidInput("""Must specify outfile for ASCII output.""") + dataframe_header = ["x", "y", "z"] + if type(grid) == xr.DataArray and output_type == "pandas": + if len(grid.dims) == 3: + dataframe_header = grid.dims with GMTTempFile() as tmpfile: with Session() as lib: @@ -87,7 +92,9 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): # Read temporary csv output to a pandas table if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame - result = pd.read_csv(tmpfile.name, sep="\t", header=None, comment=">") + result = pd.read_csv( + tmpfile.name, sep="\t", names=dataframe_header, comment=">" + ) elif outfile != tmpfile.name: # return None if outfile set, output in outfile result = None diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index e3574161756..aea88dee851 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -6,6 +6,7 @@ import numpy as np import pandas as pd import pytest +import xarray as xr from pygmt import grd2xyz from pygmt.datasets import load_earth_relief from pygmt.exceptions import GMTInvalidInput @@ -34,10 +35,13 @@ def test_grd2xyz_format(grid): """ xyz_default = grd2xyz(grid=grid) assert isinstance(xyz_default, pd.DataFrame) + print(type(list(xyz_default.columns))) + assert list(xyz_default.columns) == ["x", "y", "z"] xyz_array = grd2xyz(grid=grid, output_type="numpy") assert isinstance(xyz_array, np.ndarray) xyz_df = grd2xyz(grid=grid, output_type="pandas") assert isinstance(xyz_df, pd.DataFrame) + assert list(xyz_df.columns) == ["x", "y", "z"] def test_grd2xyz_file_output(grid): From 938532a2f68e712299900f79f6345a7bed60dbea Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 31 Aug 2021 17:48:18 +0100 Subject: [PATCH 34/56] remove unused import --- pygmt/tests/test_grd2xyz.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index aea88dee851..948ec886505 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -6,7 +6,6 @@ import numpy as np import pandas as pd import pytest -import xarray as xr from pygmt import grd2xyz from pygmt.datasets import load_earth_relief from pygmt.exceptions import GMTInvalidInput From 161c94bf0e9f22fabfc8ab82d2346c434af07e45 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 31 Aug 2021 17:49:44 +0100 Subject: [PATCH 35/56] adding comments --- pygmt/src/grd2xyz.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 62d6f996c16..cbc277a300c 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -76,7 +76,9 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): output_type = "file" elif output_type == "file" and outfile is None: raise GMTInvalidInput("""Must specify outfile for ASCII output.""") + # Set the default column names for the pandas dataframe header dataframe_header = ["x", "y", "z"] + # Set the column names to match an input DataArray as the grid if type(grid) == xr.DataArray and output_type == "pandas": if len(grid.dims) == 3: dataframe_header = grid.dims From 317a3ddd129bbfa01229d03fbdbe0edca62b8e30 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Wed, 1 Sep 2021 16:02:00 +0100 Subject: [PATCH 36/56] adding test_grd2xyz_outfile_incorrect_output_type --- pygmt/tests/test_grd2xyz.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index 948ec886505..c244760cd72 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -67,3 +67,13 @@ def test_grd2xyz_no_outfile(grid): """ with pytest.raises(GMTInvalidInput): grd2xyz(grid=grid, output_type="file") + + +def test_grd2xyz_outfile_incorrect_output_type(grid): + """ + Test that grd2xyz raises a warning when an outfile name is set but the + output_type is not set to file is set with no outfile. + """ + with pytest.warns(RuntimeWarning): + with GMTTempFile(suffix=".xyz") as tmpfile: + grd2xyz(grid=grid, outfile=tmpfile.name, output_type="numpy") From 41051a9a08e196ba5fec63ddf585e528d45c54b9 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Wed, 1 Sep 2021 16:06:13 +0100 Subject: [PATCH 37/56] style fix --- pygmt/src/grd2xyz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index cbc277a300c..b655aa54c6a 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -79,7 +79,7 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): # Set the default column names for the pandas dataframe header dataframe_header = ["x", "y", "z"] # Set the column names to match an input DataArray as the grid - if type(grid) == xr.DataArray and output_type == "pandas": + if isinstance(grid, xr.DataArray) == xr.DataArray and output_type == "pandas": if len(grid.dims) == 3: dataframe_header = grid.dims From 9eebee3b679f764bd186381b1f97af894f35843e Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Thu, 2 Sep 2021 08:12:11 +0100 Subject: [PATCH 38/56] Apply suggestions from code review Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> --- pygmt/src/grd2xyz.py | 5 ++--- pygmt/tests/test_grd2xyz.py | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index b655aa54c6a..3bead249ca5 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -79,9 +79,8 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): # Set the default column names for the pandas dataframe header dataframe_header = ["x", "y", "z"] # Set the column names to match an input DataArray as the grid - if isinstance(grid, xr.DataArray) == xr.DataArray and output_type == "pandas": - if len(grid.dims) == 3: - dataframe_header = grid.dims + if isinstance(grid, xr.DataArray) and output_type == "pandas": + dataframe_header = grid.dims + (grid.name,) with GMTTempFile() as tmpfile: with Session() as lib: diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index c244760cd72..8b6c6cb3bed 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -34,8 +34,7 @@ def test_grd2xyz_format(grid): """ xyz_default = grd2xyz(grid=grid) assert isinstance(xyz_default, pd.DataFrame) - print(type(list(xyz_default.columns))) - assert list(xyz_default.columns) == ["x", "y", "z"] + assert list(xyz_default.columns) == ["lon", "lat", "elevation"] xyz_array = grd2xyz(grid=grid, output_type="numpy") assert isinstance(xyz_array, np.ndarray) xyz_df = grd2xyz(grid=grid, output_type="pandas") @@ -76,4 +75,6 @@ def test_grd2xyz_outfile_incorrect_output_type(grid): """ with pytest.warns(RuntimeWarning): with GMTTempFile(suffix=".xyz") as tmpfile: - grd2xyz(grid=grid, outfile=tmpfile.name, output_type="numpy") + result = grd2xyz(grid=grid, outfile=tmpfile.name, output_type="numpy") + assert result is None # return value is None + assert os.path.exists(path=tmpfile.name) # check that outfile exists From 3ac3642e553cee5a778f6449d07830c865f2aa3b Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 14 Sep 2021 07:42:57 -0400 Subject: [PATCH 39/56] Apply suggestions from code review Co-authored-by: Meghan Jones --- pygmt/tests/test_grd2xyz.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index 8b6c6cb3bed..ab08543658a 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -17,7 +17,7 @@ def fixture_grid(): """ Load the grid data from the sample earth_relief file. """ - return load_earth_relief(resolution="01d", region=[-1, 1, -1, 1]) + return load_earth_relief(resolution="01d", region=[-1, 1, 3, 5]) def test_grd2xyz(grid): @@ -32,9 +32,17 @@ def test_grd2xyz_format(grid): """ Test that correct formats are returned. """ + lon = -0.5 + lat = 3.5 + orig_val = grid.sel(lon=lon, lat=lat).to_numpy() xyz_default = grd2xyz(grid=grid) + xyz_val = xyz_default[(xyz_default["lon"] == lon) & (xyz_default["lat"] == lat)][ + "elevation" + ].to_numpy() assert isinstance(xyz_default, pd.DataFrame) - assert list(xyz_default.columns) == ["lon", "lat", "elevation"] + assert orig_val.size == 1 + assert xyz_val.size == 1 + np.testing.assert_allclose(orig_val, xyz_val) xyz_array = grd2xyz(grid=grid, output_type="numpy") assert isinstance(xyz_array, np.ndarray) xyz_df = grd2xyz(grid=grid, output_type="pandas") From 81b051158ddd988c5d33631a7f3cb57865b24782 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Tue, 14 Sep 2021 20:05:44 -0400 Subject: [PATCH 40/56] Update pygmt/src/grd2xyz.py Co-authored-by: Meghan Jones --- pygmt/src/grd2xyz.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 3bead249ca5..d50f970e262 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -76,11 +76,13 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): output_type = "file" elif output_type == "file" and outfile is None: raise GMTInvalidInput("""Must specify outfile for ASCII output.""") - # Set the default column names for the pandas dataframe header - dataframe_header = ["x", "y", "z"] - # Set the column names to match an input DataArray as the grid - if isinstance(grid, xr.DataArray) and output_type == "pandas": - dataframe_header = grid.dims + (grid.name,) + if "o" not in kwargs.keys(): # Only set column names for standard output + # Set the default column names for the pandas dataframe header + dataframe_header = ["x", "y", "z"] + # Set the column names to match an input DataArray as the grid + if isinstance(grid, xr.DataArray) and output_type == "pandas": + # Reverse the dims because it is rows, columns ordered. + dataframe_header = (grid.dims[1],) + (grid.dims[0],) + (grid.name,) with GMTTempFile() as tmpfile: with Session() as lib: From af6aac9593777fbb9675a7ed608e2d698a6375ec Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Wed, 15 Sep 2021 22:50:06 -0400 Subject: [PATCH 41/56] update test --- pygmt/tests/test_grd2xyz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index ab08543658a..07b2380a43f 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -47,7 +47,7 @@ def test_grd2xyz_format(grid): assert isinstance(xyz_array, np.ndarray) xyz_df = grd2xyz(grid=grid, output_type="pandas") assert isinstance(xyz_df, pd.DataFrame) - assert list(xyz_df.columns) == ["x", "y", "z"] + assert list(xyz_df.columns) == ["lon", "lat", "elevation"] def test_grd2xyz_file_output(grid): From e1c6555473bc1aa38407ee2219e37bef5b1553fe Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Thu, 16 Sep 2021 18:51:25 -0400 Subject: [PATCH 42/56] Apply suggestions from code review Co-authored-by: Dongdong Tian --- pygmt/src/grd2xyz.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index d50f970e262..dedd497d143 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -64,7 +64,7 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): """ if output_type not in ["numpy", "pandas", "file"]: raise GMTInvalidInput( - """Must specify format as either numpy, pandas, or file.""" + "Must specify format as either numpy, pandas, or file." ) if outfile is not None and output_type != "file": msg = ( @@ -82,7 +82,7 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): # Set the column names to match an input DataArray as the grid if isinstance(grid, xr.DataArray) and output_type == "pandas": # Reverse the dims because it is rows, columns ordered. - dataframe_header = (grid.dims[1],) + (grid.dims[0],) + (grid.name,) + dataframe_header = [grid.dims[1], grid.dims[0], grid.name] with GMTTempFile() as tmpfile: with Session() as lib: From 19277951bd8ece0480a18bc2a7ecb2cd102e7d45 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Thu, 16 Sep 2021 18:53:04 -0400 Subject: [PATCH 43/56] add line for grd2xyz region --- pygmt/src/grd2xyz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index d50f970e262..fa4157173d7 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -76,7 +76,7 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): output_type = "file" elif output_type == "file" and outfile is None: raise GMTInvalidInput("""Must specify outfile for ASCII output.""") - if "o" not in kwargs.keys(): # Only set column names for standard output + if "o" not in kwargs.keys(): # Only set column names for standard output # Set the default column names for the pandas dataframe header dataframe_header = ["x", "y", "z"] # Set the column names to match an input DataArray as the grid From 76190ab81d21647ae0fa7ef30199aa4ddb46528b Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Thu, 16 Sep 2021 18:59:49 -0400 Subject: [PATCH 44/56] update region docstring --- pygmt/src/grd2xyz.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 8216011f1f6..498b81e58f2 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -48,6 +48,9 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): outfile : str The file name for the output ASCII file. {R} + Adding `region` will select a subsection of the grid. If this + subsection exceeds the boundaries of the grid, only the common region + will be output. {V} Returns From 31388eb885aaecf4ea3fa34d0bf304b2ad3b7a9b Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Thu, 16 Sep 2021 19:02:19 -0400 Subject: [PATCH 45/56] add if statement --- pygmt/src/grd2xyz.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 498b81e58f2..3298be4362f 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -48,8 +48,8 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): outfile : str The file name for the output ASCII file. {R} - Adding `region` will select a subsection of the grid. If this - subsection exceeds the boundaries of the grid, only the common region + Adding `region` will select a subsection of the grid. If this + subsection exceeds the boundaries of the grid, only the common region will be output. {V} @@ -66,9 +66,7 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): """ if output_type not in ["numpy", "pandas", "file"]: - raise GMTInvalidInput( - "Must specify format as either numpy, pandas, or file." - ) + raise GMTInvalidInput("Must specify format as either numpy, pandas, or file.") if outfile is not None and output_type != "file": msg = ( f"Changing `output_type` of grd2xyz from '{output_type}' to 'file' " @@ -98,9 +96,12 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): # Read temporary csv output to a pandas table if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame - result = pd.read_csv( - tmpfile.name, sep="\t", names=dataframe_header, comment=">" - ) + if "o" not in kwargs.keys(): + result = pd.read_csv( + tmpfile.name, sep="\t", names=dataframe_header, comment=">" + ) + else: + result = pd.read_csv(tmpfile.name, sep="\t", comment=">") elif outfile != tmpfile.name: # return None if outfile set, output in outfile result = None From 924a3e01cba0d9220b443621c3a74ffbfff3c8f6 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Sun, 19 Sep 2021 07:26:07 -0400 Subject: [PATCH 46/56] Apply suggestions from code review Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> --- pygmt/src/grd2xyz.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 3298be4362f..add2c5e820c 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -66,21 +66,25 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): """ if output_type not in ["numpy", "pandas", "file"]: - raise GMTInvalidInput("Must specify format as either numpy, pandas, or file.") + raise GMTInvalidInput( + "Must specify `output_type` either as 'numpy', 'pandas' or 'file'." + ) + if outfile is not None and output_type != "file": msg = ( f"Changing `output_type` of grd2xyz from '{output_type}' to 'file' " "since `outfile` parameter is set. Please use `output_type='file'` " "to silence this warning." ) - warnings.warn(msg, category=RuntimeWarning, stacklevel=2) + warnings.warn(message=msg, category=RuntimeWarning, stacklevel=2) output_type = "file" - elif output_type == "file" and outfile is None: - raise GMTInvalidInput("""Must specify outfile for ASCII output.""") - if "o" not in kwargs.keys(): # Only set column names for standard output + elif outfile is None and output_type == "file": + raise GMTInvalidInput("Must specify `outfile` for ASCII output.") + + if "o" not in kwargs: # Only set column names for standard output # Set the default column names for the pandas dataframe header dataframe_header = ["x", "y", "z"] - # Set the column names to match an input DataArray as the grid + # Let output pandas column names match input DataArray dimension names if isinstance(grid, xr.DataArray) and output_type == "pandas": # Reverse the dims because it is rows, columns ordered. dataframe_header = [grid.dims[1], grid.dims[0], grid.name] From 9a3c37736221138173a5217f7431f96c59a35429 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Sun, 19 Sep 2021 19:52:38 -0400 Subject: [PATCH 47/56] update comment for o if statement --- pygmt/src/grd2xyz.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index add2c5e820c..f14e51cd0dc 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -81,7 +81,7 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): elif outfile is None and output_type == "file": raise GMTInvalidInput("Must specify `outfile` for ASCII output.") - if "o" not in kwargs: # Only set column names for standard output + if "o" not in kwargs: # Set default column names if not specified # Set the default column names for the pandas dataframe header dataframe_header = ["x", "y", "z"] # Let output pandas column names match input DataArray dimension names @@ -100,7 +100,7 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): # Read temporary csv output to a pandas table if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame - if "o" not in kwargs.keys(): + if "o" not in kwargs: result = pd.read_csv( tmpfile.name, sep="\t", names=dataframe_header, comment=">" ) From 4b1214cc92e8ae22040624209ec67a9a66242cbc Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Mon, 20 Sep 2021 15:57:53 -0400 Subject: [PATCH 48/56] change if statement for o raises GMTInvalidInput if o is specified and the output type is set to "pandas" --- pygmt/src/grd2xyz.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index f14e51cd0dc..435d37e1cbc 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -81,13 +81,17 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): elif outfile is None and output_type == "file": raise GMTInvalidInput("Must specify `outfile` for ASCII output.") - if "o" not in kwargs: # Set default column names if not specified - # Set the default column names for the pandas dataframe header - dataframe_header = ["x", "y", "z"] - # Let output pandas column names match input DataArray dimension names - if isinstance(grid, xr.DataArray) and output_type == "pandas": - # Reverse the dims because it is rows, columns ordered. - dataframe_header = [grid.dims[1], grid.dims[0], grid.name] + if "o" in kwargs and output_type == "pandas": + raise GMTInvalidInput( + "If 'o' is specified, `output_type` must be either as 'numpy' or 'file'." + ) + + # Set the default column names for the pandas dataframe header + dataframe_header = ["x", "y", "z"] + # Let output pandas column names match input DataArray dimension names + if isinstance(grid, xr.DataArray) and output_type == "pandas": + # Reverse the dims because it is rows, columns ordered. + dataframe_header = [grid.dims[1], grid.dims[0], grid.name] with GMTTempFile() as tmpfile: with Session() as lib: @@ -100,12 +104,9 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): # Read temporary csv output to a pandas table if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame - if "o" not in kwargs: - result = pd.read_csv( - tmpfile.name, sep="\t", names=dataframe_header, comment=">" - ) - else: - result = pd.read_csv(tmpfile.name, sep="\t", comment=">") + result = pd.read_csv( + tmpfile.name, sep="\t", names=dataframe_header, comment=">" + ) elif outfile != tmpfile.name: # return None if outfile set, output in outfile result = None From 59bae5c8ecdb1a4ed8363c39ed88aa29c18ae22c Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Mon, 20 Sep 2021 15:58:14 -0400 Subject: [PATCH 49/56] add test for setting o and output_type to pandas --- pygmt/tests/test_grd2xyz.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index 07b2380a43f..cee2debcda5 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -86,3 +86,10 @@ def test_grd2xyz_outfile_incorrect_output_type(grid): result = grd2xyz(grid=grid, outfile=tmpfile.name, output_type="numpy") assert result is None # return value is None assert os.path.exists(path=tmpfile.name) # check that outfile exists + +def test_grd2xyz_pandas_output_wiht_o(grid): + """ + Test that grd2xyz fails when 'o' is set and output_type is set to 'pandas'. + """ + with pytest.raises(GMTInvalidInput): + grd2xyz(grid=grid, output_type="pandas", o="2") From 2a11880c6274a54e21be683702f8565220652f06 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Mon, 20 Sep 2021 16:05:40 -0400 Subject: [PATCH 50/56] run make format --- pygmt/tests/test_grd2xyz.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index cee2debcda5..1062a553181 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -87,6 +87,7 @@ def test_grd2xyz_outfile_incorrect_output_type(grid): assert result is None # return value is None assert os.path.exists(path=tmpfile.name) # check that outfile exists + def test_grd2xyz_pandas_output_wiht_o(grid): """ Test that grd2xyz fails when 'o' is set and output_type is set to 'pandas'. From ff45946d09b05ed8ce98c3625d51dced3e614d49 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Mon, 20 Sep 2021 16:06:57 -0400 Subject: [PATCH 51/56] typo fix --- pygmt/tests/test_grd2xyz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index 1062a553181..a209b2263aa 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -88,7 +88,7 @@ def test_grd2xyz_outfile_incorrect_output_type(grid): assert os.path.exists(path=tmpfile.name) # check that outfile exists -def test_grd2xyz_pandas_output_wiht_o(grid): +def test_grd2xyz_pandas_output_with_o(grid): """ Test that grd2xyz fails when 'o' is set and output_type is set to 'pandas'. """ From e3336c4ecb7c78a174078825fdf1026b8f97d2da Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Wed, 22 Sep 2021 11:43:39 +0100 Subject: [PATCH 52/56] Apply suggestions from code review Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> Co-authored-by: Dongdong Tian --- pygmt/src/grd2xyz.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 435d37e1cbc..0985e117dac 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -20,8 +20,9 @@ @use_alias( R="region", V="verbose", + o="outcols", ) -@kwargs_to_strings(R="sequence") +@kwargs_to_strings(R="sequence", o="sequence_comma") def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): r""" Convert grid to data table. @@ -48,10 +49,11 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): outfile : str The file name for the output ASCII file. {R} - Adding `region` will select a subsection of the grid. If this + Adding ``region`` will select a subsection of the grid. If this subsection exceeds the boundaries of the grid, only the common region will be output. {V} + {o} Returns ------- @@ -67,7 +69,7 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): """ if output_type not in ["numpy", "pandas", "file"]: raise GMTInvalidInput( - "Must specify `output_type` either as 'numpy', 'pandas' or 'file'." + "Must specify 'output_type' either as 'numpy', 'pandas' or 'file'." ) if outfile is not None and output_type != "file": @@ -83,7 +85,8 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): if "o" in kwargs and output_type == "pandas": raise GMTInvalidInput( - "If 'o' is specified, `output_type` must be either as 'numpy' or 'file'." + "If 'outcols' is specified, `output_type` must be either 'numpy'" + "or 'file'." ) # Set the default column names for the pandas dataframe header From 552bf3f0a79cf136d0deab120f830ce3d394820d Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Wed, 22 Sep 2021 12:23:08 +0100 Subject: [PATCH 53/56] Apply suggestions from code review Co-authored-by: Dongdong Tian --- pygmt/src/grd2xyz.py | 8 ++++---- pygmt/tests/test_grd2xyz.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 0985e117dac..22f334ad354 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -74,18 +74,18 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): if outfile is not None and output_type != "file": msg = ( - f"Changing `output_type` of grd2xyz from '{output_type}' to 'file' " - "since `outfile` parameter is set. Please use `output_type='file'` " + f"Changing 'output_type' of grd2xyz from '{output_type}' to 'file' " + "since 'outfile' parameter is set. Please use output_type='file' " "to silence this warning." ) warnings.warn(message=msg, category=RuntimeWarning, stacklevel=2) output_type = "file" elif outfile is None and output_type == "file": - raise GMTInvalidInput("Must specify `outfile` for ASCII output.") + raise GMTInvalidInput("Must specify 'outfile' for ASCII output.") if "o" in kwargs and output_type == "pandas": raise GMTInvalidInput( - "If 'outcols' is specified, `output_type` must be either 'numpy'" + "If 'outcols' is specified, 'output_type' must be either 'numpy'" "or 'file'." ) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index a209b2263aa..654c053aaea 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -90,7 +90,7 @@ def test_grd2xyz_outfile_incorrect_output_type(grid): def test_grd2xyz_pandas_output_with_o(grid): """ - Test that grd2xyz fails when 'o' is set and output_type is set to 'pandas'. + Test that grd2xyz fails when outcols is set and output_type is set to 'pandas'. """ with pytest.raises(GMTInvalidInput): - grd2xyz(grid=grid, output_type="pandas", o="2") + grd2xyz(grid=grid, output_type="pandas", outcols="2") From 6731814075e1640f841a7b722ba4c9201c29f17c Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Wed, 22 Sep 2021 12:34:01 +0100 Subject: [PATCH 54/56] Update pygmt/src/grd2xyz.py Co-authored-by: Dongdong Tian --- pygmt/src/grd2xyz.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pygmt/src/grd2xyz.py b/pygmt/src/grd2xyz.py index 22f334ad354..c6404febf63 100644 --- a/pygmt/src/grd2xyz.py +++ b/pygmt/src/grd2xyz.py @@ -63,8 +63,7 @@ def grd2xyz(grid, output_type="pandas", outfile=None, **kwargs): - None if ``outfile`` is set (output will be stored in file set by ``outfile``) - :class:`pandas.DataFrame` or :class:`numpy.ndarray` if ``outfile`` is - not set (depends on ``output_type`` [Default is - :class:`pandas.DataFrame`]) + not set (depends on ``output_type``) """ if output_type not in ["numpy", "pandas", "file"]: From f49dac07f6a9a1cb1940c3fdafc06c5f355aba69 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Wed, 22 Sep 2021 12:40:54 +0100 Subject: [PATCH 55/56] fix sentence in docstring --- pygmt/tests/test_grd2xyz.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index 654c053aaea..7efaff0297a 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -78,8 +78,8 @@ def test_grd2xyz_no_outfile(grid): def test_grd2xyz_outfile_incorrect_output_type(grid): """ - Test that grd2xyz raises a warning when an outfile name is set but the - output_type is not set to file is set with no outfile. + Test that grd2xyz raises a warning when an outfile filename is set but the + output_type is not set to 'file'. """ with pytest.warns(RuntimeWarning): with GMTTempFile(suffix=".xyz") as tmpfile: From 708e3c42a31c88e0142b0ff68f8d72d209c50442 Mon Sep 17 00:00:00 2001 From: Will Schlitzer Date: Wed, 22 Sep 2021 13:12:48 +0100 Subject: [PATCH 56/56] run make format --- pygmt/tests/test_grd2xyz.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pygmt/tests/test_grd2xyz.py b/pygmt/tests/test_grd2xyz.py index 7efaff0297a..230132dc548 100644 --- a/pygmt/tests/test_grd2xyz.py +++ b/pygmt/tests/test_grd2xyz.py @@ -90,7 +90,8 @@ def test_grd2xyz_outfile_incorrect_output_type(grid): def test_grd2xyz_pandas_output_with_o(grid): """ - Test that grd2xyz fails when outcols is set and output_type is set to 'pandas'. + Test that grd2xyz fails when outcols is set and output_type is set to + 'pandas'. """ with pytest.raises(GMTInvalidInput): grd2xyz(grid=grid, output_type="pandas", outcols="2")