Skip to content

docs: add personalized PageRank on a grid tutorial #821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 31, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions doc/examples_sphinx-gallery/personalized_pagerank.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
"""
.. _tutorials-personalized_pagerank:

===============================
Personalized PageRank on a grid
===============================

This example demonstrates how to calculate and visualize personalized PageRank on a grid. We use the :meth:`igraph.Graph.personalized_pagerank` method, and demonstrate the effects on a grid graph.
"""

# %%
# .. note::
#
# The PageRank score of a vertex reflects the probability that a random walker will be at that vertex over the long run. At each step the walker has a 1 - damping chance to restart the walk and pick a starting vertex according to the probabilities defined in the reset vector.

import igraph as ig
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import numpy as np

# %%
# We define a function that plots the graph on a Matplotlib axis, along with
# its personalized PageRank values. The function also generates a
# color bar on the side to see how the values change.
# We use `Matplotlib's Normalize class <https://matplotlib.org/stable/api/_as_gen/matplotlib.colors.Normalize.html>`_
# to set the colors and ensure that our color bar range is correct.


def plot_pagerank(graph: ig.Graph, p_pagerank: list[float]):
"""Plots personalized PageRank values on a grid graph with a colorbar.

Parameters
----------
graph : ig.Graph
graph to plot
p_pagerank : list[float]
calculated personalized PageRank values
"""
# Create the axis for matplotlib
_, ax = plt.subplots(figsize=(8, 8))

# Create a matplotlib colormap
# coolwarm goes from blue (lowest value) to red (highest value)
cmap = cm.coolwarm

# Normalize the PageRank values for colormap
normalized_pagerank = ig.rescale(p_pagerank)

graph.vs["color"] = [cmap(pr) for pr in normalized_pagerank]
graph.vs["size"] = ig.rescale(p_pagerank, (20, 40))
graph.es["color"] = "gray"
graph.es["width"] = 1.5

# Plot the graph
ig.plot(graph, target=ax, layout=graph.layout_grid())

# Add a colorbar
sm = cm.ScalarMappable(norm=plt.Normalize(min(p_pagerank), max(p_pagerank)), cmap=cmap)
plt.colorbar(sm, ax=ax, label="Personalized PageRank")

plt.title("Graph with Personalized PageRank")
plt.axis("equal")
plt.show()


# %%
# First, we generate a graph, e.g. a Lattice Graph, which basically is a ``dim x dim`` grid:
dim = 5
grid_size = (dim, dim) # dim rows, dim columns
g = ig.Graph.Lattice(dim=grid_size, circular=False)

# %%
# Then we initialize the ``reset_vector`` (it's length should be equal to the number of vertices in the graph):
reset_vector = np.zeros(g.vcount())

# %%
# Then we set the nodes to prioritize, for example nodes with indices ``0`` and ``18``:
reset_vector[0] = 1
reset_vector[18] = 0.65

# %%
# Then we calculate the personalized PageRank:
personalized_page_rank = g.personalized_pagerank(damping=0.85, reset=reset_vector)

# %%
# Finally, we plot the graph with the personalized PageRank values:
plot_pagerank(g, personalized_page_rank)


# %%
# Alternatively, we can play around with the ``damping`` parameter:
personalized_page_rank = g.personalized_pagerank(damping=0.45, reset=reset_vector)

# %%
# Here we can see the same plot with the new damping parameter:
plot_pagerank(g, personalized_page_rank)
Loading