Run in Google Colab
|
View on GitHub
|
Visualizing networks¶
Let's showcase a few ways you can visualize networks using the igraph library. Let's first import a few libraries:
import igraph as ig
import numpy as np
Now let's load one of the networks in the Datasets/Networks folder. Let's load the EUPowerGrid network, which is a network of the European power grid.
We are going to use the simplify() function to remove self-loops and multiple edges, which is a common preprocessing step for network analysis.
# Loading EUPowerGrid network
g_power = ig.Graph.Read_GML("../../Datasets/Networks/EUPowerGrid.gml").simplify() # adjust the path as needed.
Let's see the attributes of the network:
# Node attributes
print(g_power.vertex_attributes())
['id', 'name', 'Country']
We can calculate the layout using the layout function. Let's start with the circle layout with the order defined by the degree of the nodes.
Note that the default plot function from igraph needs you to install cairo. However this library can be a bit tricky to install on some systems. So I will offer here an alternative way to plot the network using matplotlib.
# Size of node changes with degree
node_degrees = np.array(g_power.degree())
layout = g_power.layout("circle",order=node_degrees.argsort())
# Plotting using the cairo backend (requires cairo installed)
# ig.plot(g_power,
# layout=layout,
# vertex_size=node_degrees,
# )
Here is a nice matplotlib function to plot the network.
import matplotlib.pyplot as plt
import numpy as np
def plot_igraph_with_matplotlib(
g,
layout,
node_size=300,
node_color="skyblue",
node_alpha=1.0,
edge_color="gray",
edge_width=1.0,
edge_alpha=0.7,
with_labels=False,
label_attr="label",
label_font_size=10,
label_color="black",
figsize=(6, 6),
dpi=100,
axis_off=True
):
"""
Draw an igraph Graph `g` using matplotlib, given `layout`.
Parameters
----------
g : igraph.Graph
The graph to draw.
layout : Layout or sequence of (x, y)
An igraph Layout object or list/array of coordinate pairs.
node_size : float
Size of the nodes (passed to plt.scatter `s`).
node_color : color or list of colors
Node face color.
node_alpha : float
Node transparency (0.0 transparent, 1.0 opaque).
edge_color : color
Color for all edges.
edge_width : float
Line width for edges.
edge_alpha : float
Edge transparency.
with_labels : bool
Whether to draw vertex labels.
label_attr : str
Vertex attribute name to use for labels; if absent, vertex indices used.
label_font_size : float
Font size for labels.
label_color : color
Color for label text.
figsize : tuple
Matplotlib figure size.
dpi : int
Figure DPI.
axis_off : bool
If True, hides axes.
"""
# extract coordinates as an (N,2) array
coords = np.array(layout.coords) if hasattr(layout, "coords") else np.array(layout)
xs, ys = coords[:, 0], coords[:, 1]
fig, ax = plt.subplots(figsize=figsize, dpi=dpi)
# draw edges
for src, tgt in g.get_edgelist():
x0, y0 = coords[src]
x1, y1 = coords[tgt]
ax.plot(
[x0, x1],
[y0, y1],
color=edge_color,
linewidth=edge_width,
alpha=edge_alpha,
zorder=1
)
# draw nodes
ax.scatter(
xs,
ys,
s=node_size,
c=node_color,
alpha=node_alpha,
zorder=2,
edgecolors="black"
)
# draw labels
if with_labels:
if label_attr in g.vs.attribute_names():
labels = g.vs[label_attr]
else:
labels = [str(i) for i in range(g.vcount())]
for idx, label in enumerate(labels):
ax.text(
xs[idx],
ys[idx],
label,
fontsize=label_font_size,
color=label_color,
ha="center",
va="center",
zorder=3
)
if axis_off:
ax.set_axis_off()
plt.tight_layout()
plt.show()
# Size of node changes with degree
node_degrees = np.array(g_power.degree())
layout = g_power.layout("circle",order=node_degrees.argsort())
# using the custom plotting function
plot_igraph_with_matplotlib(
g_power,
layout=layout,
node_size=node_degrees * 20, # Scale node size by degree
edge_alpha=0.05
)
Let's try another layout, the Fruchterman-Reingold layout, which is a force-directed layout. This layout is often used for visualizing networks as it tends to spread out the nodes nicely. We can color the nodes based on the country they belong to.
# color countries
from collections import Counter
import matplotlib as mpl
country2Index = {country:index for index,(country,_) in enumerate(Counter(g_power.vs["Country"]).most_common(10))}
countryColors = [mpl.cm.tab10(country2Index[country]) if country in country2Index else "#888888" for country in g_power.vs["Country"]]
# Size of node changes with degree
node_degrees = np.array(g_power.degree())
layout = g_power.layout("fruchterman_reingold", niter= 2000)
# Other supported layouts: drl, davidson_harel, circle, kamada_kawai, fruchterman_reingold, graphopt, mds
# ig.plot(g_power,
# layout=layout,
# vertex_size=node_degrees,
# vertex_color=countryColors
# )
# custom plotting with matplotlib
plot_igraph_with_matplotlib(
g_power,
layout=layout,
node_size=node_degrees * 20, # Scale node size by degree
node_color=countryColors,
figsize=(10, 10)
)
Using Helios-Web¶
You can try other layouts on igraph. However if you want to try more advanced visualizations, you can use Helios-Web. Helios-Web is a web-based visualization tool that allows you to visualize networks in a more interactive way. You can upload your network and try different layouts and styles.
First you need to save the network to the .xnet format or .gml format.
You may need to install the xnetwork package to save the network in the .xnet format. You can install it using pip:
pip install xnetwork
import xnetwork as xn
xn.save(g_power, "EUPowerGrid.xnet")
Now open a browser window and drag and drop the .xnet file into the Helios-Web interface. From the bottom menus you can select different attributes.
go to: https://heliosweb.io/docs/example/?advanced&dark
We are still working on the Helios-Web interface, so there are no controllers for the layout yet. If you know javascript, you can use helios-web as a library to create your own visualizations.
More information on how to use Helios-Web can be found in the Helios-Web documentation.
Exercises¶
Find the best layout for the EU power grid network.
Hint: Check documentation for layouts in https://igraph.org/python/api/latest/igraph._igraph.GraphBase.html#layout_fruchterman_reingold
Load a network from the Networks folder, explore it, and create a visualization
Run in Google Colab
View on GitHub