Newbies Guide to Python-igraph. A simple guide to common functions of... | by Vijini Mallawaarachchi | Towards Data Science

Handling graph/network data has become much easier at present with the availability of different modules. For python, two of such modules are networkx and igraph. I have been playing around with the python-igraph module for some time and I have found it very useful in my research. I have used python-graph in my latest published tool GraphBin. In this article, I will introduce you to some basic functions of python-igraph which can make implementation much easier with just a single call.
You can read my previous article Visualising Graph Data with Python-igraph where I have introduced the python-igraph module.
towardsdatascience.com
In this article, we will go through the functions that perform the following tasks.
Creating a graphVisualising the graphObtaining information on the vertices and edges of the graphObtaining adjacent vertices to a vertexBreadth-first search (BFS) from a vertexDetermining shortest paths from a vertexObtain the Laplacian matrix of a graphDetermine the maximum flow between the source and target vertices
Creating a graph
Visualising the graph
Obtaining information on the vertices and edges of the graph
Obtaining adjacent vertices to a vertex
Breadth-first search (BFS) from a vertex
Determining shortest paths from a vertex
Obtain the Laplacian matrix of a graph
Determine the maximum flow between the source and target vertices
Let us start by plotting an example graph as shown in Figure 1.
This is a directed graph that contains 5 vertices. We can create this graph as follows.
# Create a directed graphg = Graph(directed=True)# Add 5 verticesg.add_vertices(5)
The vertices will be labelled from 0 to 4 and the 7 weighted edges (0,2), (0,1), (0,3), (1,2), (1,3), (2,4) and (3,4).
# Add ids and labels to verticesfor i in range(len(g.vs)):    g.vs[i]["id"]= i    g.vs[i]["label"]= str(i)# Add edgesg.add_edges([(0,2),(0,1),(0,3),(1,2),(1,3),(2,4),(3,4)])# Add weights and edge labelsweights = [8,6,3,5,6,4,9]g.es['weight'] = weightsg.es['label'] = weights
Now that we have created our graph, let’s visualise it using the plot function of igraph.
visual_style = {}out_name = "graph.png"# Set bbox and marginvisual_style["bbox"] = (400,400)visual_style["margin"] = 27# Set vertex coloursvisual_style["vertex_color"] = 'white'# Set vertex sizevisual_style["vertex_size"] = 45# Set vertex lable sizevisual_style["vertex_label_size"] = 22# Don't curve the edgesvisual_style["edge_curved"] = False# Set the layoutmy_layout = g.layout_lgl()visual_style["layout"] = my_layout# Plot the graphplot(g, out_name, **visual_style)
Running this code will result in a graph as shown in Figure 1. You can colour the vertices if you want as shown in Figure 2, by adding g.vs[“color”] = ["red", "green", "blue", "yellow", "orange"] instead of the line visual_style[“vertex_color”] = ‘white’. You can read more on visualising graphs and analysing them from my previous article Visualising Graph Data with Python-igraph.
You can obtain some basic information about the graph such as the number of vertices, the number of edges, whether the graph is directed or not, the maximum degree and the adjacency matrix of the graph by calling the functions vcount(), ecount(), is_directed(), maxdegree() and get_adjacency().
print("Number of vertices in the graph:", g.vcount())print("Number of edges in the graph", g.ecount())print("Is the graph directed:", g.is_directed())print("Maximum degree in the graph:", g.maxdegree())print("Adjacency matrix:\n", g.get_adjacency())
The output will be as follows.
Number of vertices in the graph: 5Number of edges in the graph 7Is the graph directed: TrueMaximum degree in the graph: 3Adjacency matrix: [[0, 1, 1, 1, 0] [0, 0, 1, 1, 0] [0, 0, 0, 0, 1] [0, 0, 0, 0, 1] [0, 0, 0, 0, 0]]
You can obtain the adjacent vertices of a given vertex using the function neighbors(vid, mode=ALL). If we consider vertex 0, the adjacent vertices or neighbours will be vertices 1, 2 and 3.
print(g.neighbors(0, mode=ALL))
To perform a breadth-first search starting from a vertex, you can use the function bfs(vid, mode=OUT).
print(g.bfs(0)[0])
The vertex IDs returned will be [0, 1, 2, 3, 4].
You can obtain the shortest paths from a given vertex using the function get_shortest_paths(vid). You want to specify the destination vertex as get_shortest_paths(vid, to=destination).
print(g.get_shortest_paths(0))
The above line will result in all the shortest paths to all the vertices starting from vertex 0 which will be [[0], [0, 1], [0, 2], [0, 3], [0, 2, 4]].
print(g.get_shortest_paths(0, to=4))
The above line will return the shortest paths from vertex 0 to vertex 4 which is [[0, 2, 4]].
You can obtain the Laplacian matrix of the graph using the laplacian() function.
print("Laplacian matrix of a graph:\n",g.laplacian())
The output will be as follows.
Laplacian matrix of a graph: [[3, -1, -1, -1, 0], [0, 2, -1, -1, 0], [0, 0, 1, 0, -1], [0, 0, 0, 1, -1], [0, 0, 0, 0, 0]]
Let us assume that the source vertex as vertex 0 and the target vertex as vertex 4 in our example. We can determine the maximum flow and the minimal cut (according to the max-flow min-cut theorem) between the source and target using the function maxflow(source, target, weights).
maxflow = g.maxflow(0,4,weights)print(maxflow.value)print(maxflow.flow)print(maxflow.cut)print(maxflow.partition)
The above line will output a Graph flow object with the maximum value of the flow as 13, the flow values [4.0, 6.0, 3.0, 0.0, 6.0, 4.0, 9.0] for each vertex, the minimal cut on the edge ids [5, 6] and the partition between vertices as [[0, 1, 2, 3], [4]].
Figure 3 denotes the values related to the maximal flow and minimal cut with the cut marked in purple colour. The values in purple on the edges are the flow values. We can see that two partitions are formed by the cut with vertices 0, 1, 2 and 3 in one partition and vertex 4 in the other partition.
You can read more about graph algorithms from my article 10 Graph Algorithms Visually Explained.
medium.com
If you come across a function that you do not know how to use, you can simply print its docstring which will have a description of the function’s inputs, outputs and what it does. For example,
print(g.bfs.__doc__)print(g.laplacian.__doc__)print(g.maxflow.__doc__)
Personally, I find the python-igraph to be a very useful module in my work. You can easily represent graphs and perform different analysis tasks using the provided functions.
I have attached the jupyter notebook containing all the examples and code I have used in this article. Feel free to play around with it and hope you can make use of igraph in your work as well.
Thank you for reading!
Cheers!
[1] Python-igraph manual at https://igraph.org/python/doc/igraph-module.html
[2] The example graph was adapted from https://www.youtube.com/watch?v=u6FkNw16VJA