igraph

This Jupyter notebook provides an example of using the Python packages gravis and igraph. The .ipynb file can be found here.

References

Installation

  • With pip: pip install igraph

  • With conda: conda install -c conda-forge igraph

Import

[1]:
import os

import igraph as ig

import gravis as gv

Quick start

[2]:
def assign_properties(g):
    # Centrality calculation
    node_centralities = g.betweenness()
    edge_centralities = g.edge_betweenness()

    # Community detection
    communities = g.community_fastgreedy().as_clustering().membership

    # Graph properties
    g['node_border_size'] = 1.5
    g['node_border_color'] = 'black'
    g['edge_opacity'] = 0.75

    # Node properties: Size by centrality, color by community
    colors = ['red', 'blue', 'green', 'orange', 'pink', 'brown', 'yellow', 'cyan', 'magenta', 'violet']
    g.vs['size'] = [10.0 + val / 50.0 for val in node_centralities]
    g.vs['color'] = [colors[community_index % len(colors)] for community_index in communities]

    # Edge properties: Size by centrality, color by community (within=community color, between=black)
    g.es['size'] = [0.5 + val / 100.0 for val in edge_centralities]
    g.es['color'] = [colors[communities[i] % len(colors)] if communities[i] == communities[j] else 'black'
                     for i, j in g.get_edgelist()]


# Create a graph with a generator function
g = ig.Graph.GRG(200, 0.14)

# Scale the coordinates provided by this particular graph generator (alternative: delete them)
g.vs['x'] = [val * 2000 - 1000 for val in g.vs['x']]  # del g.vs['x']
g.vs['y'] = [val * 2000 - 1000 for val in g.vs['y']]  # del g.vs['y']

# Assign properties
assign_properties(g)

# Plot it
gv.d3(g, zoom_factor=0.2)
[2]:
Details for selected element
General
App state
Display mode
Export
Data selection
Graph
Node label text
Edge label text
Node size
Minimum
Maximum
Edge size
Minimum
Maximum
Nodes
Visibility
Size
Scaling factor
Position
Drag behavior
Hover behavior
Node images
Visibility
Size
Scaling factor
Node labels
Visibility
Size
Scaling factor
Rotation
Angle
Edges
Visibility
Size
Scaling factor
Form
Curvature
Hover behavior
Edge labels
Visibility
Size
Scaling factor
Rotation
Angle
Layout algorithm
Simulation
Many-body force
Strength
Theta
Min
Max
Links force
Collision force
Radius
Strength
x-positioning force
Strength
y-positioning force
Strength
Centering force

Graph construction

1) Manual graph construction

1a) Graph (with directed=False)

undirected, with self-loops, with parallel edges, with attributes

[3]:
ug = ig.Graph(directed=False)


# Node with automatic id (starts from 0)
ug.add_vertex()

# Node with user-defined id (=only a synonym, also gets an automatic id!)
ug.add_vertex(name='b')

# Node + attribute
ug.add_vertex(name='c', size=20)

# Node + attributes
ug.add_vertex(name='d', size=30, color='orange')


# Nodes
ug.add_vertices(2)           # argument: number of nodes with automatic ids
ug.add_vertices('g')         # argument: user-defined id (also gets an automatic id)
ug.add_vertices(['h', 'i'])  # argument: iterable of user-defined ids (also get automatic ids)


# Edge (nodes need to already exist)
ug.add_edge(0, 1)
ug.add_edge('b', 'c')

# Edge + attribute
ug.add_edge('c', 'd', size=3)

# Edge + attributes
ug.add_edge('d', 4, size=4, color='orange')


# Edges
ug.add_edges([
    (4, 5),
    (5, 'g'),
    ('g', 'h'),
    ('h', 'i'),
    (8, 0),
    (0, 0),
    (0, 0),
    (0, 1),
    (0, 1),
])


gv.d3(ug, graph_height=200)
[3]:
Details for selected element
General
App state
Display mode
Export
Data selection
Graph
Node label text
Edge label text
Node size
Minimum
Maximum
Edge size
Minimum
Maximum
Nodes
Visibility
Size
Scaling factor
Position
Drag behavior
Hover behavior
Node images
Visibility
Size
Scaling factor
Node labels
Visibility
Size
Scaling factor
Rotation
Angle
Edges
Visibility
Size
Scaling factor
Form
Curvature
Hover behavior
Edge labels
Visibility
Size
Scaling factor
Rotation
Angle
Layout algorithm
Simulation
Many-body force
Strength
Theta
Min
Max
Links force
Collision force
Radius
Strength
x-positioning force
Strength
y-positioning force
Strength
Centering force

1b) Graph (with directed=True)

undirected, with self-loops, with parallel edges, with attributes

[4]:
dg = ig.Graph(directed=True, edges=[(e.source, e.target) for e in ug.es])

gv.d3(dg, graph_height=200)
[4]:
Details for selected element
General
App state
Display mode
Export
Data selection
Graph
Node label text
Edge label text
Node size
Minimum
Maximum
Edge size
Minimum
Maximum
Nodes
Visibility
Size
Scaling factor
Position
Drag behavior
Hover behavior
Node images
Visibility
Size
Scaling factor
Node labels
Visibility
Size
Scaling factor
Rotation
Angle
Edges
Visibility
Size
Scaling factor
Form
Curvature
Hover behavior
Edge labels
Visibility
Size
Scaling factor
Rotation
Angle
Layout algorithm
Simulation
Many-body force
Strength
Theta
Min
Max
Links force
Collision force
Radius
Strength
x-positioning force
Strength
y-positioning force
Strength
Centering force

Assign attributes to a created graph

[5]:
g = ig.Graph(directed=False, edges=[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 0)])

Graph attributes

[6]:
g['background_color'] = 'gray'
g['node_shape'] = 'rectangle'
g['node_label_color'] = 'white'
g['edge_opacity'] = 0.3

Node attributes

[7]:
# Nodes
num_nodes = len(g.vs)
g.vs['size'] = [5 + i*5 for i in range(num_nodes)]
g.vs['color'] = ['lightblue'] * num_nodes

# Node
g.vs[3]['color'] = 'darkred'
g.vs[3]['shape'] = 'hexagon'
g.vs[3]['size'] = 40
g.vs[3]['opacity'] = 0.3

Edge attributes

[8]:
# Edges
num_edges = len(g.es)
g.es['size'] = [1 + i for i in range(num_edges)]
g.es['color'] = ['lightgreen'] * num_edges

# Edge
g.es[3]['size'] = 1
g.es[3]['color'] = 'darkred'
[9]:
gv.d3(g, graph_height=200, use_centering_force=False)
[9]:
Details for selected element
General
App state
Display mode
Export
Data selection
Graph
Node label text
Edge label text
Node size
Minimum
Maximum
Edge size
Minimum
Maximum
Nodes
Visibility
Size
Scaling factor
Position
Drag behavior
Hover behavior
Node images
Visibility
Size
Scaling factor
Node labels
Visibility
Size
Scaling factor
Rotation
Angle
Edges
Visibility
Size
Scaling factor
Form
Curvature
Hover behavior
Edge labels
Visibility
Size
Scaling factor
Rotation
Angle
Layout algorithm
Simulation
Many-body force
Strength
Theta
Min
Max
Links force
Collision force
Radius
Strength
x-positioning force
Strength
y-positioning force
Strength
Centering force

2) Algorithmic graph construction

[10]:
n = 10

g = ig.Graph.Barabasi(10)
g = ig.Graph.Erdos_Renyi(50, 0.1)
g = ig.Graph.Watts_Strogatz(2, 3, 3, 0.1)

3) Graph loading from an internal collection

[11]:
g = ig.Graph.Atlas(22)
g = ig.Graph.Famous('Chvatal')

4) Graph import and export

Import

[12]:
# TODO

Export

[13]:
# TODO

Basic graph inspection

1) Graph and its properties

[14]:
print('Type:', type(g))
print('Directed:', g.is_directed())
Type: <class 'igraph.Graph'>
Directed: False

2) Nodes and their properties

[15]:
for node in g.vs:
    node_id = node.index
    attributes = node.attributes()
    degree = node.degree()
    print('Type:', type(node), type(attributes))
    print('Id:', node_id)
    print('Attributes:', attributes)
    print('Degree:', degree)
    break
Type: <class 'igraph.Vertex'> <class 'dict'>
Id: 0
Attributes: {}
Degree: 4

3) Edges and their properties

[16]:
for edge in g.es:
    source = edge.source
    target = edge.target
    attributes = edge.attributes()
    print('Type:', type(source), type(target), type(attributes))
    print('Source:', source)
    print('Target:', target)
    print('Attributes:', )
    break
Type: <class 'int'> <class 'int'> <class 'dict'>
Source: 5
Target: 6
Attributes:
[17]:
edge_list = g.get_edgelist()
edge_list[0:3]
[17]:
[(5, 6), (6, 7), (7, 8)]

Calculating graph measures and metrics

1) Quantitative measures

[18]:
g.degree()
g.betweenness()
g.edge_betweenness()
g.pagerank()

# TODO: more measures are available
[18]:
[0.08333333333333333,
 0.08333333333333334,
 0.08333333333333334,
 0.08333333333333333,
 0.08333333333333333,
 0.08333333333333333,
 0.08333333333333334,
 0.08333333333333334,
 0.08333333333333334,
 0.08333333333333333,
 0.08333333333333333,
 0.08333333333333334]

2) Structure inference

Community detection and graph partitioning

[19]:
g = ig.Graph.GRG(40, 0.4)

# based on the betweenness of the edges in the network
g.community_edge_betweenness()

# Greedily maximize the modularity score of the graph - Clauset, Newman, Moore
g.community_fastgreedy()

# Infomap method of Rosvall and Bergstrom
g.community_infomap()

# Label propagation method of Raghavan, Albert, Kumara
g.community_label_propagation()

# Newman's leading eigenvector method
g.community_leading_eigenvector()

# g.community_leading_eigenvector_naive()

# Multilevel algorithm of Blondel et al.
g.community_multilevel()

# Calculates the optimal modularity score with GNU Linear Programming Kit
g.community_optimal_modularity()

# Spinglass community detection method of Reichardt and Bornholdt
g.community_spinglass()

# Community detection algorithm of Latapy and Pons, based on random walks
g.community_walktrap()
[19]:
<igraph.clustering.VertexDendrogram at 0x7f0c04568690>

Graph visualization

Layout calculation

[20]:
# TODO

Plot

[21]:
# TODO