The core API

pygridtools.core.transform(nodes, fxn, *args, **kwargs)[source]

Apply an arbitrary function to an array of node coordinates.

Parameters:
nodes : numpy.ndarray

An N x M array of individual node coordinates (i.e., the x-coords or the y-coords only)

fxn : callable

The transformation to be applied to the whole nodes array

args, kwargs

Additional positional and keyword arguments that are passed to fxn. The final call will be fxn(nodes, *args, **kwargs).

Returns:
transformed : numpy.ndarray

The transformed array.

pygridtools.core.split(nodes, index, axis=0)[source]

Split a array of nodes into two separate, non-overlapping arrays.

Parameters:
nodes : numpy.ndarray

An N x M array of individual node coordinates (i.e., the x-coords or the y-coords only)

index : int

The leading edge of where the split should occur.

axis : int, optional

The axis along which nodes will be split. Use axis = 0 to split along rows and axis = 1 for columns.

Returns:
n1, n2 : numpy.ndarrays

The two non-overlapping sides of the original array.

Raises:
ValueError

Trying to split nodes at the edge (i.e., resulting in the original array and an empty array) will raise an error.

pygridtools.core.merge(nodes, other_nodes, how='vert', where='+', shift=0)[source]

Merge two sets of nodes together.

Parameters:
nodes, other_nodes : numpy.ndarrays

The sets of nodes that will be merged.

how : string, optional (default = ‘vert’)

The method through wich the arrays should be stacked. ‘Vert’ is analogous to numpy.vstack. ‘Horiz’ maps to numpy.hstack.

where : string, optional (default = ‘+’)

The placement of the arrays relative to each other. Keeping in mind that the origin of an array’s index is in the upper-left corner, ‘+’ indicates that the second array will be placed at higher index relative to the first array. Essentially

  • if how == ‘vert’
    • ‘+’ -> a is above (higher index) b
    • ‘-‘ -> a is below (lower index) b
  • if how == ‘horiz’
    • ‘+’ -> a is to the left of b
    • ‘-‘ -> a is to the right of b

See the examples and :func:~`pygridtools.misc.padded_stack` for more info.

shift : int, optional (default = 0)

The number of indices the second array should be shifted in axis other than the one being merged. In other words, vertically stacked arrays can be shifted horizontally, and horizontally stacked arrays can be shifted vertically.

Returns:
merged : numpy.ndarrays

The unified nodes coordinates.

pygridtools.core.insert(nodes, index, axis=0, n_nodes=1)[source]

Inserts new rows or columns between existing nodes.

Parameters:
nodes : numpy.ndarray

The the array to be inserted.

index : int

The index within the array that will be inserted.

axis : int

Either 0 to insert rows or 1 to insert columns.

n_nodes : int

The number of new nodes to be inserted. In other words, n_nodes = 1 implies that the given row to columns will be split in half. Similarly, n_nodes = 2 will divide into thirds, n_nodes = 3 implies quarters, and so on.

Returns:
inserted : numpy.ndarray

The modified node array.

pygridtools.core.extract(nodes, jstart=None, istart=None, jend=None, iend=None)[source]

Extracts a subset of an array into new array.

Parameters:
jstart, jend : int, optional

Start and end of the selection along the j-index

istart, iend : int, optional

Start and end of the selection along the i-index

Returns:
subset : array

The extracted subset of a copy of the original array.

Notes

Calling this without any [j|i][start|end] arguments effectively just makes a copy of the array.

class pygridtools.core.ModelGrid(nodes_x, nodes_y, crs=None)[source]

Bases: object

Container for a curvilinear-orthogonal grid. Provides convenient access to masking, manipulation, and visualization methods.

Although a good effort attempt is made to be consistent with the terminology, in general node and vertex are used interchangeably, with the former prefered over the latter. Similarly, centroids and cells can be interchangeable, although they are different. (Cell = the polygon created by 4 adjacent nodes and centroid = the centroid point of a cell).

Parameters:
nodes_x, nodes_y : numpy.ndarray

M-by-N arrays of node (vertex) coordinates for the grid.

crs : dict or str, optional

Output projection parameters as string or in dictionary form.

nodes_x

Array of node x-coordinates.

nodes_y

Array of node y-coordinates.

cells_x

Array of cell centroid x-coordinates

cells_y

Array of cell centroid y-coordinates

shape

Shape of the nodes arrays

cell_shape

Shape of the cells arrays

xn

Shortcut to x-coords of nodes

yn

Shortcut to y-coords of nodes

xc

Shortcut to x-coords of cells/centroids

yc

Shortcut to y-coords of cells/centroids

icells

Number of rows of cells

jcells

Number of columns of cells

inodes

Number of rows of nodes

jnodes

Number of columns of nodes

cell_mask

Boolean mask for the cells

node_mask
crs

Coordinate reference system for GIS data export

domain

The optional domain used to generate the raw grid

extent

The final extent of the model grid (everything outside is masked).

islands

Polygons used to make holes/gaps in the grid

transform(fxn, *args, **kwargs)[source]

Apply an attribrary function to the grid nodes.

Parameters:
fxn : callable

The function to be applied to the nodes. It should accept a node array as its first argument.

arg, kwargs : optional arguments and keyword arguments

Additional values passed to fxn after the node array.

Returns:
modelgrid

A new ModelGrid is returned.

transform_x(fxn, *args, **kwargs)[source]
transform_y(fxn, *args, **kwargs)[source]
transpose()[source]

Transposes the node arrays of the model grid.

Parameters:
None
Returns:
modelgrid

A new ModelGrid is returned.

fliplr()[source]

Reverses the columns of the node arrays of the model grid.

Parameters:
None
Returns:
modelgrid

A new ModelGrid is returned.

flipud()[source]

Reverses the rows of the node arrays of the model grid.

Parameters:
None
Returns:
modelgrid

A new ModelGrid is returned.

split(index, axis=0)[source]

Splits a model grid into two separate objects.

Parameters:
index : int

The leading edge of where the split should occur.

axis : int, optional

The axis along which nodes will be split. Use axis = 0 to split along rows and axis = 1 for columns.

Returns:
grid1, grid2 : ModelGrids

The two non-overlapping sides of the grid.

Raises:
ValueError

Trying to split at the edge (i.e., resulting in the original array and an empty array) will raise an error.

insert(index, axis=0, n_nodes=1)[source]

Inserts and linearly interpolates new nodes in an existing grid.

Parameters:
nodes : numpy.ndarray

An N x M array of individual node coordinates (i.e., the x-coords or the y-coords only)

index : int

The leading edge of where the split should occur.

axis : int, optional

The axis along which nodes will be split. Use axis = 0 to split along rows and axis = 1 for columns.

n_nodes : int, optional

The number of new rows or columns to be inserted.

Returns:
modelgrid

A new ModelGrid is returned.

extract(jstart=0, istart=0, jend=-1, iend=-1)[source]

Extracts a subset of an array into new grid.

Parameters:
jstart, jend : int, optional

Start and end of the selection along the j-index

istart, iend : int, optional

Start and end of the selection along the i-index

Returns:
subset : grid

The extracted subset of a copy of the original grid.

Notes

Calling this without any [j|i][start|end] arguments effectively just makes a copy of the grid.

copy()[source]

Returns a deep copy of the current ModelGrid

merge(other, how='vert', where='+', shift=0, min_nodes=1)[source]

Merge with another grid using pygridtools.misc.padded_stack.

Parameters:
other : ModelGrid

The other ModelGrid object.

how : optional string (default = ‘vert’)

The method through wich the arrays should be stacked. ‘Vert’ is analogous to numpy.vstack. ‘Horiz’ maps to numpy.hstack.

where : optional string (default = ‘+’)

The placement of the arrays relative to each other. Keeping in mind that the origin of an array’s index is in the upper-left corner, ‘+’ indicates that the second array will be placed at higher index relative to the first array. Essentially:

  • if how == ‘vert’
    • ‘+’ -> a is above (higher index) b
    • ‘-‘ -> a is below (lower index) b
  • if how == ‘horiz’
    • ‘+’ -> a is to the left of b
    • ‘-‘ -> a is to the right of b

See the examples and pygridtools.misc.padded_stack for more info.

shift : int (default = 0)

The number of indices the second array should be shifted in axis other than the one being merged. In other words, vertically stacked arrays can be shifted horizontally, and horizontally stacked arrays can be shifted vertically.

min_nodes : int (default = 1)

Minimum number of masked nodes required to mask a cell.

Returns:
modelgrid

A new ModelGrid is returned.

See also

pygridtools.padded_stack

Examples

import matplotlib.pyplot as plt
import pandas
import pygridtools
domain1 = pandas.DataFrame({
    'x': [2, 5, 5, 2],
    'y': [6, 6, 4, 4],
    'beta': [1, 1, 1, 1]
})
domain2 = pandas.DataFrame({
    'x': [6, 11, 11, 5],
    'y': [5, 5, 3, 3],
    'beta': [1, 1, 1, 1]
})
grid1 = pygridtools.make_grid(domain=domain1, nx=6, ny=5, rawgrid=False)
grid2 = pygridtools.make_grid(domain=domain2, nx=8, ny=7, rawgrid=False)
merged = grid1.merge(grid2, how='horiz')
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6, 6))
grid1.plot_cells(ax=ax1, cell_kws=dict(cmap='Blues'))
grid2.plot_cells(ax=ax1, cell_kws=dict(cmap='Greens'))
merged.plot_cells(ax=ax2, cell_kws=dict(cmap='BuPu'))
plt.show()

(Source code)

update_cell_mask(mask=None, merge_existing=True)[source]

Regenerate the cell mask based on either the NaN cells or a user-provided mask. This is usefull after splitting, merging, or anything other transformation.

Parameters:
mask : numpy.ndarray of bools, optional

The custom make to apply. If ommited, the mask will be determined by the missing values in the cells arrays.

merge_existing : bool (default is True)

If True, the new mask is bitwise OR’d with the existing mask.

Returns:
masked : ModelGrid

A new ModelGrid wit the final mask to be applied to the cells.

mask_nodes(inside=None, outside=None, min_nodes=3, use_existing=False, triangles=False)[source]

Create mask the ModelGrid based on its nodes with a polygon.

Parameters:
inside, outside : GeoDataFrame, optional

GeoDataFrames of Polygons or MultiPolygons inside or outside of which nodes will be masked, respectively.

min_nodes : int (default = 3)

Only used when use_centroids is False. This is the minimum number of nodes inside the polygon required to mark the cell as “inside”. Must be greater than 0, but no more than 4.

use_existing : bool (default = True)

When True, the newly computed mask is combined (via a bit-wise or operation) with the existing cell_mask attribute of the ModelGrid.

Returns:
masked : ModelGrid

A new ModelGrid with the final mask to be applied to the cells.

mask_centroids(inside=None, outside=None, use_existing=True)[source]

Create mask for the cells of the ModelGrid with a polygon.

Parameters:
inside, outside : GeoDataFrame, optional

GeoDataFrames of Polygons or MultiPolygons inside or outside of which nodes will be masked, respectively.

use_existing : bool (default = True)

When True, the newly computed mask is combined (via a bit-wise or operation) with the existing cell_mask attribute of the ModelGrid.

Returns:
masked : ModelGrid

A new ModelGrid wit the final mask to be applied to the cells.

mask_cells_with_polygon(**kwds)

mask_cells_with_polygon is deprecated! use mask_nodes or mask_centroids

plot_cells(engine='mpl', ax=None, usemask=True, showisland=True, cell_kws=None, domain_kws=None, extent_kws=None, island_kws=None)[source]

Creates a figure of the cells, boundary, domain, and islands.

Parameters:
engine : str

The plotting engine to be used. Right now, only ‘mpl’ has been implemented. Interactive figures via ‘bokeh’ are planned.

ax : matplotlib.Axes, optional

The axes onto which the data will be drawn. If not provided, a new one will be created. Applies only to the mpl engine.

usemask : bool, optional

Whether or not cells should have the ModelGrid’s mask applied to them.

cell_kws, domain_kws, extent_kws, island_kws : dict

Dictionaries of plotting options for each element of the figure.

cell_kws and island_kws are fed to Polygon(). All others are sent to plot().

to_point_geodataframe(which='nodes', usemask=True, elev=None)[source]
to_polygon_geodataframe(usemask=True, elev=None)[source]
to_dataframe(usemask=False, which='nodes')[source]

Converts a grid to a wide dataframe of coordinates.

Parameters:
usemask : bool, optional

Toggles the ommission of masked values (as determined by cell_mask().

which : str, optional (‘nodes’)

This can be “nodes” (default) or “cells”. Specifies which coordinates should be used.

Returns:
pandas.DataFrame
to_coord_pairs(usemask=False, which='nodes')[source]

Converts a grid to a long array of coordinates pairs.

Parameters:
usemask : bool, optional

Toggles the ommission of masked values (as determined by cell_mask().

which : str, optional (‘nodes’)

This can be “nodes” (default) or “cells”. Specifies which coordinates should be used.

Returns:
numpy.ndarray
to_gefdc(directory)[source]
classmethod from_dataframe(df, icol='ii', jcol='jj', xcol='easting', ycol='northing', crs=None)[source]

Build a ModelGrid from a DataFrame of I/J indexes and x/y columns.

Parameters:
df : pandas.DataFrame

Must have a MultiIndex of I/J cell index values.

xcol, ycol : str, optional

The names of the columns for the x and y coordinates.

icol : str, optional

The index level specifying the I-index of the grid.

crs : dict or str, optional

Output projection parameters as string or in dictionary form.

Returns:
ModelGrid
classmethod from_gis(gisfile, icol='ii', jcol='jj')[source]

Build a ModelGrid from a GIS file of nodes.

Parameters:
gisfile : str

The path to the GIS file of the grid nodes.

icol, jcol : str, optional

The names of the columns in the gisfile containing the I/J index of the nodes.

Returns:
ModelGrid
classmethod from_Gridgen(gridgen, crs=None)[source]

Build a ModelGrid from a Gridgen object.

Parameters:
gridgen : pygridgen.Gridgen
crs : dict or str, optional

Output projection parameters as string or in dictionary form.

Returns:
ModelGrid
pygridtools.core.make_grid(ny, nx, domain, betacol='beta', crs=None, rawgrid=True, **gg_params)[source]

Generate a Gridgen or ModelGrid from scratch. This can take a large number of parameters passed directly to the Gridgen constructor. See the Other Parameters section.

Parameters:
ny, nx : int

The number of rows and columns that will make up the grid’s nodes. Note the final grid cells will be (ny-1) by (nx-1).

domain : GeoDataFrame

Defines the boundary of the model area. Needs to have a column of Point geometries and a a column of beta (turning point) values.

betacol : str

Label of the column in domain that contains the beta (i.e., turning point) values of domain. This sum of this column must be 4.

crs : dict or str, optional

Output projection parameters as string or in dictionary form.

rawgrid : bool (default = True)

When True, returns a pygridgen.Gridgen object. Otherwise, a pygridtools.ModelGrid object is returned.

Returns:
grid : pygridgen.Gridgen or ModelGrid
Other Parameters:
 
ul_idx : optional int (default = 0)

The index of the what should be considered the upper left corner of the grid boundary in the xbry, ybry, and beta inputs. This is actually more arbitrary than it sounds. Put it some place convenient for you, and the algorthim will conceptually rotate the boundary to place this point in the upper left corner. Keep that in mind when specifying the shape of the grid.

focus : optional pygridgen.Focus instance or None (default)

A focus object to tighten/loosen the grid in certain sections.

proj : option pyproj projection or None (default)

A pyproj projection to be used to convert lat/lon coordinates to a projected (Cartesian) coordinate system (e.g., UTM, state plane).

nnodes : optional int (default = 14)

The number of nodes used in grid generation. This affects the precision and computation time. A rule of thumb is that this should be equal to or slightly larger than -log10(precision).

precision : optional float (default = 1.0e-12)

The precision with which the grid is generated. The default value is good for lat/lon coordinate (i.e., smaller magnitudes of boundary coordinates). You can relax this to e.g., 1e-3 when working in state plane or UTM grids and you’ll typically get better performance.

nppe : optional int (default = 3)

The number of points per internal edge. Lower values will coarsen the image.

newton : optional bool (default = True)

Toggles the use of Gauss-Newton solver with Broyden update to determine the sigma values of the grid domains. If False simple iterations will be used instead.

thin : optional bool (default = True)

Toggle to True when the (some portion of) the grid is generally narrow in one dimension compared to another.

checksimplepoly : optional bool (default = True)

Toggles a check to confirm that the boundary inputs form a valid geometry.

verbose : optional bool (default = True)

Toggles the printing of console statements to track the progress of the grid generation.

See also

pygridgen.Gridgen, pygridtools.ModelGrid

Notes

If your boundary has a lot of points, this really can take quite some time.