NetworkX Graphs

The NetworkX library

NetworkX is a Python library for creating, manipulating, and displaying mathematical objects called graphs, or networks.

We begin by importing the library:

import networkx as nx

Graphs

A graph is a mathematical object that consists of points called nodes together with lines connecting them called edges. Nodes are typically labeled with positive integers, and an edge between two nodes is given by an ordered pair.

G = nx.Graph()
G.add_nodes_from([1,2,3,4,5,6])
G.add_edge(1,4)
nx.draw(G)

In the above code, the function Graph() creates an empty graph object in Python that we can then fill with nodes and edges. Nodes and edges can either be added individually or from a list using different methods.

Below is the graph G generated by the code above.

../../../_images/graph1.png

Notice that the layout of the nodes is not ideal, and we do not know which node is which. To make the graph come out looking better, we can add some additional arguments to the draw function.

nx.draw(G, pos=nx.circular_layout(G), with_labels=True)
../../../_images/graph1_circular.png

In the above code, the argument pos=nx.circular_layout(G) arranges the nodes in a circle going counterclockwise with the first node on the right. The argument with_labels=True turns on the node labels so we can tell which node is which.

To modify the graph, we do not need to start over from scratch, we can simply add additional nodes and edges using the methods add_node, add_nodes_from, add_edge, and add_edges_from.

G.add_node(7)
G.add_edges_from([(1,2),(1,3),(1,4),(3,5),(3,6),(5,7)])
nx.draw(G, pos=nx.circular_layout(G), with_labels=True)
../../../_images/graph2.png

We can also remove nodes and edges in a similar fashion using the methods remove_node, remove_nodes_from, remove_edge, and remove_edges_from. When removing nodes, any edges containing the removed node will also be removed.

You can take at look at the nodes and edges in your graph at anytime using the nodes and edges methods.

G.nodes()

NodeView((1, 2, 3, 4, 5, 6, 7))

G.edges()

EdgeView([(1, 2), (1, 3), (1, 4), (2, 4), (3, 5), (3, 6), (5, 7)])

The data structure of graph objects is composed of dictionaries with the nodes as keys. If you input the node \(x\), you will get a dictionary containing the nodes connected to \(x\) by an edge. Such nodes are called adjacent or neighbors.

G[1]

AtlasView({2: {}, 3: {}, 4: {}})

The neighborhood of a node is the collection of all its neighbors. For example, the our graph \(G\), the neighborhood of node 1 is the collection of nodes 2, 3, and 4.

The number of nodes in the neighborhood of \(x\) is called the degree of the node \(x\). In our example, the degree of node 1 is 3 since node 1 has 3 neighbors. You can use the degree method to obtain the degree of a node.

G.degree(1)

3

Weighted Edges

NetworkX also makes it possible to assign different attributes to each edge, the most common of which are edge weights. An edge weight is a real number associated to an edge, typically representing the importance of the connection between the two corresponding nodes.

A weighted edge between nodes \(x\) and \(y\) with weight \(w\) is represented by the triple \((x,y,w)\).

W = nx.Graph()
W.add_weighted_edges_from([(1,2,1.3),(2,3,1.9),(2,4,0.8),(3,4,2.3)])
nx.draw(W, pos=nx.circular_layout(W), with_labels=True)
../../../_images/weighted_graph1.png

Notice that nx.draw does not draw the edge weights. For that we will need some additional commands.

weights = nx.get_edge_attributes(W,'weight')
nx.draw(W, pos=nx.circular_layout(W), with_labels=True)
nx.draw_networkx_edge_labels(W, pos=nx.circular_layout(W), edge_labels=weights)
plt.show()
../../../_images/weighted_graph2.png

Digraphs

A directed graph or digraph is a graph where the edges have direction. The edge, often called an arrow, \((x,y)\) starts at node \(x\) and goes to node \(y\).

D = DiGraph()
D.add_edges_from([(1,2),(3,2),(4,3),(4,1),(1,4),(3,1)])
nx.draw(D, pos=nx.circular_layout(D), with_labels=True)
../../../_images/digraph1.png

A node \(x\) in a digraph \(D\) has two neighborhoods, the out-neighborhood and the in-neighborhood. The out-neighborhood contains all the nodes \(y\) such that \(D\) contains the arrow \((x,y)\). The in-neighborhood of \(x\) contains all the nodes \(w\) such that \(D\) contains the arrow \((w,x)\). Thus every node will also have an out-degree and an in-degree.

It is easy to get the out-neighborhood of a node in a NetworkX digraph.

D[1]

AtlasView({2: {}, 4: {}})

The out-degree and in-degree can be obtained using the methods out_degree and in_degree respectively.

D.out_degree(3),D.in_degree(3)

(2,1)

Multigraphs

A multigraph is a graph that can have multiples edges connecting the same two nodes.

M = nx.MultiGraph()
M.add_edges_from([(1,2),(2,3),(3,1),(3,1),(3,1),(2,4),(2,4)])

Multigraphs also allow for edges to start and stop at the same node.

M.add_edge(1,1)

The neighborhood and degree are defined the same way as for graphs.

M[1]

AdjacencyView({2: {0: {}}, 3: {0: {}, 1: {}, 2: {}}, 1: {0: {}}})

M.degree(1)

6

Further reading

NetworkX website can be used to access the official documentation for the NetworkX library.