diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index bcd38cd3ecf..7680e81108e 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -1748,16 +1748,18 @@ def virtualfile_from_stringio( seg.header = None seg.text = None + # TODO(PyGMT>=0.20.0): Remove the deprecated parameter 'required_z'. # TODO(PyGMT>=0.20.0): Remove the deprecated parameter 'extra_arrays'. - def virtualfile_in( + def virtualfile_in( # noqa: PLR0912 self, check_kind=None, data=None, x=None, y=None, z=None, - required_z=False, + mincols=2, required_data=True, + required_z=False, extra_arrays=None, ): """ @@ -1778,11 +1780,19 @@ def virtualfile_in( data input. x/y/z : 1-D arrays or None x, y, and z columns as numpy arrays. - required_z : bool - State whether the 'z' column is required. + mincols + Number of minimum required columns. Default is 2 (i.e. require x and y + columns). required_data : bool Set to True when 'data' is required, or False when dealing with optional virtual files. [Default is True]. + required_z : bool + State whether the 'z' column is required. + + .. deprecated:: v0.16.0 + The parameter 'required_z' will be removed in v0.20.0. Use parameter + 'mincols' instead. E.g., ``required_z=True`` is equivalent to + ``mincols=3``. extra_arrays : list of 1-D arrays A list of numpy arrays in addition to x, y, and z. All of these arrays must be of the same size as the x/y/z arrays. @@ -1818,13 +1828,23 @@ def virtualfile_in( ... print(fout.read().strip()) : N = 3 <7/9> <4/6> <1/3> """ + if required_z is True: + warnings.warn( + "The parameter 'required_z' is deprecated in v0.16.0 and will be " + "removed in v0.20.0. Use parameter 'mincols' instead. E.g., " + "``required_z=True`` is equivalent to ``mincols=3``.", + category=FutureWarning, + stacklevel=1, + ) + mincols = 3 + kind = data_kind(data, required=required_data) _validate_data_input( data=data, x=x, y=y, z=z, - required_z=required_z, + mincols=mincols, required_data=required_data, kind=kind, ) diff --git a/pygmt/helpers/utils.py b/pygmt/helpers/utils.py index 6dcf71bf890..7223e45fe94 100644 --- a/pygmt/helpers/utils.py +++ b/pygmt/helpers/utils.py @@ -43,7 +43,7 @@ def _validate_data_input( # noqa: PLR0912 - data=None, x=None, y=None, z=None, required_z=False, required_data=True, kind=None + data=None, x=None, y=None, z=None, mincols=2, required_data=True, kind=None ) -> None: """ Check if the combination of data/x/y/z is valid. @@ -66,7 +66,7 @@ def _validate_data_input( # noqa: PLR0912 Traceback (most recent call last): ... pygmt.exceptions.GMTInvalidInput: Must provide both x and y. - >>> _validate_data_input(x=[1, 2, 3], y=[4, 5, 6], required_z=True) + >>> _validate_data_input(x=[1, 2, 3], y=[4, 5, 6], mincols=3) Traceback (most recent call last): ... pygmt.exceptions.GMTInvalidInput: Must provide x, y, and z. @@ -74,13 +74,13 @@ def _validate_data_input( # noqa: PLR0912 >>> import pandas as pd >>> import xarray as xr >>> data = np.arange(8).reshape((4, 2)) - >>> _validate_data_input(data=data, required_z=True, kind="matrix") + >>> _validate_data_input(data=data, mincols=3, kind="matrix") Traceback (most recent call last): ... pygmt.exceptions.GMTInvalidInput: data must provide x, y, and z columns. >>> _validate_data_input( ... data=pd.DataFrame(data, columns=["x", "y"]), - ... required_z=True, + ... mincols=3, ... kind="vectors", ... ) Traceback (most recent call last): @@ -88,7 +88,7 @@ def _validate_data_input( # noqa: PLR0912 pygmt.exceptions.GMTInvalidInput: data must provide x, y, and z columns. >>> _validate_data_input( ... data=xr.Dataset(pd.DataFrame(data, columns=["x", "y"])), - ... required_z=True, + ... mincols=3, ... kind="vectors", ... ) Traceback (most recent call last): @@ -116,6 +116,7 @@ def _validate_data_input( # noqa: PLR0912 GMTInvalidInput If the data input is not valid. """ + required_z = mincols >= 3 if data is None: # data is None if x is None and y is None: # both x and y are None if required_data: # data is not optional diff --git a/pygmt/src/blockm.py b/pygmt/src/blockm.py index 9c995eb6782..6c32331d298 100644 --- a/pygmt/src/blockm.py +++ b/pygmt/src/blockm.py @@ -56,7 +56,7 @@ def _blockm( with Session() as lib: with ( lib.virtualfile_in( - check_kind="vector", data=data, x=x, y=y, z=z, required_z=True + check_kind="vector", data=data, x=x, y=y, z=z, mincols=3 ) as vintbl, lib.virtualfile_out(kind="dataset", fname=outfile) as vouttbl, ): diff --git a/pygmt/src/contour.py b/pygmt/src/contour.py index 39a5a7b93cb..ad20bf80c2a 100644 --- a/pygmt/src/contour.py +++ b/pygmt/src/contour.py @@ -148,7 +148,7 @@ def contour( with Session() as lib: with lib.virtualfile_in( - check_kind="vector", data=data, x=x, y=y, z=z, required_z=True + check_kind="vector", data=data, x=x, y=y, z=z, mincols=3 ) as vintbl: lib.call_module( module="contour", args=build_arg_list(kwargs, infile=vintbl) diff --git a/pygmt/src/nearneighbor.py b/pygmt/src/nearneighbor.py index 1efb3e0ad29..118eba785b0 100644 --- a/pygmt/src/nearneighbor.py +++ b/pygmt/src/nearneighbor.py @@ -147,7 +147,7 @@ def nearneighbor( with Session() as lib: with ( lib.virtualfile_in( - check_kind="vector", data=data, x=x, y=y, z=z, required_z=True + check_kind="vector", data=data, x=x, y=y, z=z, mincols=3 ) as vintbl, lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd, ): diff --git a/pygmt/src/plot3d.py b/pygmt/src/plot3d.py index 45545e9da96..f50894ec060 100644 --- a/pygmt/src/plot3d.py +++ b/pygmt/src/plot3d.py @@ -259,7 +259,5 @@ def plot3d( # noqa: PLR0912 kwargs["S"] = "u0.2c" with Session() as lib: - with lib.virtualfile_in( - check_kind="vector", data=data, required_z=True - ) as vintbl: + with lib.virtualfile_in(check_kind="vector", data=data, mincols=3) as vintbl: lib.call_module(module="plot3d", args=build_arg_list(kwargs, infile=vintbl)) diff --git a/pygmt/src/project.py b/pygmt/src/project.py index 99bcb221021..1356b84495f 100644 --- a/pygmt/src/project.py +++ b/pygmt/src/project.py @@ -246,7 +246,7 @@ def project( x=x, y=y, z=z, - required_z=False, + mincols=2, required_data=False, ) as vintbl, lib.virtualfile_out(kind="dataset", fname=outfile) as vouttbl, diff --git a/pygmt/src/surface.py b/pygmt/src/surface.py index 28b0a68a370..d33027b5b7c 100644 --- a/pygmt/src/surface.py +++ b/pygmt/src/surface.py @@ -161,7 +161,7 @@ def surface( with Session() as lib: with ( lib.virtualfile_in( - check_kind="vector", data=data, x=x, y=y, z=z, required_z=True + check_kind="vector", data=data, x=x, y=y, z=z, mincols=3 ) as vintbl, lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd, ): diff --git a/pygmt/src/triangulate.py b/pygmt/src/triangulate.py index 51c915c5209..aa50e9d927c 100644 --- a/pygmt/src/triangulate.py +++ b/pygmt/src/triangulate.py @@ -144,7 +144,7 @@ def regular_grid( with Session() as lib: with ( lib.virtualfile_in( - check_kind="vector", data=data, x=x, y=y, z=z, required_z=False + check_kind="vector", data=data, x=x, y=y, z=z, mincols=2 ) as vintbl, lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd, ): @@ -244,7 +244,7 @@ def delaunay_triples( with Session() as lib: with ( lib.virtualfile_in( - check_kind="vector", data=data, x=x, y=y, z=z, required_z=False + check_kind="vector", data=data, x=x, y=y, z=z, mincols=2 ) as vintbl, lib.virtualfile_out(kind="dataset", fname=outfile) as vouttbl, ): diff --git a/pygmt/src/wiggle.py b/pygmt/src/wiggle.py index 5bb73439604..c507d13f9f8 100644 --- a/pygmt/src/wiggle.py +++ b/pygmt/src/wiggle.py @@ -109,6 +109,6 @@ def wiggle( with Session() as lib: with lib.virtualfile_in( - check_kind="vector", data=data, x=x, y=y, z=z, required_z=True + check_kind="vector", data=data, x=x, y=y, z=z, mincols=3 ) as vintbl: lib.call_module(module="wiggle", args=build_arg_list(kwargs, infile=vintbl)) diff --git a/pygmt/src/xyz2grd.py b/pygmt/src/xyz2grd.py index 4eca0f2e581..4ff93bda894 100644 --- a/pygmt/src/xyz2grd.py +++ b/pygmt/src/xyz2grd.py @@ -155,7 +155,7 @@ def xyz2grd( with Session() as lib: with ( lib.virtualfile_in( - check_kind="vector", data=data, x=x, y=y, z=z, required_z=True + check_kind="vector", data=data, x=x, y=y, z=z, mincols=3 ) as vintbl, lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd, ): diff --git a/pygmt/tests/test_clib_virtualfile_in.py b/pygmt/tests/test_clib_virtualfile_in.py index bf7c54b1bba..7203bbcd4ad 100644 --- a/pygmt/tests/test_clib_virtualfile_in.py +++ b/pygmt/tests/test_clib_virtualfile_in.py @@ -41,9 +41,7 @@ def test_virtualfile_in_required_z_matrix(array_func, kind): ) data = array_func(dataframe) with clib.Session() as lib: - with lib.virtualfile_in( - data=data, required_z=True, check_kind="vector" - ) as vfile: + with lib.virtualfile_in(data=data, mincols=3, check_kind="vector") as vfile: with GMTTempFile() as outfile: lib.call_module("info", [vfile, f"->{outfile.name}"]) output = outfile.read(keep_tabs=True) @@ -64,10 +62,26 @@ def test_virtualfile_in_required_z_matrix_missing(): data = np.ones((5, 2)) with clib.Session() as lib: with pytest.raises(GMTInvalidInput): - with lib.virtualfile_in(data=data, required_z=True, check_kind="vector"): + with lib.virtualfile_in(data=data, mincols=3, check_kind="vector"): pass +# TODO(PyGMT>=0.20.0): Remove this test for the deprecated 'required_z' parameter. +def test_virtualfile_in_required_z_deprecated(): + """ + Same as test_virtualfile_in_required_z_matrix_missing but using the deprecated + 'required_z' parameter. + """ + data = np.ones((5, 2)) + with clib.Session() as lib: + with pytest.raises(GMTInvalidInput): # noqa: PT012 + with pytest.warns(FutureWarning): + with lib.virtualfile_in( + data=data, required_z=True, check_kind="vector" + ): + pass + + def test_virtualfile_in_fail_non_valid_data(data): """ Should raise an exception if too few or too much data is given. @@ -91,7 +105,7 @@ def test_virtualfile_in_fail_non_valid_data(data): with clib.Session() as lib: with pytest.raises(GMTInvalidInput): lib.virtualfile_in( - x=variable[0], y=variable[1], z=variable[2], required_z=True + x=variable[0], y=variable[1], z=variable[2], mincols=3 ) # Should also fail if given too much data