diff --git a/doc/api/index.rst b/doc/api/index.rst index 0426f79385d..e08f1c0aacb 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -81,6 +81,7 @@ Operations on tabular data: blockmean blockmedian + blockmode surface Operations on grids: diff --git a/pygmt/__init__.py b/pygmt/__init__.py index 4963c21a163..554f8646e4d 100644 --- a/pygmt/__init__.py +++ b/pygmt/__init__.py @@ -32,6 +32,7 @@ from pygmt.src import ( blockmean, blockmedian, + blockmode, config, grd2cpt, grdclip, diff --git a/pygmt/src/__init__.py b/pygmt/src/__init__.py index e70e74367b6..a7f1e1c74ef 100644 --- a/pygmt/src/__init__.py +++ b/pygmt/src/__init__.py @@ -4,7 +4,7 @@ # pylint: disable=import-outside-toplevel from pygmt.src.basemap import basemap -from pygmt.src.blockm import blockmean, blockmedian +from pygmt.src.blockm import blockmean, blockmedian, blockmode from pygmt.src.coast import coast from pygmt.src.colorbar import colorbar from pygmt.src.config import config diff --git a/pygmt/src/blockm.py b/pygmt/src/blockm.py index b835d174d8a..a0484cfae97 100644 --- a/pygmt/src/blockm.py +++ b/pygmt/src/blockm.py @@ -1,5 +1,5 @@ """ -blockm - Block average (x,y,z) data tables by mean or median estimation. +blockm - Block average (x,y,z) data tables by mean, median, or mode estimation. """ import pandas as pd from pygmt.clib import Session @@ -14,18 +14,19 @@ def _blockm(block_method, table, outfile, x, y, z, **kwargs): r""" - Block average (x,y,z) data tables by mean or median estimation. + Block average (x,y,z) data tables by mean, median, or mode estimation. Reads arbitrarily located (x,y,z) triples [or optionally weighted - quadruples (x,y,z,w)] from a table and writes to the output a mean or - median (depending on ``block_method``) position and value for every - non-empty block in a grid region defined by the ``region`` and ``spacing`` - parameters. + quadruples (x,y,z,w)] from a table and writes to the output a mean, + median, or mode (depending on ``block_method``) position and value for + every non-empty block in a grid region defined by the ``region`` and + ``spacing`` parameters. Parameters ---------- block_method : str - Name of the GMT module to call. Must be "blockmean" or "blockmedian". + Name of the GMT module to call. Must be "blockmean", "blockmedian" or + "blockmode". Returns ------- @@ -226,3 +227,82 @@ def blockmedian(table=None, outfile=None, *, x=None, y=None, z=None, **kwargs): z=z, **kwargs ) + + +@fmt_docstring +@use_alias( + I="spacing", + R="region", + V="verbose", + a="aspatial", + b="binary", + d="data", + e="find", + f="coltypes", + h="header", + i="incols", + o="outcols", + r="registration", + s="skiprows", + w="wrap", +) +@kwargs_to_strings(R="sequence", i="sequence_comma") +def blockmode(table=None, outfile=None, *, x=None, y=None, z=None, **kwargs): + r""" + Block average (x,y,z) data tables by mode estimation. + + Reads arbitrarily located (x,y,z) triples [or optionally weighted + quadruples (x,y,z,w)] and writes to the output a mode position and value + for every non-empty block in a grid region defined by the ``region`` and + ``spacing`` parameters. + + Takes a matrix, xyz triplets, or a file name as input. + + Must provide either ``table`` or ``x``, ``y``, and ``z``. + + Full option list at :gmt-docs:`blockmode.html` + + {aliases} + + Parameters + ---------- + table : str or {table-like} + Pass in (x, y, z) or (longitude, latitude, elevation) values by + providing a file name to an ASCII data table, a 2D + {table-classes}. + x/y/z : 1d arrays + Arrays of x and y coordinates and values z of the data points. + + {I} + + {R} + + outfile : str + The file name for the output ASCII file. + + {V} + {a} + {b} + {d} + {e} + {f} + {h} + {i} + {o} + {r} + {s} + {w} + + Returns + ------- + output : pandas.DataFrame or None + Return type depends on whether the ``outfile`` parameter is set: + + - :class:`pandas.DataFrame` table with (x, y, z) columns if ``outfile`` + is not set. + - None if ``outfile`` is set (filtered output will be stored in file + set by ``outfile``). + """ + return _blockm( + block_method="blockmode", table=table, outfile=outfile, x=x, y=y, z=z, **kwargs + ) diff --git a/pygmt/tests/test_blockmean.py b/pygmt/tests/test_blockm.py similarity index 86% rename from pygmt/tests/test_blockmean.py rename to pygmt/tests/test_blockm.py index 67f232a6c6e..39a0e315f7f 100644 --- a/pygmt/tests/test_blockmean.py +++ b/pygmt/tests/test_blockm.py @@ -1,12 +1,12 @@ """ -Tests for blockmean. +Tests for blockmean and blockmode. """ import os import numpy.testing as npt import pandas as pd import pytest -from pygmt import blockmean +from pygmt import blockmean, blockmode from pygmt.datasets import load_sample_bathymetry from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import GMTTempFile, data_kind @@ -96,3 +96,14 @@ def test_blockmean_without_outfile_setting(): assert isinstance(output, pd.DataFrame) assert output.shape == (5849, 3) npt.assert_allclose(output.iloc[0], [245.888877, 29.978707, -384.0]) + + +def test_blockmode_input_dataframe(dataframe): + """ + Run blockmode by passing in a pandas.DataFrame as input. + """ + output = blockmode(table=dataframe, spacing="5m", region=[245, 255, 20, 30]) + assert isinstance(output, pd.DataFrame) + assert all(dataframe.columns == output.columns) + assert output.shape == (5849, 3) + npt.assert_allclose(output.iloc[0], [245.88819, 29.97895, -385.0])