Skip to content
Merged
Changes from 1 commit
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
81 changes: 81 additions & 0 deletions doc/examples_sphinx-gallery/personalized_pagerank.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""
.. _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.GraphBase.personalized_pagerank` method, and demonstrate the effects on a grid graph.
Comment thread
BeaMarton13 marked this conversation as resolved.
Outdated
"""

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

import igraph as ig


# %%
# 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.show()
Comment on lines +56 to +63
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make the plot not be stretched vertically or horizontally. Something like plt.axis("equal") can achieve this.



# %%
# 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 ``6``:
reset_vector[0] = 1
reset_vector[6] = 1
Copy link
Copy Markdown
Member

@szhorvat szhorvat Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's choose two nodes that are a bit further from each other, and give one of them a higher weight than the other. This will make a more interesting plot.

Alternatively, use the reset_vertices parameter and pass in the vertices. They will have equal weights in this case.

It's your choice which pattern you demonstrate.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ntamas In IGraph/M I allow reset_vertices to be a dictionary. They keys are vertices and the values are reset weights. What do you think about implementing the same for python-igraph, assuming that @BeaMarton13 is interested in doing it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely, we can try to do it.


# %%
# Then we calculate the personalized PageRank:
personalized_page_rank = g.personalized_pagerank(weights=None, damping=0.85, reset=reset_vector)
Copy link
Copy Markdown
Member

@szhorvat szhorvat Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove weights here since there are no weights to think about. You can choose to tune the damping to make the plot look more interesting. Even if you leave it at the default of 0.85, do keep the damping parameter, as this is something people may want to play with.

You could even choose to show two plots with two different damping values, to illustrate the effect of this parameter.


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