Note

This page was generated from a jupyter notebook.

Create A Network Grid from Raster Grid#

This notebook demonstrates how to extract a NetworkModelGrid from a RasterModelGrid using the ‘create_network_from_raster’ function

[ ]:
import matplotlib.pyplot as plt
import numpy as np

from landlab.grid.create_network import network_grid_from_raster
from landlab.io import esri_ascii
from landlab.plot.graph import plot_graph

Create a Raster Model Grid#

Now let’s create a raster model grid from the .asc data

[ ]:
with open("hugo_site.asc") as fp:
    grid = esri_ascii.load(fp, name="topographic__elevation", at="node")
z = grid.at_node["topographic__elevation"]

grid.status_at_node[grid.nodes_at_right_edge] = grid.BC_NODE_IS_FIXED_VALUE
grid.status_at_node[np.isclose(z, -9999.0)] = grid.BC_NODE_IS_CLOSED

Visualize Basin topography

[ ]:
grid.imshow(
    "topographic__elevation",
    plot_name="Basin topography",
    color_for_closed=None,
    colorbar_label="$z$ [m]",
)

Create a Network Model Grid#

Now let’s create a network model grid using the ‘create_network_from_raster’ function:

[ ]:
network_grid = network_grid_from_raster(
    grid,
    minimum_channel_threshold=12000.0,
    include=["drainage_area", "topographic__elevation"],
)

Let’s plot our network#

The nodes are numbered in landlab convention of lower-left to upper-right.

[ ]:
plot_graph(network_grid, at="node")
plt.title("Nodes");

As are the links,

[ ]:
plot_graph(network_grid, at="node,link", with_id="link")
plt.title("Links");
[ ]:
grid.imshow(
    "topographic__elevation",
    plot_name="Basin topography",
    color_for_closed=None,
    colorbar_label="$z$ [m]",
)
ax = plt.gca()
xlim, ylim = ax.get_xlim(), ax.get_ylim()

plot_graph(network_grid, at="link", with_id=False, axes=ax)

ax.set_xlim(xlim)
ax.set_ylim(ylim)
[ ]:
if len(network_grid.nodes_at_link) > (len(network_grid.nodes) - 1):
    print("there are duplicate links")
else:
    print("link count looks good!")

Reduce the numer of nodes in channel segments#

In the above, we have preserved every node in each channel segment. You can reduce the number of nodes in each segment by passing a reducer to the network_grid_from_raster function. A reducer is simply a function that accepts a list of nodes defining a segment. Although you can write your own, landlab provides a set of commonly used reducers.

[ ]:
from landlab.grid.create_network import (
    AtMostNodes,
    JustEndNodes,
    SpacingAtLeast,
    spacing_from_drainage_area,
)

As an example, the following will retain only the downstream and upstream node of each segment.

[ ]:
network_grid = network_grid_from_raster(
    grid,
    reducer=JustEndNodes(),
    minimum_channel_threshold=12000.0,
    include=["drainage_area", "topographic__elevation"],
)

plot_graph(network_grid, at="node,link")
plt.title("Nodes and Links");

Reduce to a maximum number of nodes per segment (including end nodes), use AtMostNodes,

[ ]:
network_grid = network_grid_from_raster(
    grid,
    reducer=AtMostNodes(count=4),
    minimum_channel_threshold=12000.0,
    include=["drainage_area", "topographic__elevation"],
)

plot_graph(network_grid, at="node,link")
plt.title("Nodes and Links");

Another option is to specify a spacing at each node. The spacing can be either a scalar, meaning the spacing is the same for every node, or can vary from node to node. An example of the latter is a spacing that depends on upstream area at each node.

[ ]:
spacing = spacing_from_drainage_area(grid.at_node["drainage_area"])

network_grid = network_grid_from_raster(
    grid,
    reducer=SpacingAtLeast(grid.xy_of_node, spacing),
    minimum_channel_threshold=12000.0,
    include=["drainage_area", "topographic__elevation"],
)

plot_graph(network_grid, at="node,link", with_id=False)
plt.title("Nodes and Links");

Generated by nbsphinx from a Jupyter notebook.