def psconvert(self, **kwargs): r""" Convert [E]PS file(s) to other formats. Converts one or more PostScript files to other formats (BMP, EPS, JPEG, PDF, PNG, PPM, SVG, TIFF) using GhostScript. If no input files are given, will convert the current active figure (see :func:`pygmt.figure`). In this case, an output name must be given using parameter *prefix*. Full option list at :gmt-docs:`psconvert.html` {aliases} Parameters ---------- crop : str or bool Adjust the BoundingBox and HiResBoundingBox to the minimum required by the image content. Append ``u`` to first remove any GMT-produced time-stamps. Default is True. gs_option : str Specify a single, custom option that will be passed on to GhostScript as is. dpi : int Set raster resolution in dpi. Default = 720 for PDF, 300 for others. prefix : str Force the output file name. By default output names are constructed using the input names as base, which are appended with an appropriate extension. Use this option to provide a different name, but without extension. Extension is still determined automatically. icc_gray : bool Enforce gray-shades by using ICC profiles. anti_aliasing : str [**g**\|\ **p**\|\ **t**\][**1**\|\ **2**\|\ **4**]. Set the anti-aliasing options for **g**\ raphics or **t**\ ext. Append the size of the subsample box (1, 2, or 4) [4]. [Default is no anti-aliasing (same as bits = 1)]. fmt : str Sets the output format, where **b** means BMP, **e** means EPS, **E** means EPS with PageSize command, **f** means PDF, **F** means multi-page PDF, **j** means JPEG, **g** means PNG, **G** means transparent PNG (untouched regions are transparent), **m** means PPM, **s** means SVG, and **t** means TIFF [default is JPEG]. To **b**\|\ **j**\|\ **g**\|\ **t**\ , optionally append **+m** in order to get a monochrome (grayscale) image. The EPS format can be combined with any of the other formats. For example, **ef** creates both an EPS and a PDF file. Using **F** creates a multi-page PDF file from the list of input PS or PDF files. It requires the ``prefix`` parameter. """ kwargs = self._preprocess(**kwargs) # Default cropping the figure to True if "A" not in kwargs: kwargs["A"] = "" # allow for spaces in figure name kwargs["F"] = f'"{kwargs.get("F")}"' if kwargs.get("F") else None with Session() as lib: lib.call_module("psconvert", build_arg_string(kwargs))
def legend(self, spec=None, position="JTR+jTR+o0.2c", box="+gwhite+p1p", **kwargs): r""" Plot legends on maps. Makes legends that can be overlaid on maps. Reads specific legend-related information from an input file, or automatically creates legend entries from plotted symbols that have labels. Unless otherwise noted, annotations will be made using the primary annotation font and size in effect (i.e., FONT_ANNOT_PRIMARY). Full option list at :gmt-docs:`legend.html` {aliases} Parameters ---------- spec : None or str Either ``None`` [default] for using the automatically generated legend specification file, or a *filename* pointing to the legend specification file. {J} {R} position : str [**g**\|\ **j**\|\ **J**\|\ **n**\|\ **x**]\ *refpoint*\ **+w**\ *width*\ [/*height*]\ [**+j**\ *justify*]\ [**+l**\ *spacing*]\ [**+o**\ *dx*\ [/*dy*]]. Defines the reference point on the map for the legend. By default, uses **JTR**\ +\ **jTR**\ +\ **o**\ *0.2c* which places the legend at the top-right corner inside the map frame, with a 0.2 cm offset. box : bool or str [**+c**\ *clearances*][**+g**\ *fill*][**+i**\ [[*gap*/]\ *pen*]]\ [**+p**\ [*pen*]][**+r**\ [*radius*]][**+s**\ [[*dx*/*dy*/][*shade*]]]. Without further arguments, draws a rectangular border around the legend using :gmt-term:`MAP_FRAME_PEN`. By default, uses **+g**\ white\ **+p**\ 1p which draws a box around the legend using a 1p black pen and adds a white background. {V} {XY} {c} {p} {t} """ kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access if "D" not in kwargs: kwargs["D"] = position if "F" not in kwargs: kwargs["F"] = box with Session() as lib: if spec is None: specfile = "" elif data_kind(spec) == "file": specfile = spec else: raise GMTInvalidInput("Unrecognized data type: {}".format(type(spec))) arg_str = " ".join([specfile, build_arg_string(kwargs)]) lib.call_module("legend", arg_str)
def grdsample(grid, **kwargs): r""" Change the registration, spacing, or nodes in a grid file. This reads a grid file and interpolates it to create a new grid file. It can change the registration with ``translate`` or ``registration``, change the grid-spacing or number of nodes with ``spacing``, and set a new sub-region using ``region``. A bicubic [Default], bilinear, B-spline or nearest-neighbor interpolation is set with ``interpolation``. When ``region`` is omitted, the output grid will cover the same region as the input grid. When ``spacing`` is omitted, the grid spacing of the output grid will be the same as the input grid. Either ``registration`` or ``translate`` can be used to change the grid registration. When omitted, the output grid will have the same registration as the input grid. {aliases} Parameters ---------- grid : str or xarray.DataArray The file name of the input grid or the grid loaded as a DataArray. outgrid : str or None The name of the output netCDF file with extension .nc to store the grid in. {I} {R} translate : bool Translate between grid and pixel registration; if the input is grid-registered, the output will be pixel-registered and vice-versa. registration : str or bool [**g**\|\ **p**\ ]. Set registration to **g**\ ridline or **p**\ ixel. {V} {f} {n} {x} Returns ------- ret: xarray.DataArray or None Return type depends on whether the ``outgrid`` parameter is set: - :class:`xarray.DataArray` if ``outgrid`` is not set - None if ``outgrid`` is set (grid output will be stored in file set by ``outgrid``) """ with GMTTempFile(suffix=".nc") as tmpfile: with Session() as lib: file_context = lib.virtualfile_from_data(check_kind="raster", data=grid) with file_context as infile: if "G" not in kwargs: # if outgrid is unset, output to tempfile kwargs.update({"G": tmpfile.name}) outgrid = kwargs["G"] arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdsample", arg_str) return load_dataarray(outgrid) if outgrid == tmpfile.name else None
def set_panel(self, panel=None, **kwargs): r""" Set the current subplot panel to plot on. Before you start plotting you must first select the active subplot. Note: If any *projection* option is passed with the question mark **?** as scale or width when plotting subplots, then the dimensions of the map are automatically determined by the subplot size and your region. For Cartesian plots: If you want the scale to apply equally to both dimensions then you must specify ``projection="x"`` [The default ``projection="X"`` will fill the subplot by using unequal scales]. {aliases} Parameters ---------- panel : str or list *row,col*\|\ *index*. Sets the current subplot until further notice. **Note**: First *row* or *col* is 0, not 1. If not given we go to the next subplot by order specified via ``autolabel`` in :meth:`pygmt.Figure.subplot`. As an alternative, you may bypass using :meth:`pygmt.Figure.set_panel` and instead supply the common option **panel**\ =[*row,col*] to the first plot command you issue in that subplot. GMT maintains information about the current figure and subplot. Also, you may give the one-dimensional *index* instead which starts at 0 and follows the row or column order set via ``autolabel`` in :meth:`pygmt.Figure.subplot`. fixedlabel : str Overrides the automatic labeling with the given string. No modifiers are allowed. Placement, justification, etc. are all inherited from how ``autolabel`` was specified by the initial :meth:`pygmt.Figure.subplot` command. clearance : str or list [*side*]\ *clearance*. Reserve a space of dimension *clearance* between the margin and the subplot on the specified side, using *side* values from **w**, **e**, **s**, or **n**. The option is repeatable to set aside space on more than one side (e.g. ``clearance=['w1c', 's2c']`` would set a clearance of 1 cm on west side and 2 cm on south side). Such space will be left untouched by the main map plotting but can be accessed by modules that plot scales, bars, text, etc. This setting overrides the common clearances set by ``clearance`` in the initial :meth:`pygmt.Figure.subplot` call. {V} """ kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access # allow for spaces in string with needing double quotes kwargs["A"] = f'"{kwargs.get("A")}"' if kwargs.get( "A") is not None else None # convert tuple or list to comma-separated str panel = ",".join(map(str, panel)) if is_nonstr_iter(panel) else panel with Session() as lib: arg_str = " ".join(["set", f"{panel}", build_arg_string(kwargs)]) lib.call_module(module="subplot", args=arg_str) yield
def sph2grd(data, **kwargs): r""" Create spherical grid files in tension of data. Reads a spherical harmonics coefficient table with records of L, M, C[L,M], S[L,M] and evaluates the spherical harmonic model on the specified grid. Full option list at :gmt-docs:`sph2grd.html` {aliases} Parameters ---------- data : str or {table-like} Pass in data with L, M, C[L,M], S[L,M] values by providing a file name to an ASCII data table, a 2D {table-classes}. outgrid : str or None The name of the output netCDF file with extension .nc to store the grid in. {I} {R} {V} {b} {h} {i} {r} {x} Returns ------- ret: xarray.DataArray or None Return type depends on whether the ``outgrid`` parameter is set: - :class:`xarray.DataArray` if ``outgrid`` is not set - None if ``outgrid`` is set (grid output will be stored in file set by ``outgrid``) Example ------- >>> import pygmt >>> # Create a new grid from the remote file "EGM96_to_36.txt", >>> # set the grid spacing to 1, and the region to "g" >>> new_grid = pygmt.sph2grd( ... data="@EGM96_to_36.txt", spacing=1, region="g" ... ) """ with GMTTempFile(suffix=".nc") as tmpfile: with Session() as lib: file_context = lib.virtualfile_from_data(check_kind="vector", data=data) with file_context as infile: if (outgrid := kwargs.get("G")) is None: kwargs["G"] = outgrid = tmpfile.name # output to tmpfile lib.call_module(module="sph2grd", args=build_arg_string(kwargs, infile=infile)) return load_dataarray(outgrid) if outgrid == tmpfile.name else None
def _blockm(block_method, data, x, y, z, outfile, **kwargs): r""" 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, 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", "blockmedian" or "blockmode". 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``) """ with GMTTempFile(suffix=".csv") as tmpfile: with Session() as lib: # Choose how data will be passed into the module table_context = lib.virtualfile_from_data(check_kind="vector", data=data, x=x, y=y, z=z, required_z=True) # Run blockm* on data table with table_context as infile: if outfile is None: outfile = tmpfile.name arg_str = " ".join( [infile, build_arg_string(kwargs), "->" + outfile]) lib.call_module(module=block_method, args=arg_str) # Read temporary csv output to a pandas table if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame try: column_names = data.columns.to_list() result = pd.read_csv(tmpfile.name, sep="\t", names=column_names) except AttributeError: # 'str' object has no attribute 'columns' 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 return result
def grdclip(grid, **kwargs): r""" Sets values in a grid that meet certain criteria to a new value. Produce a clipped ``outgrid`` or :class:`xarray.DataArray` version of the input ``grid`` file. The parameters ``above`` and ``below`` allow for a given value to be set for values above or below a set amount, respectively. This allows for extreme values in a grid, such as points below a certain depth when plotting Earth relief, to all be set to the same value. Full option list at :gmt-docs:`grdclip.html` {aliases} Parameters ---------- grid : str or xarray.DataArray The file name of the input grid or the grid loaded as a DataArray. outgrid : str or None The name of the output netCDF file with extension .nc to store the grid in. {R} above : str or list or tuple [*high*, *above*]. Set all data[i] > *high* to *above*. below : str or list or tuple [*low*, *below*]. Set all data[i] < *low* to *below*. between : str or list or tuple [*low*, *high*, *between*]. Set all data[i] >= *low* and <= *high* to *between*. new : str or list or tuple [*old*, *new*]. Set all data[i] == *old* to *new*. This is mostly useful when your data are known to be integer values. {V} """ with GMTTempFile(suffix=".nc") as tmpfile: with Session() as lib: file_context = lib.virtualfile_from_data(check_kind="raster", data=grid) with file_context as infile: if "G" not in kwargs.keys( ): # if outgrid is unset, output to tempfile kwargs.update({"G": tmpfile.name}) outgrid = kwargs["G"] arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdclip", arg_str) if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray with xr.open_dataarray(outgrid) as dataarray: result = dataarray.load() _ = result.gmt # load GMTDataArray accessor information else: result = None # if user sets an outgrid, return None return result
def sphinterpolate(data, **kwargs): r""" Create spherical grid files in tension of data. Reads a table containing *lon, lat, z* columns and performs a Delaunay triangulation to set up a spherical interpolation in tension. Several options may be used to affect the outcome, such as choosing local versus global gradient estimation or optimize the tension selection to satisfy one of four criteria. Full option list at :gmt-docs:`sphinterpolate.html` {aliases} Parameters ---------- data : 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}. outgrid : str or None The name of the output netCDF file with extension .nc to store the grid in. {I} {R} {V} Returns ------- ret: xarray.DataArray or None Return type depends on whether the ``outgrid`` parameter is set: - :class:`xarray.DataArray` if ``outgrid`` is not set - None if ``outgrid`` is set (grid output will be stored in file set by ``outgrid``) Example ------- >>> import pygmt >>> # Load a table of Mars with longitude/latitude/radius columns >>> mars_shape = pygmt.datasets.load_sample_data(name="mars_shape") >>> # Perform Delaunay triangulation on the table data >>> # to produce a grid with a 1 arc-degree spacing >>> grid = pygmt.sphinterpolate(data=mars_shape, spacing=1, region="g") """ with GMTTempFile(suffix=".nc") as tmpfile: with Session() as lib: file_context = lib.virtualfile_from_data(check_kind="vector", data=data) with file_context as infile: if (outgrid := kwargs.get("G")) is None: kwargs["G"] = outgrid = tmpfile.name # output to tmpfile lib.call_module( module="sphinterpolate", args=build_arg_string(kwargs, infile=infile), ) return load_dataarray(outgrid) if outgrid == tmpfile.name else None
def grdfill(grid, **kwargs): r""" Fill blank areas from a grid file. Read a grid that presumably has unfilled holes that the user wants to fill in some fashion. Holes are identified by NaN values but this criteria can be changed. There are several different algorithms that can be used to replace the hole values. Full option list at :gmt-docs:`grdfill.html` {aliases} Parameters ---------- grid : str or xarray.DataArray The file name of the input grid or the grid loaded as a DataArray. outgrid : str or None The name of the output netCDF file with extension .nc to store the grid in. mode : str Specify the hole-filling algorithm to use. Choose from **c** for constant fill and append the constant value, **n** for nearest neighbor (and optionally append a search radius in pixels [default radius is :math:`r^2 = \sqrt{{ X^2 + Y^2 }}`, where (*X,Y*) are the node dimensions of the grid]). {R} Returns ------- ret: xarray.DataArray or None Return type depends on whether the ``outgrid`` parameter is set: - :class:`xarray.DataArray` if ``outgrid`` is not set - None if ``outgrid`` is set (grid output will be stored in file set by ``outgrid``) """ with GMTTempFile(suffix=".nc") as tmpfile: with Session() as lib: file_context = lib.virtualfile_from_data(check_kind="raster", data=grid) with file_context as infile: if "G" not in kwargs.keys( ): # if outgrid is unset, output to tempfile kwargs.update({"G": tmpfile.name}) outgrid = kwargs["G"] arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdfill", arg_str) if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray with xr.open_dataarray(outgrid) as dataarray: result = dataarray.load() _ = result.gmt # load GMTDataArray accessor information else: result = None # if user sets an outgrid, return None return result
def which(fname, **kwargs): r""" Find the full path to specified files. Reports the full paths to the files given through *fname*. We look for the file in (1) the current directory, (2) in $GMT_USERDIR (if defined), (3) in $GMT_DATADIR (if defined), or (4) in $GMT_CACHEDIR (if defined). *fname* can also be a downloadable file (either a full URL, a `@file` special file for downloading from the GMT Site Cache, or `@earth_relief_*` topography grids). In these cases, use option *download* to set the desired behavior. If *download* is not used (or False), the file will not be found. Full option list at :gmt-docs:`gmtwhich.html` {aliases} Parameters ---------- fname : str or list One or more file names of any data type (grids, tables, etc.). download : bool or str [**a**\|\ **c**\|\ **l**\|\ **u**]. If the fname argument is a downloadable file (either a complete URL, an @file for downloading from the GMT data server, or @earth_relief_xxy) we will try to download the file if it is not found in your local data or cache dirs. By default [``download=True`` or ``download="l"``] we download to the current directory. Use **a** to place files in the appropriate folder under the user directory (this is where GMT normally places downloaded files), **c** to place it in the user cache directory, or **u** for the user data directory instead (i.e., ignoring any subdirectory structure). {V} Returns ------- path : str or list The path(s) to the file(s), depending on the options used. Raises ------ FileNotFoundError If the file is not found. """ with GMTTempFile() as tmpfile: with Session() as lib: lib.call_module( module="which", args=build_arg_string(kwargs, infile=fname, outfile=tmpfile.name), ) path = tmpfile.read().strip() if not path: _fname = fname.replace(" ", "', '") raise FileNotFoundError(f"File(s) '{_fname}' not found.") return path.split("\n") if "\n" in path else path
def grdfill(grid, **kwargs): r""" Fill blank areas from a grid file. Read a grid that presumably has unfilled holes that the user wants to fill in some fashion. Holes are identified by NaN values but this criteria can be changed. There are several different algorithms that can be used to replace the hole values. Full option list at :gmt-docs:`grdfill.html` {aliases} Parameters ---------- grid : str or xarray.DataArray The file name of the input grid or the grid loaded as a DataArray. outgrid : str or None The name of the output netCDF file with extension .nc to store the grid in. mode : str Specify the hole-filling algorithm to use. Choose from **c** for constant fill and append the constant value, **n** for nearest neighbor (and optionally append a search radius in pixels [default radius is :math:`r^2 = \sqrt{{ X^2 + Y^2 }}`, where (*X,Y*) are the node dimensions of the grid]), or **s** for bicubic spline (optionally append a *tension* parameter [Default is no tension]). {R} {V} Returns ------- ret: xarray.DataArray or None Return type depends on whether the ``outgrid`` parameter is set: - :class:`xarray.DataArray` if ``outgrid`` is not set - None if ``outgrid`` is set (grid output will be stored in file set by ``outgrid``) """ if kwargs.get("A") is None and kwargs.get("L") is None: raise GMTInvalidInput( "At least parameter 'mode' or 'L' must be specified.") with GMTTempFile(suffix=".nc") as tmpfile: with Session() as lib: file_context = lib.virtualfile_from_data(check_kind="raster", data=grid) with file_context as infile: if (outgrid := kwargs.get("G")) is None: kwargs["G"] = outgrid = tmpfile.name # output to tmpfile lib.call_module(module="grdfill", args=build_arg_string(kwargs, infile=infile)) return load_dataarray(outgrid) if outgrid == tmpfile.name else None
def _blockm(block_method, table, outfile, **kwargs): r""" Block average (x,y,z) data tables by mean or median 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. Parameters ---------- block_method : str Name of the GMT module to call. Must be "blockmean" or "blockmedian". 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``) """ kind = data_kind(table) with GMTTempFile(suffix=".csv") as tmpfile: with Session() as lib: if kind == "matrix": if not hasattr(table, "values"): raise GMTInvalidInput( f"Unrecognized data type: {type(table)}") file_context = lib.virtualfile_from_matrix(table.values) elif kind == "file": if outfile is None: raise GMTInvalidInput("Please pass in a str to 'outfile'") file_context = dummy_context(table) else: raise GMTInvalidInput(f"Unrecognized data type: {type(table)}") with file_context as infile: if outfile is None: outfile = tmpfile.name arg_str = " ".join( [infile, build_arg_string(kwargs), "->" + outfile]) lib.call_module(module=block_method, args=arg_str) # 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=table.columns) elif outfile != tmpfile.name: # return None if outfile set, output in outfile result = None return result
def grdlandmask(**kwargs): r""" Create a grid file with set values for land and water. Read the selected shoreline database and create a grid to specify which nodes in the specified grid are over land or over water. The nodes defined by the selected region and lattice spacing will be set according to one of two criteria: (1) land vs water, or (2) the more detailed (hierarchical) ocean vs land vs lake vs island vs pond. Full option list at :gmt-docs:`grdlandmask.html` {aliases} Parameters ---------- outgrid : str or None The name of the output netCDF file with extension .nc to store the grid in. {I} {R} {r} Returns ------- ret: xarray.DataArray or None Return type depends on whether the ``outgrid`` parameter is set: - :class:`xarray.DataArray` if ``outgrid`` is not set - None if ``outgrid`` is set (grid output will be stored in file set by ``outgrid``) """ if "I" not in kwargs.keys() or "R" not in kwargs.keys(): raise GMTInvalidInput("Both 'region' and 'spacing' must be specified.") with GMTTempFile(suffix=".nc") as tmpfile: with Session() as lib: if "G" not in kwargs.keys( ): # if outgrid is unset, output to tempfile kwargs.update({"G": tmpfile.name}) outgrid = kwargs["G"] arg_str = build_arg_string(kwargs) lib.call_module("grdlandmask", arg_str) if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray with xr.open_dataarray(outgrid) as dataarray: result = dataarray.load() _ = result.gmt # load GMTDataArray accessor information else: result = None # if user sets an outgrid, return None return result
def sph2grd(data, **kwargs): r""" Create spherical grid files in tension of data. Reads a spherical harmonics coefficient table with records of L, M, C[L,M], S[L,M] and evaluates the spherical harmonic model on the specified grid. Full option list at :gmt-docs:`sph2grd.html` {aliases} Parameters ---------- data : str or {table-like} Pass in data with L, M, C[L,M], S[L,M] values by providing a file name to an ASCII data table, a 2D {table-classes}. outgrid : str or None The name of the output netCDF file with extension .nc to store the grid in. {I} {R} {V} {b} {h} {i} {r} {x} Returns ------- ret: xarray.DataArray or None Return type depends on whether the ``outgrid`` parameter is set: - :class:`xarray.DataArray` if ``outgrid`` is not set - None if ``outgrid`` is set (grid output will be stored in file set by ``outgrid``) """ with GMTTempFile(suffix=".nc") as tmpfile: with Session() as lib: file_context = lib.virtualfile_from_data(check_kind="vector", data=data) with file_context as infile: if "G" not in kwargs: # if outgrid is unset, output to tempfile kwargs.update({"G": tmpfile.name}) outgrid = kwargs["G"] arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("sph2grd", arg_str) return load_dataarray(outgrid) if outgrid == tmpfile.name else None
def basemap(self, **kwargs): r""" Plot base maps and frames for the figure. Creates a basic or fancy basemap with axes, fill, and titles. Several map projections are available, and the user may specify separate tick-mark intervals for boundary annotation, ticking, and [optionally] gridlines. A simple map scale or directional rose may also be plotted. At least one of the parameters ``frame``, ``map_scale``, ``rose`` or ``compass`` must be specified. Full option list at :gmt-docs:`basemap.html` {aliases} Parameters ---------- {J} zscale/zsize : float or str Set z-axis scaling or z-axis size. {R} *Required if this is the first plot command.* {B} map_scale : str [**g**\|\ **j**\|\ **J**\|\ **n**\|\ **x**]\ *refpoint*\ **+w**\ *length*. Draws a simple map scale centered on the reference point specified. rose : str Draws a map directional rose on the map at the location defined by the reference and anchor points. compass : str Draws a map magnetic rose on the map at the location defined by the reference and anchor points {U} {V} {XY} {c} {f} {p} {t} """ kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access if not args_in_kwargs(args=["B", "L", "Td", "Tm", "c"], kwargs=kwargs): raise GMTInvalidInput( "At least one of frame, map_scale, compass, rose, or panel must be specified." ) with Session() as lib: lib.call_module("basemap", build_arg_string(kwargs))
def which(fname, **kwargs): """ Find the full path to specified files. Reports the full paths to the files given through *fname*. We look for the file in (1) the current directory, (2) in $GMT_USERDIR (if defined), (3) in $GMT_DATADIR (if defined), or (4) in $GMT_CACHEDIR (if defined). *fname* can also be a downloadable file (either a full URL, a `@file` special file for downloading from the GMT Site Cache, or `@earth_relief_*` topography grids). In these cases, use option *download* to set the desired behavior. If *download* is not used (or False), the file will not be found. Full option list at :gmt-docs:`gmtwhich.html` {aliases} Parameters ---------- fname : str The file name that you want to check. download : bool or str If the file is downloadable and not found, we will try to download the it. Use True or 'l' (default) to download to the current directory. Use 'c' to place in the user cache directory or 'u' user data directory instead. {V} Returns ------- path : str The path of the file, depending on the options used. Raises ------ FileNotFoundError If the file is not found. """ with GMTTempFile() as tmpfile: arg_str = " ".join( [fname, build_arg_string(kwargs), "->" + tmpfile.name]) with Session() as lib: lib.call_module("which", arg_str) path = tmpfile.read().strip() if not path: raise FileNotFoundError("File '{}' not found.".format(fname)) return path
def sphinterpolate(data, **kwargs): r""" Create spherical grid files in tension of data. Reads a table containing *lon, lat, z* columns and performs a Delaunay triangulation to set up a spherical interpolation in tension. Several options may be used to affect the outcome, such as choosing local versus global gradient estimation or optimize the tension selection to satisfy one of four criteria. Full option list at :gmt-docs:`sphinterpolate.html` {aliases} Parameters ---------- data : 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}. outgrid : str or None The name of the output netCDF file with extension .nc to store the grid in. {I} {R} {V} Returns ------- ret: xarray.DataArray or None Return type depends on whether the ``outgrid`` parameter is set: - :class:`xarray.DataArray` if ``outgrid`` is not set - None if ``outgrid`` is set (grid output will be stored in file set by ``outgrid``) """ with GMTTempFile(suffix=".nc") as tmpfile: with Session() as lib: file_context = lib.virtualfile_from_data(check_kind="vector", data=data) with file_context as infile: if "G" not in kwargs: # if outgrid is unset, output to tempfile kwargs.update({"G": tmpfile.name}) outgrid = kwargs["G"] arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("sphinterpolate", arg_str) return load_dataarray(outgrid) if outgrid == tmpfile.name else None
def image(self, imagefile, **kwargs): r""" Place images or EPS files on maps. Reads an Encapsulated PostScript file or a raster image file and plots it on a map. Full option list at :gmt-docs:`image.html` {aliases} Parameters ---------- imagefile : str This must be an Encapsulated PostScript (EPS) file or a raster image. An EPS file must contain an appropriate BoundingBox. A raster file can have a depth of 1, 8, 24, or 32 bits and is read via GDAL. Note: If GDAL was not configured during GMT installation then only EPS files are supported. {J} {R} position : str [**g**\|\ **j**\|\ **J**\|\ **n**\|\ **x**]\ *refpoint*\ **+r**\ *dpi*\ **+w**\ [**-**]\ *width*\ [/*height*]\ [**+j**\ *justify*]\ [**+n**\ *nx*\ [/*ny*] ]\ [**+o**\ *dx*\ [/*dy*]]. Sets reference point on the map for the image. box : bool or str [**+c**\ *clearances*][**+g**\ *fill*][**+i**\ [[*gap*/]\ *pen*]]\ [**+p**\ [*pen*]][**+r**\ [*radius*]][**+s**\ [[*dx*/*dy*/][*shade*]]]. Without further arguments, draws a rectangular border around the image using :gmt-term:`MAP_FRAME_PEN`. monochrome : bool Convert color image to monochrome grayshades using the (television) YIQ-transformation. {U} {V} {XY} {c} {p} {t} """ kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access with Session() as lib: arg_str = " ".join([imagefile, build_arg_string(kwargs)]) lib.call_module("image", arg_str)
def logo(self, **kwargs): r""" Plot the GMT logo. By default, the GMT logo is 2 inches wide and 1 inch high and will be positioned relative to the current plot origin. Use various options to change this and to place a transparent or opaque rectangular map panel behind the GMT logo. Full option list at :gmt-docs:`gmtlogo.html`. {aliases} Parameters ---------- {J} {R} position : str [**g**\|\ **j**\|\ **J**\|\ **n**\|\ **x**]\ *refpoint*\ **+w**\ *width*\ [**+j**\ *justify*]\ [**+o**\ *dx*\ [/*dy*]]. Sets reference point on the map for the image. box : bool or str Without further arguments, draws a rectangular border around the GMT logo. style : str [**l**\|\ **n**\|\ **u**]. Control what is written beneath the map portion of the logo. - **l** to plot the text label "The Generic Mapping Tools" [Default] - **n** to skip the label placement - **u** to place the URL to the GMT site {U} {V} {XY} {c} {t} """ kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access with Session() as lib: lib.call_module("logo", build_arg_string(kwargs))
def histogram(self, table, **kwargs): r""" Plots a histogram, and can read data from a file or list, array, or dataframe. Full option list at :gmt-docs:`histogram.html` {aliases} Parameters ---------- table : str, list, or 1d array A data file name, list, or 1d numpy array. This is a required argument. {J} {R} {B} {CPT} {G} {W} {c} label : str Add a legend entry for the symbol or line being plotted. {p} horizontal : bool Plot the histogram using horizonal bars instead of the default vertical bars. series : int or str or list [*min*\ /*max*\ /]\ *inc*\ [**+n**\ ] Set the interval for the width of each bar in the histogram. """ kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access with Session() as lib: file_context = lib.virtualfile_from_data(check_kind="vector", data=table) with file_context as infile: arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("histogram", arg_str)
def grdinfo(grid, **kwargs): """ Get information about a grid. Can read the grid from a file or given as an xarray.DataArray grid. Full option list at :gmt-docs:`grdinfo.html` Parameters ---------- grid : str or xarray.DataArray The file name of the input grid or the grid loaded as a DataArray. {V} Returns ------- info : str A string with information about the grid. """ kind = data_kind(grid, None, None) with GMTTempFile() as outfile: with Session() as lib: if kind == "file": file_context = dummy_context(grid) elif kind == "grid": file_context = lib.virtualfile_from_grid(grid) else: raise GMTInvalidInput("Unrecognized data type: {}".format( type(grid))) with file_context as infile: arg_str = " ".join( [infile, build_arg_string(kwargs), "->" + outfile.name]) lib.call_module("grdinfo", arg_str) result = outfile.read() return result
def info(table, **kwargs): r""" Get information about data tables. Reads from files and finds the extreme values in each of the columns reported as min/max pairs. It recognizes NaNs and will print warnings if the number of columns vary from record to record. As an option, it will find the extent of the first two columns rounded up and down to the nearest multiple of the supplied increments given by ``spacing``. Such output will be in a numpy.ndarray form [*w*, *e*, *s*, *n*], which can be used directly as the ``region`` parameter for other modules (hence only *dx* and *dy* are needed). If the ``per_column`` parameter is combined with ``spacing``, then the numpy.ndarray output will be rounded up/down for as many columns as there are increments provided in ``spacing``. A similar parameter ``nearest_multiple`` will provide a numpy.ndarray in the form of [*zmin*, *zmax*, *dz*] for makecpt. Full option list at :gmt-docs:`gmtinfo.html` {aliases} Parameters ---------- table : str or np.ndarray or pandas.DataFrame or xarray.Dataset Pass in either a file name to an ASCII data table, a 1D/2D numpy array, a pandas dataframe, or an xarray dataset made up of 1D xarray.DataArray data variables. per_column : bool Report the min/max values per column in separate columns. spacing : str [**b**\|\ **p**\|\ **f**\|\ **s**]\ *dx*\[/*dy*\[/*dz*...]]. Compute the min/max values of the first n columns to the nearest multiple of the provided increments [default is 2 columns]. By default, output results in the form ``[w, e, s, n]``, unless ``per_column`` is set in which case we output each min and max value in separate output columns. nearest_multiple : str **dz**\[\ **+c**\ *col*]. Report the min/max of the first (0'th) column to the nearest multiple of dz and output this in the form ``[zmin, zmax, dz]``. {V} {a} {f} {r} Returns ------- output : np.ndarray or str Return type depends on whether any of the ``per_column``, ``spacing``, or ``nearest_multiple`` parameters are set. - :class:`numpy.ndarray` if either of the above parameters are used. - str if none of the above parameters are used. """ with Session() as lib: file_context = lib.virtualfile_from_data(data=table) with GMTTempFile() as tmpfile: with file_context as fname: arg_str = " ".join( [fname, build_arg_string(kwargs), "->" + tmpfile.name]) lib.call_module("info", arg_str) result = tmpfile.read() if any(arg in kwargs for arg in ["C", "I", "T"]): # Converts certain output types into a numpy array # instead of a raw string that is less useful. if result.startswith(("-R", "-T")): # e.g. -R0/1/2/3 or -T0/9/1 result = result[2:].replace("/", " ") try: result = np.loadtxt(result.splitlines()) except ValueError: # Load non-numerical outputs in str type, e.g. for datetime result = np.loadtxt(result.splitlines(), dtype="str") return result
def surface(x=None, y=None, z=None, data=None, **kwargs): r""" Grids table data using adjustable tension continuous curvature splines. Surface reads randomly-spaced (x,y,z) triples and produces gridded values z(x,y) by solving: .. math:: (1 - t)\nabla^2(z)+t\nabla(z) = 0 where :math:`t` is a tension factor between 0 and 1, and :math:`\nabla` indicates the Laplacian operator. Takes a matrix, xyz triples, or a file name as input. Must provide either ``data`` or ``x``, ``y``, and ``z``. Full option list at :gmt-docs:`surface.html` {aliases} Parameters ---------- x/y/z : 1d arrays Arrays of x and y coordinates and values z of the data points. data : str or 2d array Either a data file name or a 2d numpy array with the tabular data. spacing : str *xinc*\[\ *unit*\][**+e**\|\ **n**]\ [/*yinc*\ [*unit*][**+e**\|\ **n**]]. *xinc* [and optionally *yinc*] is the grid spacing. region : str or list *xmin/xmax/ymin/ymax*\[**+r**][**+u**\ *unit*]. Specify the region of interest. outfile : str Optional. The file name for the output netcdf file with extension .nc to store the grid in. {V} {a} {f} {r} Returns ------- ret: xarray.DataArray or None Return type depends on whether the ``outfile`` parameter is set: - :class:`xarray.DataArray`: if ``outfile`` is not set - None if ``outfile`` is set (grid output will be stored in file set by ``outfile``) """ kind = data_kind(data, x, y, z) if kind == "vectors" and z is None: raise GMTInvalidInput("Must provide z with x and y.") with GMTTempFile(suffix=".nc") as tmpfile: with Session() as lib: if kind == "file": file_context = dummy_context(data) elif kind == "matrix": file_context = lib.virtualfile_from_matrix(data) elif kind == "vectors": file_context = lib.virtualfile_from_vectors(x, y, z) else: raise GMTInvalidInput("Unrecognized data type: {}".format( type(data))) with file_context as infile: if "G" not in kwargs.keys( ): # if outfile is unset, output to tmpfile kwargs.update({"G": tmpfile.name}) outfile = kwargs["G"] arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module(module="surface", args=arg_str) if outfile == tmpfile.name: # if user did not set outfile, return DataArray with xr.open_dataarray(outfile) as dataarray: result = dataarray.load() _ = result.gmt # load GMTDataArray accessor information elif outfile != tmpfile.name: # if user sets an outfile, return None result = None return result
def grdtrack(points, grid, newcolname=None, outfile=None, **kwargs): """ Sample grids at specified (x,y) locations. Grdtrack reads one or more grid files and a table with (x,y) [or (lon,lat)] positions in the first two columns (more columns may be present). It interpolates the grid(s) at the positions in the table and writes out the table with the interpolated values added as (one or more) new columns. A bicubic [Default], bilinear, B-spline or nearest-neighbor interpolation is used, requiring boundary conditions at the limits of the region (see *interpolation*; Default uses “natural” conditions (second partial derivative normal to edge is zero) unless the grid is automatically recognized as periodic.) Full option list at :gmt-docs:`grdtrack.html` {aliases} Parameters ---------- points : pandas.DataFrame or str Either a table with (x, y) or (lon, lat) values in the first two columns, or a filename (e.g. csv, txt format). More columns may be present. grid : xarray.DataArray or str Gridded array from which to sample values from, or a filename (netcdf format). newcolname : str Required if 'points' is a pandas.DataFrame. The name for the new column in the track pandas.DataFrame table where the sampled values will be placed. outfile : str Required if 'points' is a file. The file name for the output ASCII file. {V} {n} Returns ------- track: pandas.DataFrame or None Return type depends on whether the outfile parameter is set: - pandas.DataFrame table with (x, y, ..., newcolname) if outfile is not set - None if outfile is set (track output will be stored in outfile) """ with GMTTempFile(suffix=".csv") as tmpfile: with Session() as lib: # Store the pandas.DataFrame points table in virtualfile if data_kind(points) == "matrix": if newcolname is None: raise GMTInvalidInput( "Please pass in a str to 'newcolname'") table_context = lib.virtualfile_from_matrix(points.values) elif data_kind(points) == "file": if outfile is None: raise GMTInvalidInput("Please pass in a str to 'outfile'") table_context = dummy_context(points) else: raise GMTInvalidInput(f"Unrecognized data type {type(points)}") # Store the xarray.DataArray grid in virtualfile if data_kind(grid) == "grid": grid_context = lib.virtualfile_from_grid(grid) elif data_kind(grid) == "file": grid_context = dummy_context(grid) else: raise GMTInvalidInput(f"Unrecognized data type {type(grid)}") # Run grdtrack on the temporary (csv) points table # and (netcdf) grid virtualfile with table_context as csvfile: with grid_context as grdfile: kwargs.update({"G": grdfile}) if outfile is None: # Output to tmpfile if outfile is not set outfile = tmpfile.name arg_str = " ".join( [csvfile, build_arg_string(kwargs), "->" + outfile]) lib.call_module(module="grdtrack", args=arg_str) # Read temporary csv output to a pandas table if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame column_names = points.columns.to_list() + [newcolname] result = pd.read_csv(tmpfile.name, sep="\t", names=column_names) elif outfile != tmpfile.name: # return None if outfile set, output in outfile result = None return result
def grdtrack(points, grid, newcolname=None, outfile=None, **kwargs): r""" Sample grids at specified (x,y) locations. Reads one or more grid files and a table (from file or an array input; but see ``profile`` for exception) with (x,y) [or (lon,lat)] positions in the first two columns (more columns may be present). It interpolates the grid(s) at the positions in the table and writes out the table with the interpolated values added as (one or more) new columns. Alternatively (``crossprofile``), the input is considered to be line-segments and we create orthogonal cross-profiles at each data point or with an equidistant separation and sample the grid(s) along these profiles. A bicubic [Default], bilinear, B-spline or nearest-neighbor interpolation is used, requiring boundary conditions at the limits of the region (see ``interpolation``; Default uses "natural" conditions (second partial derivative normal to edge is zero) unless the grid is automatically recognized as periodic.) Full option list at :gmt-docs:`grdtrack.html` {aliases} Parameters ---------- points : str or {table-like} Pass in either a file name to an ASCII data table, a 2D {table-classes}. grid : xarray.DataArray or str Gridded array from which to sample values from, or a filename (netcdf format). newcolname : str Required if ``points`` is a :class:`pandas.DataFrame`. The name for the new column in the track :class:`pandas.DataFrame` table where the sampled values will be placed. outfile : str The file name for the output ASCII file. resample : str **f**\|\ **p**\|\ **m**\|\ **r**\|\ **R**\ [**+l**] For track resampling (if ``crossprofile`` or ``profile`` are set) we can select how this is to be performed. Append **f** to keep original points, but add intermediate points if needed [Default], **m** as **f**, but first follow meridian (along y) then parallel (along x), **p** as **f**, but first follow parallel (along y) then meridian (along x), **r** to resample at equidistant locations; input points are not necessarily included in the output, and **R** as **r**, but adjust given spacing to fit the track length exactly. Finally, append **+l** if geographic distances should be measured along rhumb lines (loxodromes) instead of great circles. Ignored unless ``crossprofile`` is used. crossprofile : str *length*/\ *ds*\ [*/spacing*][**+a**\|\ **+v**][**l**\|\ **r**]. Use input line segments to create an equidistant and (optionally) equally-spaced set of crossing profiles along which we sample the grid(s) [Default simply samples the grid(s) at the input locations]. Specify two length scales that control how the sampling is done: *length* sets the full length of each cross-profile, while *ds* is the sampling spacing along each cross-profile. Optionally, append **/**\ *spacing* for an equidistant spacing between cross-profiles [Default erects cross-profiles at the input coordinates]; see ``resample`` for how resampling the input track is controlled. By default, all cross-profiles have the same direction (left to right as we look in the direction of the input line segment). Append **+a** to alternate the direction of cross-profiles, or **v** to enforce either a "west-to-east" or "south-to-north" view. By default the entire profiles are output. Choose to only output the left or right halves of the profiles by appending **+l** or **+r**, respectively. Append suitable units to *length*; it sets the unit used for *ds* [and *spacing*] (See :gmt-docs:`Units <grdtrack.html#units>`). The default unit for geographic grids is meter while Cartesian grids implies the user unit. The output columns will be *lon*, *lat*, *dist*, *azimuth*, *z1*, *z2*, ..., *zn* (The *zi* are the sampled values for each of the *n* grids). dfile : str In concert with ``crossprofile`` we can save the (possibly resampled) original lines to *dfile* [Default only saves the cross-profiles]. The columns will be *lon*, *lat*, *dist*, *azimuth*, *z1*, *z2*, ... (sampled value for each grid). profile : str *line*\ [,\ *line*,...][**+a**\ *az*][**+c**][**+d**][**+g**]\ [**+i**\ *inc*][**+l**\ *length*][**+n**\ *np*][**+o**\ *az*]\ [**+r**\ *radius*]. Instead of reading input track coordinates, specify profiles via coordinates and modifiers. The format of each *line* is *start*/*stop*, where *start* or *stop* are either *lon*/*lat* (*x*/*y* for Cartesian data) or a 2-character XY key that uses the :gmt-docs:`text <text.html>`-style justification format to specify a point on the map as [LCR][BMT]. Each line will be a separate segment unless **+c** is used which will connect segments with shared joints into a single segment. In addition to line coordinates, you can use Z-, Z+ to mean the global minimum and maximum locations in the grid (only available if a single grid is given via **outfile**). You may append **+i**\ *inc* to set the sampling interval; if not given then we default to half the minimum grid interval. For a *line* along parallels or meridians you can add **+g** to report degrees of longitude or latitude instead of great circle distances starting at zero. Instead of two coordinates you can specify an origin and one of **+a**, **+o**, or **+r**. The **+a** sets the azimuth of a profile of given length starting at the given origin, while **+o** centers the profile on the origin; both require **+l**. For circular sampling specify **+r** to define a circle of given radius centered on the origin; this option requires either **+n** or **+i**. The **+n**\ *np* modifier sets the desired number of points, while **+l**\ *length* gives the total length of the profile. Append **+d** to output the along-track distances after the coordinates. **Note**: No track file will be read. Also note that only one distance unit can be chosen. Giving different units will result in an error. If no units are specified we default to great circle distances in km (if geographic). If working with geographic data you can use ``distcalc`` to control distance calculation mode [Default is Great Circle]. **Note**: If ``crossprofile`` is set and *spacing* is given then that sampling scheme overrules any modifier set in ``profile``. critical : str [**+b**][**+n**][**+r**][**+z**\ *z0*]. Find critical points along each cross-profile as a function of along-track distance. Requires ``crossprofile`` and a single input grid (*z*). We examine each cross-profile generated and report (*dist*, *lonc*, *latc*, *distc*, *azimuthc*, *zc*) at the center peak of maximum *z* value, (*lonl*, *latl*, *distl*) and (*lonr*, *latr*, *distr*) at the first and last non-NaN point whose *z*-value exceeds *z0*, respectively, and the *width* based on the two extreme points found. Here, *dist* is the distance along the original input ``points`` and the other 12 output columns are a function of that distance. When searching for the center peak and the extreme first and last values that exceed the threshold we assume the profile is positive up. If we instead are looking for a trough then you must use **+n** to temporarily flip the profile to positive. The threshold *z0* value is always given as >= 0; use **+z** to change it [Default is 0]. Alternatively, use **+b** to determine the balance point and standard deviation of the profile; this is the weighted mean and weighted standard deviation of the distances, with *z* acting as the weight. Finally, use **+r** to obtain the weighted rms about the cross-track center (*distc* == 0). **Note**: We round the exact results to the nearest distance nodes along the cross-profiles. We write 13 output columns per track: *dist, lonc, latc, distc, azimuthc, zc, lonl, latl, distl, lonr, latr, distr, width*. {R} no_skip : bool Do *not* skip points that fall outside the domain of the grid(s) [Default only output points within grid domain]. stack : str or list *method*/*modifiers*. In conjunction with ``crossprofile``, compute a single stacked profile from all profiles across each segment. Choose how stacking should be computed [Default method is **a**]: - **a** = mean (average) - **m** = median - **p** = mode (maximum likelihood) - **l** = lower - **L** = lower but only consider positive values - **u** = upper - **U** = upper but only consider negative values. The *modifiers* control the output; choose one or more among these choices: - **+a** : Append stacked values to all cross-profiles. - **+d** : Append stack deviations to all cross-profiles. - **+r** : Append data residuals (data - stack) to all cross-profiles. - **+s**\ [*file*] : Save stacked profile to *file* [Default filename is grdtrack_stacked_profile.txt]. - **+c**\ *fact* : Compute envelope on stacked profile as ±\ *fact* \*\ *deviation* [Default fact value is 2]. Notes: 1. Deviations depend on *method* and are st.dev (**a**), L1 scale, i.e., 1.4826 \* median absolute deviation (MAD) (for **m** and **p**), or half-range (upper-lower)/2. 2. The stacked profile file contains a leading column plus groups of 4-6 columns, with one group for each sampled grid. The leading column holds cross distance, while the first four columns in a group hold stacked value, deviation, min value, and max value, respectively. If *method* is one of **a**\|\ **m**\|\ **p** then we also write the lower and upper confidence bounds (see **+c**). When one or more of **+a**, **+d**, and **+r** are used then we also append the stacking results to the end of each row, for all cross-profiles. The order is always stacked value (**+a**), followed by deviations (**+d**) and finally residuals (**+r**). When more than one grid is sampled this sequence of 1-3 columns is repeated for each grid. radius : bool or int or float or str [*radius*][**+e**\|\ **p**]. To be used with normal grid sampling, and limited to a single, non-IMG grid. If the nearest node to the input point is NaN, search outwards until we find the nearest non-NaN node and report that value instead. Optionally specify a search radius which limits the consideration to points within this distance from the input point. To report the location of the nearest node and its distance from the input point, append **+e**. The default unit for geographic grid distances is spherical degrees. Use *radius* to change the unit and give *radius* = 0 if you do not want to limit the radius search. To instead replace the input point with the coordinates of the nearest node, append **+p**. {V} z_only : bool Only write out the sampled z-values [Default writes all columns]. {a} {b} {d} {e} {f} {g} {h} {i} {j} {n} {o} {s} {w} Returns ------- track: pandas.DataFrame or None Return type depends on whether the ``outfile`` parameter is set: - :class:`pandas.DataFrame` table with (x, y, ..., newcolname) if ``outfile`` is not set - None if ``outfile`` is set (track output will be stored in file set by ``outfile``) Example ------- >>> import pygmt >>> # Load a grid of @earth_relief_30m data, with an x-range of -118 to >>> # -107, and a y-range of -49 to -42 >>> grid = pygmt.datasets.load_earth_relief( ... resolution="30m", region=[-118, -107, -49, -42] ... ) >>> # Load a pandas dataframe with ocean ridge points >>> points = pygmt.datasets.load_sample_data(name="ocean_ridge_points") >>> # Create a pandas dataframe from an input grid and set of points >>> # The output dataframe adds a column named "bathymetry" >>> output_dataframe = pygmt.grdtrack( ... points=points, grid=grid, newcolname="bathymetry" ... ) """ if hasattr(points, "columns") and newcolname is None: raise GMTInvalidInput("Please pass in a str to 'newcolname'") with GMTTempFile(suffix=".csv") as tmpfile: with Session() as lib: # Choose how data will be passed into the module table_context = lib.virtualfile_from_data(check_kind="vector", data=points) # Store the xarray.DataArray grid in virtualfile grid_context = lib.virtualfile_from_data(check_kind="raster", data=grid) # Run grdtrack on the temporary (csv) points table # and (netcdf) grid virtualfile with table_context as csvfile: with grid_context as grdfile: kwargs.update({"G": grdfile}) if outfile is None: # Output to tmpfile if outfile is not set outfile = tmpfile.name lib.call_module( module="grdtrack", args=build_arg_string(kwargs, infile=csvfile, outfile=outfile), ) # Read temporary csv output to a pandas table if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame try: column_names = points.columns.to_list() + [newcolname] result = pd.read_csv(tmpfile.name, sep="\t", names=column_names) except AttributeError: # 'str' object has no attribute 'columns' 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 return result
def grdfilter(grid, **kwargs): r""" Filter a grid in the space (or time) domain. Filter a grid file in the time domain using one of the selected convolution or non-convolution isotropic or rectangular filters and compute distances using Cartesian or Spherical geometries. The output grid file can optionally be generated as a sub-region of the input (via ``region``) and/or with new increment (via ``spacing``) or registration (via ``toggle``). In this way, one may have "extra space" in the input data so that the edges will not be used and the output can be within one half-width of the input edges. If the filter is low-pass, then the output may be less frequently sampled than the input. Full option list at :gmt-docs:`grdfilter.html` {aliases} Parameters ---------- grid : str or xarray.DataArray The file name of the input grid or the grid loaded as a DataArray. outgrid : str or None The name of the output netCDF file with extension .nc to store the grid in. filter : str **b**\|\ **c**\|\ **g**\|\ **o**\|\ **m**\|\ **p**\|\ **h**\ *xwidth*\ [/*width2*\][*modifiers*]. Name of filter type you which to apply, followed by the width: b: Box Car c: Cosine Arch g: Gaussian o: Operator m: Median p: Maximum Likelihood probability h: histogram distance : str Distance *flag* tells how grid (x,y) relates to filter width as follows: p: grid (px,py) with *width* an odd number of pixels; Cartesian distances. 0: grid (x,y) same units as *width*, Cartesian distances. 1: grid (x,y) in degrees, *width* in kilometers, Cartesian distances. 2: grid (x,y) in degrees, *width* in km, dx scaled by cos(middle y), Cartesian distances. The above options are fastest because they allow weight matrix to be computed only once. The next three options are slower because they recompute weights for each latitude. 3: grid (x,y) in degrees, *width* in km, dx scaled by cosine(y), Cartesian distance calculation. 4: grid (x,y) in degrees, *width* in km, Spherical distance calculation. 5: grid (x,y) in Mercator ``projection='m1'`` img units, *width* in km, Spherical distance calculation. spacing : str *xinc*\[\ *unit*\][**+e**\|\ **n**] [/*yinc*\ [*unit*][**+e**\|\ **n**]]. *xinc* [and optionally *yinc*] is the grid spacing. nans : str or float **i**\|\ **p**\|\ **r**. Determine how NaN-values in the input grid affects the filtered output. {R} toggle : bool Toggle the node registration for the output grid so as to become the opposite of the input grid. [Default gives the same registration as the input grid]. {V} Returns ------- ret: xarray.DataArray or None Return type depends on whether the ``outgrid`` parameter is set: - :class:`xarray.DataArray` if ``outgrid`` is not set - None if ``outgrid`` is set (grid output will be stored in file set by ``outgrid``) Examples -------- >>> import os >>> import pygmt >>> # Apply a filter of 600km (full width) to the @earth_relief_30m file >>> # and return a filtered field (saved as netcdf) >>> pygmt.grdfilter( ... grid="@earth_relief_30m", ... filter="m600", ... distance="4", ... region=[150, 250, 10, 40], ... spacing=0.5, ... outgrid="filtered_pacific.nc", ... ) >>> os.remove("filtered_pacific.nc") # cleanup file >>> # Apply a gaussian smoothing filter of 600 km in the input data array, >>> # and returns a filtered data array with the smoothed field. >>> grid = pygmt.datasets.load_earth_relief() >>> smooth_field = pygmt.grdfilter(grid=grid, filter="g600", distance="4") """ kind = data_kind(grid) with GMTTempFile(suffix=".nc") as tmpfile: with Session() as lib: if kind == "file": file_context = dummy_context(grid) elif kind == "grid": file_context = lib.virtualfile_from_grid(grid) else: raise GMTInvalidInput("Unrecognized data type: {}".format( type(grid))) with file_context as infile: if "G" not in kwargs.keys( ): # if outgrid is unset, output to tempfile kwargs.update({"G": tmpfile.name}) outgrid = kwargs["G"] arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdfilter", arg_str) if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray with xr.open_dataarray(outgrid) as dataarray: result = dataarray.load() _ = result.gmt # load GMTDataArray accessor information else: result = None # if user sets an outgrid, return None return result
def grdview(self, grid, **kwargs): r""" Create 3-D perspective image or surface mesh from a grid. Reads a 2-D grid file and produces a 3-D perspective plot by drawing a mesh, painting a colored/gray-shaded surface made up of polygons, or by scanline conversion of these polygons to a raster image. Options include draping a data set on top of a surface, plotting of contours on top of the surface, and apply artificial illumination based on intensities provided in a separate grid file. Full option list at :gmt-docs:`grdview.html` {aliases} Parameters ---------- grid : str or xarray.DataArray The file name of the input relief grid or the grid loaded as a DataArray. region : str or list *xmin/xmax/ymin/ymax*\ [**+r**][**+u**\ *unit*]. Specify the :doc:`region </tutorials/basics/regions>` of interest. When used with ``perspective``, optionally append */zmin/zmax* to indicate the range to use for the 3-D axes [Default is the region in the input grid]. {J} zscale/zsize : float or str Set z-axis scaling or z-axis size. {B} cmap : str The name of the color palette table to use. drapegrid : str or xarray.DataArray The file name or a DataArray of the image grid to be draped on top of the relief provided by grid. [Default determines colors from grid]. Note that ``zscale`` and ``plane`` always refers to the grid. The drapegrid only provides the information pertaining to colors, which (if drapegrid is a grid) will be looked-up via the CPT (see ``cmap``). plane : float or str *level*\ [**+g**\ *fill*]. Draws a plane at this z-level. If the optional color is provided via the **+g** modifier, and the projection is not oblique, the frontal facade between the plane and the data perimeter is colored. surftype : str Specifies cover type of the grid. Select one of following settings: - **m** - mesh plot [Default]. - **mx** or **my** - waterfall plots (row or column profiles). - **s** - surface plot, and optionally append **m** to have mesh lines drawn on top of the surface. - **i** - image plot. - **c** - Same as **i** but will make nodes with z = NaN transparent. For any of these choices, you may force a monochrome image by appending the modifier **+m**. contourpen : str Draw contour lines on top of surface or mesh (not image). Append pen attributes used for the contours. meshpen : str Sets the pen attributes used for the mesh. You must also select ``surftype`` of **m** or **sm** for meshlines to be drawn. facadepen :str Sets the pen attributes used for the facade. You must also select ``plane`` for the facade outline to be drawn. shading : str Provide the name of a grid file with intensities in the (-1,+1) range, or a constant intensity to apply everywhere (affects the ambient light). Alternatively, derive an intensity grid from the input data grid reliefgrid via a call to ``grdgradient``; append **+a**\ *azimuth*, **+n**\ *args*, and **+m**\ *ambient* to specify azimuth, intensity, and ambient arguments for that method, or just give **+d** to select the default arguments [Default is **+a**\ -45\ **+nt**\ 1\ **+m**\ 0]. {V} {XY} {c} {f} {n} {p} {t} """ kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access with Session() as lib: file_context = lib.virtualfile_from_data(check_kind="raster", data=grid) with contextlib.ExitStack() as stack: if kwargs.get("G") is not None: # deal with kwargs["G"] if drapegrid is xr.DataArray drapegrid = kwargs["G"] if data_kind(drapegrid) in ("file", "grid"): if data_kind(drapegrid) == "grid": drape_context = lib.virtualfile_from_grid(drapegrid) kwargs["G"] = stack.enter_context(drape_context) else: raise GMTInvalidInput( f"Unrecognized data type for drapegrid: {type(drapegrid)}" ) fname = stack.enter_context(file_context) lib.call_module(module="grdview", args=build_arg_string(kwargs, infile=fname))
def blockmedian(table, outfile=None, **kwargs): r""" Block average (x,y,z) data tables by median 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 median position and value for every non-empty block in a grid region defined by the region and spacing arguments. Full option list at :gmt-docs:`blockmedian.html` {aliases} Parameters ---------- table : pandas.DataFrame or str Either a pandas dataframe with (x, y, z) or (longitude, latitude, elevation) values in the first three columns, or a file name to an ASCII data table. spacing : str *xinc*\[\ *unit*\][**+e**\|\ **n**] [/*yinc*\ [*unit*][**+e**\|\ **n**]]. *xinc* [and optionally *yinc*] is the grid spacing. region : str or list *xmin/xmax/ymin/ymax*\[\ **+r**\][**+u**\ *unit*]. Specify the region of interest. outfile : str Required if ``table`` is a file. The file name for the output ASCII file. {V} 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``) """ kind = data_kind(table) with GMTTempFile(suffix=".csv") as tmpfile: with Session() as lib: if kind == "matrix": if not hasattr(table, "values"): raise GMTInvalidInput( f"Unrecognized data type: {type(table)}") file_context = lib.virtualfile_from_matrix(table.values) elif kind == "file": if outfile is None: raise GMTInvalidInput("Please pass in a str to 'outfile'") file_context = dummy_context(table) else: raise GMTInvalidInput(f"Unrecognized data type: {type(table)}") with file_context as infile: if outfile is None: outfile = tmpfile.name arg_str = " ".join( [infile, build_arg_string(kwargs), "->" + outfile]) lib.call_module(module="blockmedian", args=arg_str) # 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=table.columns) elif outfile != tmpfile.name: # return None if outfile set, output in outfile result = None return result
def x2sys_init(tag, **kwargs): r""" Initialize a new x2sys track database. Serves as the starting point for x2sys and initializes a set of data bases that are particular to one kind of track data. These data, their associated data bases, and key parameters are given a short-hand notation called an x2sys TAG. The TAG keeps track of settings such as file format, whether the data are geographic or not, and the binning resolution for track indices. Before you can run :meth:`pygmt.x2sys_init` you must set the environmental parameter X2SYS_HOME to a directory where you have write permission, which is where x2sys can keep track of your settings. Full option list at :gmt-docs:`supplements/x2sys/x2sys_init.html` {aliases} Parameters ---------- tag : str The unique name of this data type x2sys TAG. fmtfile : str Format definition file prefix for this data set (see :gmt-docs:`GMT's Format Definition Files <supplements/x2sys/x2sys_init.html#format-definition-files>` for more information). Specify full path if the file is not in the current directory. Some file formats already have definition files premade. These include: - **mgd77** (for plain ASCII MGD77 data files) - **mgd77+** (for enhanced MGD77+ netCDF files) - **gmt** (for old mgg supplement binary files) - **xy** (for plain ASCII x, y tables) - **xyz** (same, with one z-column) - **geo** (for plain ASCII longitude, latitude files) - **geoz** (same, with one z-column). suffix : str Specifies the file extension (suffix) for these data files. If not given we use the format definition file prefix as the suffix (see ``fmtfile``). discontinuity : str **d**\|\ **g**. Selects geographical coordinates. Append **d** for discontinuity at the Dateline (makes longitude go from -180 to +180) or **g** for discontinuity at Greenwich (makes longitude go from 0 to 360 [Default]). If not given we assume the data are Cartesian. spacing : str or list *dx*\[/*dy*]. *dx* and optionally *dy* is the grid spacing. Append **m** to indicate minutes or **s** to indicate seconds for geographic data. These spacings refer to the binning used in the track bin-index data base. units : str or list **d**\|\ **s**\ *unit*. Sets the units used for distance and speed when requested by other programs. Append **d** for distance or **s** for speed, then give the desired *unit* as: - **c** - Cartesian userdist or userdist/usertime - **e** - meters or m/s - **f** - feet or feet/s - **k** - km or km/hr - **m** - miles or miles/hr - **n** - nautical miles or knots - **u** - survey feet or survey feet/s [Default is ``units=["dk", "se"]`` (km and m/s) if ``discontinuity`` is set, and ``units=["dc", "sc"]`` otherwise (e.g., for Cartesian units)]. {R} {V} gap : str or list **t**\|\ **d**\ *gap*. Give **t** or **d** and append the corresponding maximum time gap (in user units; this is typically seconds [Default is infinity]), or distance (for units, see ``units``) gap [Default is infinity]) allowed between the two data points immediately on either side of a crossover. If these limits are exceeded then a data gap is assumed and no COE will be determined. {j} """ with Session() as lib: arg_str = " ".join([tag, build_arg_string(kwargs)]) lib.call_module(module="x2sys_init", args=arg_str)
def plot3d(self, data=None, x=None, y=None, z=None, size=None, direction=None, **kwargs): r""" Plot lines, polygons, and symbols in 3-D. Takes a matrix, (x,y,z) triplets, or a file name as input and plots lines, polygons, or symbols at those locations in 3-D. Must provide either ``data`` or ``x``/``y``/``z``. If providing data through ``x/y/z``, ``color`` can be a 1d array that will be mapped to a colormap. If a symbol is selected and no symbol size given, then plot3d will interpret the fourth column of the input data as symbol size. Symbols whose size is <= 0 are skipped. If no symbols are specified then the symbol code (see ``style`` below) must be present as last column in the input. If ``style`` is not used, a line connecting the data points will be drawn instead. To explicitly close polygons, use ``close``. Select a fill with ``color``. If ``color`` is set, ``pen`` will control whether the polygon outline is drawn or not. If a symbol is selected, ``color`` and ``pen`` determines the fill and outline/no outline, respectively. Full option list at :gmt-docs:`plot3d.html` {aliases} Parameters ---------- data : str or {table-like} Either a data file name, a 2d {table-classes}. Optionally, use parameter ``incols`` to specify which columns are x, y, z, color, and size, respectively. x/y/z : float or 1d arrays The x, y, and z coordinates, or arrays of x, y and z coordinates of the data points size : 1d array The size of the data points in units specified in ``style``. Only valid if using ``x``/``y``/``z``. direction : list of two 1d arrays If plotting vectors (using ``style='V'`` or ``style='v'``), then should be a list of two 1d arrays with the vector directions. These can be angle and length, azimuth and length, or x and y components, depending on the style options chosen. {J} zscale/zsize : float or str Set z-axis scaling or z-axis size. {R} straight_line : bool or str [**m**\|\ **p**\|\ **x**\|\ **y**]. By default, geographic line segments are drawn as great circle arcs. To draw them as straight lines, use ``straight_line``. Alternatively, add **m** to draw the line by first following a meridian, then a parallel. Or append **p** to start following a parallel, then a meridian. (This can be practical to draw a line along parallels, for example). For Cartesian data, points are simply connected, unless you append **x** or **y** to draw stair-case curves that whose first move is along *x* or *y*, respectively. **Note**: The ``straight_line`` parameter requires constant *z*-coordinates. {B} {CPT} offset : str *dx*/*dy*\ [/*dz*]. Offset the plot symbol or line locations by the given amounts *dx*/*dy*\ [/*dz*] [Default is no offset]. {G} *color* can be a 1d array, but it is only valid if using ``x``/``y`` and ``cmap=True`` is also required. intensity : float or bool or 1d array Provide an *intensity* value (nominally in the -1 to +1 range) to modulate the fill color by simulating illumination. If using ``intensity=True``, we will instead read *intensity* from the first data column after the symbol parameters (if given). *intensity* can also be a 1d array to set varying intensity for symbols, but it is only valid for ``x``/``y``/``z``. close : str [**+b**\|\ **d**\|\ **D**][**+xl**\|\ **r**\|\ *x0*]\ [**+yl**\|\ **r**\|\ *y0*][**+p**\ *pen*]. Force closed polygons. Full documentation is at :gmt-docs:`plot3d.html#l`. no_clip : bool or str [**c**\|\ **r**]. Do NOT clip symbols that fall outside map border [Default plots points whose coordinates are strictly inside the map border only]. This parameter does not apply to lines and polygons which are always clipped to the map region. For periodic (360-longitude) maps we must plot all symbols twice in case they are clipped by the repeating boundary. ``no_clip=True`` will turn off clipping and not plot repeating symbols. Use ``no_clip="r"`` to turn off clipping but retain the plotting of such repeating symbols, or use ``no_clip="c"`` to retain clipping but turn off plotting of repeating symbols. no_sort : bool Turn off the automatic sorting of items based on their distance from the viewer. The default is to sort the items so that items in the foreground are plotted after items in the background. style : str Plot symbols. Full documentation is at :gmt-docs:`plot3d.html#s`. {U} {V} {W} {XY} zvalue : str *value*\|\ *file*. Instead of specifying a symbol or polygon fill and outline color via ``color`` and ``pen``, give both a *value* via **zvalue** and a color lookup table via ``cmap``. Alternatively, give the name of a *file* with one z-value (read from the last column) for each polygon in the input data. To apply it to the fill color, use ``color='+z'``. To apply it to the pen color, append **+z** to ``pen``. {a} {b} {c} {d} {e} {f} {g} {h} {i} {l} {p} {t} *transparency* can also be a 1d array to set varying transparency for symbols, but this option is only valid if using x/y/z. {w} """ # pylint: disable=too-many-locals kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access kind = data_kind(data, x, y, z) extra_arrays = [] if kwargs.get("S") is not None and kwargs["S"][ 0] in "vV" and direction is not None: extra_arrays.extend(direction) elif ( kwargs.get("S") is None and kind == "geojson" and data.geom_type.isin(["Point", "MultiPoint"]).all() ): # checking if the geometry of a geoDataFrame is Point or MultiPoint kwargs["S"] = "u0.2c" elif kwargs.get("S") is None and kind == "file" and str(data).endswith( ".gmt"): # checking that the data is a file path to set default style try: with open(which(data), mode="r", encoding="utf8") as file: line = file.readline() if "@GMULTIPOINT" in line or "@GPOINT" in line: # if the file is gmt style and geometry is set to Point kwargs["S"] = "u0.2c" except FileNotFoundError: pass if kwargs.get("G") is not None and is_nonstr_iter(kwargs["G"]): if kind != "vectors": raise GMTInvalidInput( "Can't use arrays for color if data is matrix or file.") extra_arrays.append(kwargs["G"]) del kwargs["G"] if size is not None: if kind != "vectors": raise GMTInvalidInput( "Can't use arrays for 'size' if data is a matrix or a file.") extra_arrays.append(size) for flag in ["I", "t"]: if kwargs.get(flag) is not None and is_nonstr_iter(kwargs[flag]): if kind != "vectors": raise GMTInvalidInput( f"Can't use arrays for {plot3d.aliases[flag]} if data is matrix or file." ) extra_arrays.append(kwargs[flag]) kwargs[flag] = "" with Session() as lib: # Choose how data will be passed in to the module file_context = lib.virtualfile_from_data( check_kind="vector", data=data, x=x, y=y, z=z, extra_arrays=extra_arrays, required_z=True, ) with file_context as fname: lib.call_module(module="plot3d", args=build_arg_string(kwargs, infile=fname))