# NetworkX graph¶

WNTR can generate a NetworkX data object that stores network connectivity as a graph. A graph is a collection of nodes that are connected by links. For water networks, nodes represent junctions, tanks, and reservoirs while links represent pipes, pumps, and valves. The NetworkX graph can be used to analyze network structure.

The type of NetworkX graph generated by WNTR is a directed multigraph. A directed multigraph is a graph with direction associated with links and the graph can have multiple links with the same start and end node. A simple example is shown in Figure 5. For water networks, the link direction is from the start node to the end node. The link direction is used as a reference to track flow direction in the network. For example, positive flow indicates that the flow direction is from the start node to the end node while negative flow indicates that the flow direction is from the end node to the start node. Multiple links with the same start and end node can be used to represent redundant pipes or backup pumps. A NetworkX graph generated from a water network model stores the start and end node of each link, node coordinates, and node and link types (i.e., Tank, Reservoir, Valve).

NetworkX includes numerous methods to analyze the structure of complex networks. For more information on NetworkX, see https://networkx.github.io/. WNTR includes a custom Graph Class, WntrMultiDiGraph. This class inherits from NetworkX MultiDigraph and includes additional methods that are specific to WNTR. The example networkx_graph.py can be used to generate a graph from a water network model.

A NetworkX graph can an be obtained using the following function:

G = wn.get_graph()


The graph is stored as a nested dictionary. The nodes and links (note that links are called edges in NetworkX) can be accessed using the following:

node_name = '123'
print(G.node[node_name])


The graph can be used to access NetworkX methods, for example:

import networkx as nx
node_degree = G.degree()
bet_cen = nx.betweenness_centrality(G)
wntr.graphics.plot_network(wn, node_attribute=bet_cen, node_size=30,
title='Betweenness Centrality')


Some methods in NetworkX require that networks are undirected. An undirected graph is a graph with no direction associated with links. The following NetworkX method can be used to convert a directed graph to an undirected graph:

uG = G.to_undirected()


Some methods in NetworkX require that networks are connected. A connected graph is a graph where a path exists between every node in the network (i.e., no node is disconnected). The following NetworkX method can be used to check if a graph is connected:

print(nx.is_connected(uG))


Some methods in NetworkX can use weighted graphs. A weighted graph is a graph in which each link is given a weight. The WNTR method weight_graph can be used to weight the graph by any attribute. In the following example, the graph is weighted by length. This graph can then be used to compute path lengths:

length = wn.query_link_attribute('length')