From dfecaa5b026c9c3f2189212496a80d2cdfb2a243 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 19 Oct 2024 08:15:58 +0800 Subject: [PATCH 1/5] Fix several small typos (#3534) --- examples/tutorials/advanced/draping_on_3d_surface.py | 2 +- pygmt/accessors.py | 2 +- ..._360.png.dvc => test_grdimage_grid_no_redundant_360.png.dvc} | 2 +- pygmt/tests/test_clib_read_data.py | 2 +- pygmt/tests/test_datatypes_dataset.py | 2 +- pygmt/tests/test_grdimage.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename pygmt/tests/baseline/{test_grdimage_grid_no_redunant_360.png.dvc => test_grdimage_grid_no_redundant_360.png.dvc} (60%) diff --git a/examples/tutorials/advanced/draping_on_3d_surface.py b/examples/tutorials/advanced/draping_on_3d_surface.py index 5a91985b8bc..eaa85cd367e 100644 --- a/examples/tutorials/advanced/draping_on_3d_surface.py +++ b/examples/tutorials/advanced/draping_on_3d_surface.py @@ -112,7 +112,7 @@ fig = pygmt.Figure() # Set up a colormap with two colors for the EU flag: blue (0/51/153) for the background -# (value 0 in the nedCDF file -> lower half of 0-255 range) and yellow (255/204/0) for +# (value 0 in the netCDF file -> lower half of 0-255 range) and yellow (255/204/0) for # the stars (value 255 -> upper half) pygmt.makecpt(cmap="0/51/153,255/204/0", series=[0, 256, 128]) diff --git a/pygmt/accessors.py b/pygmt/accessors.py index b00b11f747c..0b401e43256 100644 --- a/pygmt/accessors.py +++ b/pygmt/accessors.py @@ -60,7 +60,7 @@ class GMTDataArrayAccessor: >>> longrid, latgrid = np.meshgrid(lon, lat) >>> data = np.sin(np.deg2rad(longrid)) * np.cos(np.deg2rad(latgrid)) >>> grid = xr.DataArray(data, coords=[("latitude", lat), ("longitude", lon)]) - >>> # default to a gridline-registrated Cartesian grid + >>> # default to a gridline-registered Cartesian grid >>> grid.gmt.registration, grid.gmt.gtype (0, 0) >>> # set it to a gridline-registered geographic grid diff --git a/pygmt/tests/baseline/test_grdimage_grid_no_redunant_360.png.dvc b/pygmt/tests/baseline/test_grdimage_grid_no_redundant_360.png.dvc similarity index 60% rename from pygmt/tests/baseline/test_grdimage_grid_no_redunant_360.png.dvc rename to pygmt/tests/baseline/test_grdimage_grid_no_redundant_360.png.dvc index 55edc71dbfe..4e687dc0981 100644 --- a/pygmt/tests/baseline/test_grdimage_grid_no_redunant_360.png.dvc +++ b/pygmt/tests/baseline/test_grdimage_grid_no_redundant_360.png.dvc @@ -2,4 +2,4 @@ outs: - md5: 6145622653eaedd2b4845400aa09ac75 size: 239431 hash: md5 - path: test_grdimage_grid_no_redunant_360.png + path: test_grdimage_grid_no_redundant_360.png diff --git a/pygmt/tests/test_clib_read_data.py b/pygmt/tests/test_clib_read_data.py index 231d2a1a533..09c4e1f6fe9 100644 --- a/pygmt/tests/test_clib_read_data.py +++ b/pygmt/tests/test_clib_read_data.py @@ -207,4 +207,4 @@ def test_clib_read_data_fails(): """ with Session() as lib: with pytest.raises(GMTCLibError): - lib.read_data("not-exsits.txt", kind="dataset") + lib.read_data("not-exists.txt", kind="dataset") diff --git a/pygmt/tests/test_datatypes_dataset.py b/pygmt/tests/test_datatypes_dataset.py index 78c51e827e5..56f18143035 100644 --- a/pygmt/tests/test_datatypes_dataset.py +++ b/pygmt/tests/test_datatypes_dataset.py @@ -94,7 +94,7 @@ def test_dataset_header(): print("1.0 2.0 3.0 TEXT1 TEXT23", file=fp) print("4.0 5.0 6.0 TEXT4 TEXT567", file=fp) - # Parse columne names from the first header line + # Parse column names from the first header line df = dataframe_from_gmt(tmpfile.name, header=0) assert df.columns.tolist() == ["lon", "lat", "z", "text"] # pd.read_csv() can't parse the header line with a leading '#'. diff --git a/pygmt/tests/test_grdimage.py b/pygmt/tests/test_grdimage.py index ee48875240a..943b3f12ddc 100644 --- a/pygmt/tests/test_grdimage.py +++ b/pygmt/tests/test_grdimage.py @@ -261,7 +261,7 @@ def test_grdimage_imgout_fails(grid): reason="Upstream bug fixed in https://github.com/GenericMappingTools/gmt/pull/8554", ) @pytest.mark.mpl_image_compare() -def test_grdimage_grid_no_redunant_360(): +def test_grdimage_grid_no_redundant_360(): """ Test that global grids with and without redundant 360/0 longitude values work. From 17c0a84c3896bcaed873fc92dce8582a8627f94f Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 19 Oct 2024 08:38:32 +0800 Subject: [PATCH 2/5] Add two tests for the deprecated Session.open_virtual_file and Session.virtualfile_from_data methods (#3527) --- pygmt/clib/session.py | 2 +- pygmt/tests/test_clib_virtualfile_in.py | 30 +++++++++++++++++++++++++ pygmt/tests/test_clib_virtualfiles.py | 30 +++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index 043f2715620..5d3c7f9406b 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -1852,7 +1852,7 @@ def virtualfile_from_data( instead. """ msg = ( - "API function 'Session.virtualfile_from_datae()' has been deprecated since " + "API function 'Session.virtualfile_from_data()' has been deprecated since " "v0.13.0 and will be removed in v0.15.0. Use 'Session.virtualfile_in()' " "instead." ) diff --git a/pygmt/tests/test_clib_virtualfile_in.py b/pygmt/tests/test_clib_virtualfile_in.py index d854d556050..aac8e4af772 100644 --- a/pygmt/tests/test_clib_virtualfile_in.py +++ b/pygmt/tests/test_clib_virtualfile_in.py @@ -127,3 +127,33 @@ def test_virtualfile_in_matrix_string_dtype(): assert output == "347.5 348.5 -30.5 -30\n" # Should check that lib.virtualfile_from_vectors is called once, # not lib.virtualfile_from_matrix, but it's technically complicated. + + +def test_virtualfile_from_data(): + """ + Test the backwards compatibility of the virtualfile_from_data method. + + This test is the same as test_virtualfile_in_required_z_matrix, but using the + deprecated method. + """ + shape = (5, 3) + dataframe = pd.DataFrame( + data=np.arange(shape[0] * shape[1]).reshape(shape), columns=["x", "y", "z"] + ) + data = np.array(dataframe) + with clib.Session() as lib: + with pytest.warns(FutureWarning, match="virtualfile_from_data"): + with lib.virtualfile_from_data( + data=data, required_z=True, check_kind="vector" + ) as vfile: + with GMTTempFile() as outfile: + lib.call_module("info", [vfile, f"->{outfile.name}"]) + output = outfile.read(keep_tabs=True) + bounds = "\t".join( + [ + f"<{i.min():.0f}/{i.max():.0f}>" + for i in (dataframe.x, dataframe.y, dataframe.z) + ] + ) + expected = f": N = {shape[0]}\t{bounds}\n" + assert output == expected diff --git a/pygmt/tests/test_clib_virtualfiles.py b/pygmt/tests/test_clib_virtualfiles.py index f913d7e5472..7119691455b 100644 --- a/pygmt/tests/test_clib_virtualfiles.py +++ b/pygmt/tests/test_clib_virtualfiles.py @@ -120,3 +120,33 @@ def test_open_virtualfile_bad_direction(): with pytest.raises(GMTInvalidInput): with lib.open_virtualfile(*vfargs): pass + + +def test_open_virtual_file(): + """ + Test the deprecated Session.open_virtual_file method. + + This test is the same as test_open_virtualfile, but using the deprecated method. + """ + shape = (5, 3) + with clib.Session() as lib: + family = "GMT_IS_DATASET|GMT_VIA_MATRIX" + geometry = "GMT_IS_POINT" + dataset = lib.create_data( + family=family, + geometry=geometry, + mode="GMT_CONTAINER_ONLY", + dim=[shape[1], shape[0], 1, 0], # columns, rows, layers, dtype + ) + data = np.arange(shape[0] * shape[1]).reshape(shape) + lib.put_matrix(dataset, matrix=data) + # Add the dataset to a virtual file and pass it along to gmt info + with pytest.warns(FutureWarning, match="open_virtual_file"): + vfargs = (family, geometry, "GMT_IN|GMT_IS_REFERENCE", dataset) + with lib.open_virtual_file(*vfargs) as vfile: + with GMTTempFile() as outfile: + lib.call_module("info", [vfile, f"->{outfile.name}"]) + output = outfile.read(keep_tabs=True) + bounds = "\t".join([f"<{col.min():.0f}/{col.max():.0f}>" for col in data.T]) + expected = f": N = {shape[0]}\t{bounds}\n" + assert output == expected From 28bfaf93a9b2386e18273a717a87246359722f2c Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 19 Oct 2024 08:49:10 +0800 Subject: [PATCH 3/5] Enable ruff's flake8-commas (COM) and refurb (FURB) rules (#3531) --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 74516aefd87..8819d4e7b1b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -90,12 +90,14 @@ select = [ "B", # flake8-bugbear "BLE", # flake8-blind-except "C4", # flake8-comprehensions + "COM", # flake8-commas "D", # pydocstyle "E", # pycodestyle "EXE", # flake8-executable "F", # pyflakes "FA", # flake8-future-annotations "FLY", # flynt + "FURB", # refurb "I", # isort "ICN", # flake8-import-conventions "ISC", # flake8-implicit-str-concat @@ -127,6 +129,7 @@ extend-select = [ "PLW1514", # {function_name} in text mode without explicit encoding argument ] ignore = [ + "COM812", # Do not always add the trailing commas "D200", # One-line docstring should fit on one line "D202", # No blank lines allowed after function docstring "D205", # 1 blank line required between summary line and description From 510e14558be76cc6fa8f88542ff6f6521915b661 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 19 Oct 2024 08:52:44 +0800 Subject: [PATCH 4/5] clib.Session: Add type hints and format docstrings for some Session methods (#3530) --- pygmt/clib/conversion.py | 4 +- pygmt/clib/session.py | 247 +++++++++++++++++++-------------------- 2 files changed, 121 insertions(+), 130 deletions(-) diff --git a/pygmt/clib/conversion.py b/pygmt/clib/conversion.py index 07f8756adcd..412a18af63f 100644 --- a/pygmt/clib/conversion.py +++ b/pygmt/clib/conversion.py @@ -281,7 +281,7 @@ def sequence_to_ctypes_array( return (ctype * size)(*sequence) -def strings_to_ctypes_array(strings: Sequence[str]) -> ctp.Array: +def strings_to_ctypes_array(strings: Sequence[str] | np.ndarray) -> ctp.Array: """ Convert a sequence (e.g., a list) of strings into a ctypes array. @@ -307,7 +307,7 @@ def strings_to_ctypes_array(strings: Sequence[str]) -> ctp.Array: return (ctp.c_char_p * len(strings))(*[s.encode() for s in strings]) -def array_to_datetime(array: Sequence[Any]) -> np.ndarray: +def array_to_datetime(array: Sequence[Any] | np.ndarray) -> np.ndarray: """ Convert a 1-D datetime array from various types into numpy.datetime64. diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index 5d3c7f9406b..f87b258bc95 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -866,41 +866,39 @@ def _check_dtype_and_dim(self, array, ndim): ) from e return self[DTYPES[array.dtype.type]] - def put_vector(self, dataset, column, vector): + def put_vector(self, dataset: ctp.c_void_p, column: int, vector: np.ndarray): r""" - Attach a numpy 1-D array as a column on a GMT dataset. + Attach a 1-D numpy array as a column on a GMT dataset. - Use this function to attach numpy array data to a GMT dataset and pass - it to GMT modules. Wraps ``GMT_Put_Vector``. + Use this function to attach numpy array data to a GMT dataset and pass it to GMT + modules. Wraps ``GMT_Put_Vector``. - The dataset must be created by :meth:`pygmt.clib.Session.create_data` - first. Use ``family='GMT_IS_DATASET|GMT_VIA_VECTOR'``. + The dataset must be created by :meth:`pygmt.clib.Session.create_data` first with + ``family="GMT_IS_DATASET|GMT_VIA_VECTOR"``. - Not all numpy dtypes are supported, only: int8, int16, int32, int64, - uint8, uint16, uint32, uint64, float32, float64, str\_, and datetime64. + Not all numpy dtypes are supported, only: int8, int16, int32, int64, uint8, + uint16, uint32, uint64, float32, float64, str\_, and datetime64. .. warning:: - The numpy array must be C contiguous in memory. If it comes from a - column slice of a 2-D array, for example, you will have to make a - copy. Use :func:`numpy.ascontiguousarray` to make sure your vector - is contiguous (it won't copy if it already is). + The numpy array must be C contiguous in memory. Use + :func:`numpy.ascontiguousarray` to make sure your vector is contiguous (it + won't copy if it already is). Parameters ---------- - dataset : :class:`ctypes.c_void_p` - The ctypes void pointer to a ``GMT_Dataset``. Create it with + dataset + The ctypes void pointer to a ``GMT_VECTOR`` data container. Create it with :meth:`pygmt.clib.Session.create_data`. - column : int + column The column number of this vector in the dataset (starting from 0). - vector : numpy 1-D array - The array that will be attached to the dataset. Must be a 1-D C - contiguous array. + vector + The array that will be attached to the dataset. Must be a 1-D C contiguous + array. Raises ------ GMTCLibError - If given invalid input or ``GMT_Put_Vector`` exits with - status != 0. + If given invalid input or ``GMT_Put_Vector`` exits with a non-zero status. """ c_put_vector = self.get_libgmt_func( "GMT_Put_Vector", @@ -908,6 +906,7 @@ def put_vector(self, dataset, column, vector): restype=ctp.c_int, ) + vector_pointer: ctp.Array | ctp.c_void_p gmt_type = self._check_dtype_and_dim(vector, ndim=1) if gmt_type in {self["GMT_TEXT"], self["GMT_DATETIME"]}: if gmt_type == self["GMT_DATETIME"]: @@ -919,52 +918,51 @@ def put_vector(self, dataset, column, vector): self.session_pointer, dataset, column, gmt_type, vector_pointer ) if status != 0: - raise GMTCLibError( - f"Failed to put vector of type {vector.dtype} " - f"in column {column} of dataset." + msg = ( + f"Failed to put vector of type {vector.dtype} in column {column} of " + "dataset." ) + raise GMTCLibError(msg) - def put_strings(self, dataset, family, strings): + def put_strings(self, dataset: ctp.c_void_p, family: str, strings: np.ndarray): """ - Attach a numpy 1-D array of dtype str as a column on a GMT dataset. + Attach a 1-D numpy array of dtype str as a column on a GMT dataset. - Use this function to attach string type numpy array data to a GMT - dataset and pass it to GMT modules. Wraps ``GMT_Put_Strings``. + Use this function to attach string type numpy array data to a GMT dataset and + pass it to GMT modules. Wraps ``GMT_Put_Strings``. - The dataset must be created by :meth:`pygmt.clib.Session.create_data` - first. + The dataset must be created by :meth:`pygmt.clib.Session.create_data` first. .. warning:: - The numpy array must be C contiguous in memory. If it comes from a - column slice of a 2-D array, for example, you will have to make a - copy. Use :func:`numpy.ascontiguousarray` to make sure your vector - is contiguous (it won't copy if it already is). + The numpy array must be C contiguous in memory. If it comes from a column + slice of a 2-D array, for example, you will have to make a copy. Use + :func:`numpy.ascontiguousarray` to make sure your vector is contiguous (it + won't copy if it already is). Parameters ---------- - dataset : :class:`ctypes.c_void_p` - The ctypes void pointer to a ``GMT_Dataset``. Create it with - :meth:`pygmt.clib.Session.create_data`. - family : str + dataset + The ctypes void pointer to a ``GMT_VECTOR``/``GMT_MATRIX`` data container. + Create it with :meth:`pygmt.clib.Session.create_data`. + family The family type of the dataset. Can be either ``GMT_IS_VECTOR`` or ``GMT_IS_MATRIX``. - strings : numpy 1-D array - The array that will be attached to the dataset. Must be a 1-D C - contiguous array. + strings + The array that will be attached to the dataset. Must be a 1-D C contiguous + array. Raises ------ GMTCLibError - If given invalid input or ``GMT_Put_Strings`` exits with - status != 0. + If given invalid input or ``GMT_Put_Strings`` exits with a non-zero status. """ c_put_strings = self.get_libgmt_func( "GMT_Put_Strings", argtypes=[ - ctp.c_void_p, - ctp.c_uint, - ctp.c_void_p, - ctp.POINTER(ctp.c_char_p), + ctp.c_void_p, # V_API + ctp.c_uint, # family + ctp.c_void_p, # object + ctp.POINTER(ctp.c_char_p), # array ], restype=ctp.c_int, ) @@ -972,52 +970,48 @@ def put_strings(self, dataset, family, strings): family_int = self._parse_constant( family, valid=FAMILIES, valid_modifiers=METHODS ) - strings_pointer = strings_to_ctypes_array(strings) - status = c_put_strings( self.session_pointer, family_int, dataset, strings_pointer ) if status != 0: - raise GMTCLibError( - f"Failed to put strings of type {strings.dtype} into dataset" - ) + msg = f"Failed to put strings of type {strings.dtype} into dataset." + raise GMTCLibError(msg) - def put_matrix(self, dataset, matrix, pad=0): + def put_matrix(self, dataset: ctp.c_void_p, matrix: np.ndarray, pad: int = 0): """ - Attach a numpy 2-D array to a GMT dataset. + Attach a 2-D numpy array to a GMT dataset. - Use this function to attach numpy array data to a GMT dataset and pass - it to GMT modules. Wraps ``GMT_Put_Matrix``. + Use this function to attach numpy array data to a GMT dataset and pass it to GMT + modules. Wraps ``GMT_Put_Matrix``. - The dataset must be created by :meth:`pygmt.clib.Session.create_data` - first. Use ``|GMT_VIA_MATRIX'`` in the family. + The dataset must be created by :meth:`pygmt.clib.Session.create_data` first with + ``family="GMT_IS_DATASET|GMT_VIA_MATRIX"``. - Not all numpy dtypes are supported, only: int8, int16, int32, int64, - uint8, uint16, uint32, uint64, float32, and float64. + Not all numpy dtypes are supported, only: int8, int16, int32, int64, uint8, + uint16, uint32, uint64, float32, and float64. .. warning:: The numpy array must be C contiguous in memory. Use - :func:`numpy.ascontiguousarray` to make sure your vector is - contiguous (it won't copy if it already is). + :func:`numpy.ascontiguousarray` to make sure your matrix is contiguous (it + won't copy if it already is). Parameters ---------- - dataset : :class:`ctypes.c_void_p` - The ctypes void pointer to a ``GMT_Dataset``. Create it with + dataset + The ctypes void pointer to a ``GMT_MATRIX`` data container. Create it with :meth:`pygmt.clib.Session.create_data`. - matrix : numpy 2-D array - The array that will be attached to the dataset. Must be a 2-D C - contiguous array. - pad : int - The amount of padding that should be added to the matrix. Use when - creating grids for modules that require padding. + matrix + The array that will be attached to the dataset. Must be a 2-D C contiguous + array. + pad + The amount of padding that should be added to the matrix. Use when creating + grids for modules that require padding. Raises ------ GMTCLibError - If given invalid input or ``GMT_Put_Matrix`` exits with - status != 0. + If given invalid input or ``GMT_Put_Matrix`` exits with a non-zero status. """ c_put_matrix = self.get_libgmt_func( "GMT_Put_Matrix", @@ -1031,7 +1025,8 @@ def put_matrix(self, dataset, matrix, pad=0): self.session_pointer, dataset, gmt_type, pad, matrix_pointer ) if status != 0: - raise GMTCLibError(f"Failed to put matrix of type {matrix.dtype}.") + msg = f"Failed to put matrix of type {matrix.dtype}." + raise GMTCLibError(msg) def read_data( self, @@ -1432,42 +1427,39 @@ def virtualfile_from_vectors(self, *vectors): yield vfile @contextlib.contextmanager - def virtualfile_from_matrix(self, matrix): + def virtualfile_from_matrix(self, matrix: np.ndarray) -> Generator[str, None, None]: """ - Store a 2-D array as a table inside a virtual file. + Store a 2-D numpy array as a matrix inside a virtual file. - Use the virtual file name to pass in the data in your matrix to a GMT - module. + Use the virtual file name to pass in the data in your matrix to a GMT module. - Context manager (use in a ``with`` block). Yields the virtual file name - that you can pass as an argument to a GMT module call. Closes the - virtual file upon exit of the ``with`` block. + Context manager (use in a ``with`` block). Yields the virtual file name that you + can pass as an argument to a GMT module call. Closes the virtual file upon exit + of the ``with`` block. - The virtual file will contain the array as a ``GMT_MATRIX`` pretending - to be a ``GMT_DATASET``. + The virtual file will contain the array as a ``GMT_MATRIX`` data container + pretending to be a ``GMT_DATASET`` data container. - **Not meant for creating ``GMT_GRID``**. The grid requires more - metadata than just the data matrix. Use - :meth:`pygmt.clib.Session.virtualfile_from_grid` instead. + **Not meant for creating ``GMT_GRID``**. The grid requires more metadata than + just the data matrix. Use :meth:`pygmt.clib.Session.virtualfile_from_grid` + instead. - Use this instead of creating the data container and virtual file by - hand with :meth:`pygmt.clib.Session.create_data`, - :meth:`pygmt.clib.Session.put_matrix`, and - :meth:`pygmt.clib.Session.open_virtualfile` + Use this instead of creating the data container and virtual file by hand with + :meth:`pygmt.clib.Session.create_data`, :meth:`pygmt.clib.Session.put_matrix`, + and :meth:`pygmt.clib.Session.open_virtualfile`. - The matrix must be C contiguous in memory. If it is not (e.g., it is a - slice of a larger array), the array will be copied to make sure it is. + The matrix must be C contiguous in memory. If it is not (e.g., it is a slice of + a larger array), the array will be copied to make sure it is. Parameters ---------- - matrix : 2-D array + matrix The matrix that will be included in the GMT data container. Yields ------ - fname : str - The name of virtual file. Pass this as a file name argument to a - GMT module. + fname + The name of virtual file. Pass this as a file name argument to a GMT module. Examples -------- @@ -1488,12 +1480,11 @@ def virtualfile_from_matrix(self, matrix): ... print(fout.read().strip()) : N = 4 <0/9> <1/10> <2/11> """ - # Conversion to a C-contiguous array needs to be done here and not in - # put_matrix because we need to maintain a reference to the copy while - # it is being used by the C API. Otherwise, the array would be garbage - # collected and the memory freed. Creating it in this context manager - # guarantees that the copy will be around until the virtual file is - # closed. + # Conversion to a C-contiguous array needs to be done here and not in put_matrix + # because we need to maintain a reference to the copy while it is being used by + # the C API. Otherwise, the array would be garbage collected and the memory + # freed. Creating it in this context manager guarantees that the copy will be + # around until the virtual file is closed. matrix = np.ascontiguousarray(matrix) rows, columns = matrix.shape @@ -1512,39 +1503,36 @@ def virtualfile_from_matrix(self, matrix): yield vfile @contextlib.contextmanager - def virtualfile_from_grid(self, grid): + def virtualfile_from_grid(self, grid: xr.DataArray) -> Generator[str, None, None]: """ Store a grid in a virtual file. - Use the virtual file name to pass in the data in your grid to a GMT - module. Grids must be :class:`xarray.DataArray` instances. + Use the virtual file name to pass in the data in your grid to a GMT module. + Grids must be :class:`xarray.DataArray` instances. - Context manager (use in a ``with`` block). Yields the virtual file name - that you can pass as an argument to a GMT module call. Closes the - virtual file upon exit of the ``with`` block. + Context manager (use in a ``with`` block). Yields the virtual file name that you + can pass as an argument to a GMT module call. Closes the virtual file upon exit + of the ``with`` block. - The virtual file will contain the grid as a ``GMT_MATRIX`` with extra - metadata. + The virtual file will contain the grid as a ``GMT_MATRIX`` data container with + extra metadata. - Use this instead of creating a data container and virtual file by hand - with :meth:`pygmt.clib.Session.create_data`, - :meth:`pygmt.clib.Session.put_matrix`, and - :meth:`pygmt.clib.Session.open_virtualfile`. + Use this instead of creating a data container and virtual file by hand with + :meth:`pygmt.clib.Session.create_data`, :meth:`pygmt.clib.Session.put_matrix`, + and :meth:`pygmt.clib.Session.open_virtualfile`. - The grid data matrix must be C contiguous in memory. If it is not - (e.g., it is a slice of a larger array), the array will be copied to - make sure it is. + The grid data matrix must be C contiguous in memory. If it is not (e.g., it is a + slice of a larger array), the array will be copied to make sure it is. Parameters ---------- - grid : :class:`xarray.DataArray` + grid The grid that will be included in the virtual file. Yields ------ - fname : str - The name of virtual file. Pass this as a file name argument to a - GMT module. + fname + The name of virtual file. Pass this as a file name argument to a GMT module. Examples -------- @@ -1574,12 +1562,12 @@ def virtualfile_from_grid(self, grid): _gtype = {0: "GMT_GRID_IS_CARTESIAN", 1: "GMT_GRID_IS_GEO"}[grid.gmt.gtype] _reg = {0: "GMT_GRID_NODE_REG", 1: "GMT_GRID_PIXEL_REG"}[grid.gmt.registration] - # Conversion to a C-contiguous array needs to be done here and not in - # put_matrix because we need to maintain a reference to the copy while - # it is being used by the C API. Otherwise, the array would be garbage - # collected and the memory freed. Creating it in this context manager - # guarantees that the copy will be around until the virtual file is - # closed. The conversion is implicit in dataarray_to_matrix. + # Conversion to a C-contiguous array needs to be done here and not in put_matrix + # because we need to maintain a reference to the copy while it is being used by + # the C API. Otherwise, the array would be garbage collected and the memory + # freed. Creating it in this context manager guarantees that the copy will be + # around until the virtual file is closed. The conversion is implicit in + # dataarray_to_matrix. matrix, region, inc = dataarray_to_matrix(grid) family = "GMT_IS_GRID|GMT_VIA_MATRIX" @@ -1593,12 +1581,15 @@ def virtualfile_from_grid(self, grid): registration=_reg, ) self.put_matrix(gmt_grid, matrix) - args = (family, geometry, "GMT_IN|GMT_IS_REFERENCE", gmt_grid) - with self.open_virtualfile(*args) as vfile: + with self.open_virtualfile( + family, geometry, "GMT_IN|GMT_IS_REFERENCE", gmt_grid + ) as vfile: yield vfile @contextlib.contextmanager - def virtualfile_from_stringio(self, stringio: io.StringIO): + def virtualfile_from_stringio( + self, stringio: io.StringIO + ) -> Generator[str, None, None]: r""" Store a :class:`io.StringIO` object in a virtual file. From d1ab97ca49fd53dcd6d8cf268d344498d39642e5 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 19 Oct 2024 15:16:14 +0800 Subject: [PATCH 5/5] CI: Unpin pandas in the 'GMT Legacy Tests' workflow (#3535) --- .github/workflows/ci_tests_legacy.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci_tests_legacy.yaml b/.github/workflows/ci_tests_legacy.yaml index 8e40304e8f1..675ea7b1b2b 100644 --- a/.github/workflows/ci_tests_legacy.yaml +++ b/.github/workflows/ci_tests_legacy.yaml @@ -1,8 +1,8 @@ # Test PyGMT with GMT legacy versions on Linux/macOS/Windows # -# This workflow runs regular PyGMT tests with GMT legacy versions. Due to the -# minor baseline image changes between GMT versions, the workflow only runs -# the tests but doesn't do image comparisons. +# This workflow runs regular PyGMT tests with GMT legacy versions. Due to the minor +# baseline image changes between GMT versions, the workflow only runs the tests but +# doesn't do image comparisons. # # It is scheduled to run every Tuesday on the main branch. # @@ -63,7 +63,7 @@ jobs: gmt=${{ matrix.gmt_version }} ghostscript<10 numpy - pandas<2 + pandas xarray netCDF4 packaging @@ -85,9 +85,9 @@ jobs: run: | # Download cached files to ~/.gmt directory and list them gh run download --name gmt-cache --dir ~/.gmt/ - # Change modification times of the two files, so GMT won't refresh it - # The two files are in the `~/.gmt/server` directory for GMT<=6.4, and - # in the `~/.gmt` directory for GMT>=6.5. + # Change modification times of the two files, so GMT won't refresh it. + # The two files are in the `~/.gmt/server` directory for GMT<=6.4, and in the + # `~/.gmt` directory for GMT>=6.5. mkdir -p ~/.gmt/server/ mv ~/.gmt/gmt_data_server.txt ~/.gmt/gmt_hash_server.txt ~/.gmt/server/ touch ~/.gmt/server/gmt_data_server.txt ~/.gmt/server/gmt_hash_server.txt