Creating Graphs with NetworkX
In this tutorial, we will look at how to create graph data structures with networkx. We'll consider how to add and remove both nodes and edges, and how to inspect basic properties of the graph.
The video for this post can be found below:
Objectives
- Learn how to create a graph in
networkx - Learn how to add and remove nodes to the graph
- Learn how to add and remove edges between nodes
- Learn how to inspect graph properties, such as its nodes, its edges, the degrees of nodes, and the neighbors of nodes.
Code
A graph can be created in networkx by instantiating the nx.Graph() class. This will create an empty graph, with no nodes and no edges.
import networkx as nx
G = nx.Graph()
len(G) # gives 0
Calling len(G) on the graph will return the number of nodes in the graph (zero in this case, since we created an empty graph).
We can also create a directed graph with nx.DiGraph() - this will be covered in another lesson.
Adding Nodes
To add nodes to a graph, we have some different options.
- Use the
G.add_node(node)function - Use the
G.add_nodes_from(iterable)function - Add nodes from an existing graph into our new graph.
We can also inspect the existing nodes on a graph with the G.nodes property, which returns an iterable NodeView object.
We will consider the first two options, with the code below.
G.add_node(1)
G.add_nodes_from([2,3,4,5])
# inspect existing nodes
print("Nodes: ", G.nodes) # Nodes: [1, 2, 3, 4, 5]
The call to G.add_node(1) will add a single node with label 1 to the graph, whereas the G.add_nodes_from([2,3,4,5]) call will add 4 nodes in one action, with labels 2,3,4 and 5.
We can draw this graph using the nx.draw(G) function - this will simply return 5 disconnected nodes, since we have no edges yet.
We now want to add some edges to the graph.
Adding Edges
Two main functions can be used to add edges to the graph.
G.add_edge(node1, node2)G.add_edges_from(iterable)
We can also inspect existing edges in the graph with the G.edges property.
G.add_edge(1,2)
G.add_edges_from([(1,3), (2,4), (1,4)])
# inspect existing edges
print("Edges: ", G.edges) # [(1, 2), (1, 3), (1, 4), (2, 4)]
The call to G.add_edge(1,2) creates an edge between nodes 1 and 2. The G.add_edges_from([(1,3), (2,4), (1,4)]) statement creates three edges in a single call.
Drawing this graph will return a graph similar to the one below. We can see two connected components - node 5 is disconnected from the main component, as we did not specify any edges involving that node.
We can also remove nodes and edges from the graph.
Removing Nodes and Edges
Nodes and edges can be removed with the following functions.
G.remove_node(node)G.remove_nodes_from(iterable)G.remove_edge(node1, node2)
We will quickly inspect how to remove an edge, below.
G.remove_edge(2,4) # remove edge between node 2 and 4
Note: trying to remove an edge that does not exist will result in a KeyError.
Inspecting the Graph
There are 4 main ways to inspect the nodes and edges in a graph.
G.nodes- returns a view of the nodes that exist in the graphG.edges- returns a view of the edges that exist in the graphG.degree- returns a view of the degrees of each node in the graph.G.adj- returns a view of which neighbours each node has in the graph
We have already seen the first two of those properties in the code above. Now, let's dive into the latter two, starting with the G.degree property.
print(G.degree) # {1: 3, 2: 1, 3: 1, 4: 1, 5: 0}
The output shows, for each node, how many other nodes it is incident to (i.e. its degree). We could sort this from highest degree first - intuitively, we might want to know which nodes have highest degree, as these are likely to be important in the network. The code to sort is shown below.
sorted(G.degree, key=lambda x: x[1], reverse=True)
We can also consider the G.adj property.
print(G.adj) # {1: {2: {}, 3: {}, 4: {}}, 2: {1: {}}, 3: {1: {}}, 4: {1: {}}, 5: {}}
The output is slightly convoluted, but it shows, for each node, which other nodes it is connected to via an edge. We can see that node 1 is connected to nodes 2,3 and 4, whereas node 5 has no neighbours
For an individual node, it is easier to view neighbours using the G.neighbors(node) function.
list(G.neighbors(1)) # [2, 3, 4]
This outputs a list of all nodes which are neighbours (i.e. are connected to) node 1.
Summary
This post has summarized some of the basic graph-building functionality of networkx.
If you enjoyed this post, please subscribe to our YouTube channel and follow us on Twitter to keep up with our new content!
Please also consider buying us a coffee, to encourage us to create more posts and videos!