gwsource.graphplot#

Plots of the flow graph: the package network on a map, a zone graph and a local zoom.

The full graph of a model is mostly cell-to-cell flows and is better shown as maps of per-cell
values (gwsource.export). The views here draw the parts of the graph that a node-link drawing
does show well:

- package network: the package nodes (SFR reaches, lakes, MAW wells, UZF cells) at the mean
  centre of the cells they exchange water with, their links to each other (package FLOW-JA-FACE,
  lake outlets, MVR) as lines, line width the flow on the link;
- zone graph: the graph condensed to a few zones (for example the model layers and each package),
  with the flow between zones and the source and sink terms of each zone;
- local zoom: a handful of nodes (a cycle, the neighbourhood of a well) with every edge between
  them drawn as an arrow, in plan with each layer shifted so that vertical flows show.

Water that reaches a group. In a backward result, F_j is the share of the water passing through
node j that reaches the group (fraction_through). The water on an edge i -> j that reaches the
group is q_ij F_j, and the water from a source term of node i that reaches it is s_i F_i. Summed
over the source terms this is the group's volume_from. Every view takes these weights in place
of the plain flows, so the same drawing shows where all the water goes or only the water that
reaches the group.

Data functions return numpy arrays and need only numpy; the plot functions import matplotlib.
class gwsource.graphplot.ZoneGraph(names, flow, term_in, term_out)[source]#

Bases: object

The flow graph condensed to zones.

flow[a, b] is the flow from zone a to zone b; term_in[name][a] and term_out[name][a] are the
source and sink terms of zone a by package (both positive).
Parameters:
gwsource.graphplot.edge_list(step)[source]#
Return (src, dst, q), one entry per directed edge with flow q > 0 from src to dst.
Parameters:

step (FlowStep)

Return type:

tuple[ndarray, ndarray, ndarray]

gwsource.graphplot.carried_flow(result, group, dst, q)[source]#
Return q F_dst, the part of each edge flow that reaches the group.
Parameters:
Return type:

ndarray

gwsource.graphplot.term_weights(step, result, group)[source]#
Return per term the part of its flow that reaches the group (sources F, sinks selected).
Parameters:
Return type:

ndarray

gwsource.graphplot.zone_graph(step, zones, names, edge_weight=None, term_weight=None)[source]#
Condense the graph to zones (zones[node] in 0..len(names)-1, -1 to leave a node out).

edge_weight scales each edge of edge_list(step) and term_weight each term; give both from
carried_flow and term_weights for the water that reaches a group.
Parameters:
Return type:

ZoneGraph

gwsource.graphplot.node_blocks(step)[source]#
Return the step's node blocks; a plain single-model step is one block of all its cells.
Parameters:

step (FlowStep)

Return type:

list[NodeBlock]

gwsource.graphplot.layer_zones(step)[source]#
Return zones and names: one zone per layer of each DIS/DISV model and one per package.
Parameters:

step (FlowStep)

Return type:

tuple[ndarray, list[str]]

gwsource.graphplot.source_matrix(step, result, groups, zones=None, zone_names=None)[source]#
Return (labels, V): V[s, g] the water from source s reaching group g [L3/T].

A source is a term package (volume_from_by_term) or, with zones, a package in a zone of
entry ('<package> | <zone>'). Sources that give no water to any group are left out.
Parameters:
Return type:

tuple[list[str], ndarray]

gwsource.graphplot.neighbourhood(step, nodes, hops=1)[source]#
Return the nodes within hops edges of nodes (either direction), sorted.
Parameters:
Return type:

ndarray

gwsource.graphplot.subgraph_edges(step, nodes)[source]#
Return (src, dst, q) of the edges with both ends in nodes.
Parameters:
Return type:

tuple[ndarray, ndarray, ndarray]

gwsource.graphplot.node_layers(step)[source]#
Return the 0-based layer of each DIS/DISV cell; -1 for package nodes and DISU cells.
Parameters:

step (FlowStep)

Return type:

ndarray

gwsource.graphplot.node_positions(step)[source]#
Return (x, y) of every node: cell centres and package points (NaN where unknown).
Parameters:

step (FlowStep)

Return type:

ndarray

gwsource.graphplot.shifted_positions(step, xy, shift)[source]#
Return xy with layer k moved by k * shift and package nodes by -1 * shift.
Parameters:
Return type:

ndarray

gwsource.graphplot.package_block(step, name)[source]#
Return the package NodeBlock whose label or name ends with name (e.g. 'SFR_0').
Parameters:
gwsource.graphplot.package_net_exchange(step, block)[source]#
Return per package node the net flow from the aquifer into it (positive: gaining node).
Parameters:

step (FlowStep)

Return type:

ndarray

gwsource.graphplot.plot_package_network(step, block, xy, ax, q=None, color=None, wmax=3.0, wmin=0.15, qmax=None, **kwargs)[source]#
Draw the links between the nodes of one package block; return the LineCollection.

q gives one value per link of package_links(step, block) (default: the link flows); color, if
given, one value per link for the colormap (kwargs go to LineCollection: cmap, norm, ...).
Parameters:
Return (src, dst, q) of the edges between nodes of one package block (incl. MVR).
Parameters:

step (FlowStep)

Return type:

tuple[ndarray, ndarray, ndarray]

gwsource.graphplot.ring_layout(names, radius=2.0)[source]#
Return zone positions on a circle, the first at the top and the rest clockwise.
Parameters:
Return type:

dict[str, ndarray]

gwsource.graphplot.plot_zone_graph(graph, ax, pos=None, qmax=None, wmax=14.0, min_share=0.005, term_length=1.5, color='#2a78d6', ink='#0b0b0b', muted='#52514e', fmt='{:,.0f}')[source]#
Draw a zone graph: net flows between zones as straight arrows, terms pointing outwards.

pos defaults to ring_layout(graph.names). Flows below min_share of the largest flow are
left out. Each zone's source terms come in, and its sink terms leave, along the direction
away from the centre of the layout, sources turned to one side and sinks to the other.
Parameters:
Return type:

None

gwsource.graphplot.plot_alluvial(labels, groups, matrix, ax, colors, gap=0.02, ink='#0b0b0b', muted='#52514e', fmt='{:,.0f}')[source]#
Draw sources (left) to groups (right) as bands of width V[s, g]; colors one per source.
Parameters:
Return type:

None

gwsource.graphplot.plot_subgraph(step, nodes, xy, ax, q=None, node_values=None, wmax=4.0, edge_color='#2a78d6', ink='#0b0b0b', package_color='white', **scatter_kwargs)[source]#
Draw the edges among nodes as arrows (width from q, default the flows); return the scatter.

q, if given, has one value per edge of subgraph_edges(step, nodes). Cells are circles,
coloured by node_values (kwargs go to scatter: cmap, vmin, vmax, ...); package nodes are
squares in package_color.
Parameters: