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
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 __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)
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 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))
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 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 _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 region(self): """ The geographic WESN bounding box for the current figure. """ self._activate_figure() with Session() as lib: wesn = lib.extract_region() return wesn
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 _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 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 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="")
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)
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")
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")
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 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))
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))
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 _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))
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))