Example #1
0
def test_gmt_compat_6_is_applied(capsys):
    """
    Ensure that users with old gmt.conf files won't get pygmt-session [ERROR]:

    GMT_COMPATIBILITY: Expects values from 6 to 6; reset to 6.
    """
    end()  # Kill the global session
    try:
        # Generate a gmt.conf file in the current directory
        # with GMT_COMPATIBILITY = 5
        with Session() as lib:
            lib.call_module("gmtset", "GMT_COMPATIBILITY 5")
        begin()
        with Session() as lib:
            lib.call_module("basemap", "-R10/70/-3/8 -JX4i/3i -Ba")
            out, err = capsys.readouterr()  # capture stdout and stderr
            assert out == ""
            assert err != ("pygmt-session [ERROR]: GMT_COMPATIBILITY:"
                           " Expects values from 6 to 6; reset to 6.\n")
            assert err == ""  # double check that there are no other errors
    finally:
        end()
        # Clean up the global "gmt.conf" in the current directory
        assert os.path.exists("gmt.conf")
        os.remove("gmt.conf")
        assert os.path.exists("pygmt-session.pdf")
        os.remove("pygmt-session.pdf")
        # Make sure no global "gmt.conf" in the current directory
        assert not os.path.exists("gmt.conf")
        begin()  # Restart the global session
Example #2
0
    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))
Example #3
0
 def __exit__(self, exc_type, exc_value, traceback):
     # revert to initial values
     arg_str = " ".join(
         ["{}={}".format(key, value) for key, value in self.old_defaults.items()]
     )
     with Session() as lib:
         lib.call_module("set", arg_str)
Example #4
0
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)
Example #5
0
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
Example #6
0
    def shift_origin(self, xshift=None, yshift=None):
        """
        Shift plot origin in x and/or y directions.

        This method shifts plot origin relative to the current origin by
        (*xshift*, *yshift*) and optionally append the length unit (**c**,
        **i**, or **p**).

        Prepend **a** to shift the origin back to the original position after
        plotting, prepend **c** to center the plot on the center of the paper
        (optionally add shift), prepend **f** to shift the origin relative to
        the fixed lower left corner of the page, or prepend **r** [Default] to
        move the origin relative to its current location.

        Detailed usage at
        :gmt-docs:`cookbook/options.html#plot-positioning-and-layout-the-x-y-options`

        Parameters
        ----------
        xshift : str
            Shift plot origin in x direction.
        yshift : str
            Shift plot origin in y direction.
        """
        self._preprocess()
        args = ["-T"]
        if xshift:
            args.append("-X{}".format(xshift))
        if yshift:
            args.append("-Y{}".format(yshift))

        with Session() as lib:
            lib.call_module("plot", " ".join(args))
Example #7
0
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
Example #8
0
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
Example #9
0
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
Example #10
0
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
Example #11
0
 def region(self):
     """
     The geographic WESN bounding box for the current figure.
     """
     self._activate_figure()
     with Session() as lib:
         wesn = lib.extract_region()
     return wesn
Example #12
0
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
Example #13
0
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
Example #14
0
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
Example #15
0
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
Example #16
0
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
Example #17
0
def end():
    """
    Terminate GMT modern mode session and optionally produce the figure files.

    Called after :func:`pygmt.begin` and all commands that you want included in
    a session. Will finalize any PostScript plots that were made in the
    background, convert them to the desired format (specified in
    ``pygmt.begin``), and bring the figures to the working directory.
    """
    with Session() as lib:
        lib.call_module(module="end", args="")
Example #18
0
    def __init__(self, **kwargs):
        # Save values so that we can revert to their initial values
        self.old_defaults = {}
        self.special_params = {
            "FONT": [
                "FONT_ANNOT_PRIMARY",
                "FONT_ANNOT_SECONDARY",
                "FONT_HEADING",
                "FONT_LABEL",
                "FONT_TAG",
                "FONT_TITLE",
            ],
            "FONT_ANNOT": ["FONT_ANNOT_PRIMARY", "FONT_ANNOT_SECONDARY"],
            "FORMAT_TIME_MAP":
            ["FORMAT_TIME_PRIMARY_MAP", "FORMAT_TIME_SECONDARY_MAP"],
            "MAP_ANNOT_OFFSET": [
                "MAP_ANNOT_OFFSET_PRIMARY",
                "MAP_ANNOT_OFFSET_SECONDARY",
            ],
            "MAP_GRID_CROSS_SIZE": [
                "MAP_GRID_CROSS_SIZE_PRIMARY",
                "MAP_GRID_CROSS_SIZE_SECONDARY",
            ],
            "MAP_GRID_PEN": ["MAP_GRID_PEN_PRIMARY", "MAP_GRID_PEN_SECONDARY"],
            "MAP_TICK_LENGTH":
            ["MAP_TICK_LENGTH_PRIMARY", "MAP_TICK_LENGTH_SECONDARY"],
            "MAP_TICK_PEN": ["MAP_TICK_PEN_PRIMARY", "MAP_TICK_PEN_SECONDARY"],
        }
        with Session() as lib:
            for key in kwargs:
                if key in self.special_params:
                    for k in self.special_params[key]:
                        self.old_defaults[k] = lib.get_default(k)
                else:
                    self.old_defaults[key] = lib.get_default(key)

        # call gmt set to change GMT defaults
        arg_str = " ".join(
            ["{}={}".format(key, value) for key, value in kwargs.items()])
        with Session() as lib:
            lib.call_module("set", arg_str)
Example #19
0
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 test_begin_end():
    """
    Run a command inside a begin-end modern mode block.
    First, end the global session. When finished, restart it.
    """
    end()  # Kill the global session
    begin()
    with Session() as lib:
        lib.call_module("basemap", "-R10/70/-3/8 -JX4i/3i -Ba")
    end()
    begin()  # Restart the global session
    assert os.path.exists("pygmt-session.pdf")
    os.remove("pygmt-session.pdf")
Example #21
0
def begin():
    """
    Initiate a new GMT modern mode session.

    Used in combination with :func:`pygmt.end`.

    Only meant to be used once for creating the global session.
    """
    prefix = "pygmt-session"
    with Session() as lib:
        lib.call_module(module="begin", args=prefix)
        # pygmt relies on GMT modern mode with GMT_COMPATIBILITY at version 6
        lib.call_module(module="set", args="GMT_COMPATIBILITY 6")
Example #22
0
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
Example #23
0
def print_clib_info():
    """
    Print information about the GMT shared library that we can find.

    Includes the GMT version, default values for parameters, the path to the
    ``libgmt`` shared library, and GMT directories.
    """
    from pygmt.clib import Session

    lines = ["GMT library information:"]
    with Session() as ses:
        for key in sorted(ses.info):
            lines.append("  {}: {}".format(key, ses.info[key]))
    print("\n".join(lines))
Example #24
0
def print_clib_info():
    """
    Print information about the GMT shared library that we can find.

    Includes the GMT version, default values for parameters, the path to the
    ``libgmt`` shared library, and GMT directories.
    """
    from pygmt.clib import Session  # pylint: disable=import-outside-toplevel

    lines = ["GMT library information:"]
    with Session() as ses:
        for key in sorted(ses.info):
            lines.append(f"  {key}: {ses.info[key]}")
    print("\n".join(lines))
Example #25
0
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))
Example #26
0
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
Example #27
0
    def _activate_figure(self):
        """
        Start and/or activate the current figure.

        All plotting commands run afterward will append to this figure.

        Unlike the command-line version (``gmt figure``), this method does not
        trigger the generation of a figure file. An explicit call to
        :meth:`pygmt.Figure.savefig` or :meth:`pygmt.Figure.psconvert` must be
        made in order to get a file.
        """
        # Passing format '-' tells pygmt.end to not produce any files.
        fmt = "-"
        with Session() as lib:
            lib.call_module("figure", "{} {}".format(self._name, fmt))
Example #28
0
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
Example #29
0
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)
Example #30
0
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))