Temporal Network Visualizations with Manim¶
Prerequisites¶
First, we need to set up our Python environment that has PyTorch, PyTorch Geometric and PathpyG installed. Depending on where you are executing this notebook, this might already be (partially) done. E.g. Google Colab has PyTorch installed by default so we only need to install the remaining dependencies. The DevContainer that is part of our GitHub Repository on the other hand already has all of the necessary dependencies installed.
In the following, we install the packages for usage in Google Colab using Jupyter magic commands. For other environments comment in or out the commands as necessary. For more details on how to install pathpyG
especially if you want to install it with GPU-support, we refer to our documentation. Note that %%capture
discards the full output of the cell to not clutter this tutorial with unnecessary installation details. If you want to print the output, you can comment %%capture
out.
%%capture
# !pip install torch
!pip install torch_geometric
!pip install git+https://github.com/pathpy/pathpyG.git
Note that using the Manim
-backend in PathpyG
requires the installation of Manim
. It will not be automatically installed with PathpyG
due to its additional dependencies. We recommend using the installation instructions in the Manim
documentation or our provided DevContainer.
Motivation and Learning Objectives¶
While you already learned how to visualise graphs with PathpyG
in the interactive graph visualisation tutorial, those visualisations mostly considered static graphs.
In this tutorial, you will learn how to use the Manim
backend in PathpyG
to generate videos (.mp4
) or animations (.gif
) of temporal graphs.
Let's Get Started¶
We need to import PathpyG
first:
import pathpyG as pp
Next, we can create a temporal graph that we want to visualise:
t = pp.TemporalGraph.from_edge_list(
[
("a", "b", 1),
("b", "c", 5),
("c", "d", 9),
("d", "a", 9),
("a", "b", 10),
("b", "c", 10),
("a", "b", 8),
("b", "c", 13),
("c", "d", 17),
("d", "a", 19),
("a", "b", 20),
("b", "c", 18),
]
)
The plot
function using Manim as backend allows to use a variety of customization options to visualize temporal graphs and outputs a video. Some examples are provided below, e.g. the node_size
or the edge_size
.
pp.plot(t, backend="manim", node_size=0.3, edge_size=4, edge_color=["red", "blue"], node_color=0.89, node_label="Node")
100%|██████████| 21/21 [00:29<00:00, 1.39s/it]
<pathpyG.visualisations.network_plots.TemporalNetworkPlot at 0x7f3499c50950>
The videos can be exported as .mp4
or .gif
if you provide a filename to the plot
function.
pp.plot(
t,
backend="manim",
node_size=0.3,
edge_size=4,
edge_color=["red", "blue"],
node_color=0.89,
node_label="Node",
filename="tutorial_plot.gif",
)
100%|██████████| 21/21 [00:31<00:00, 1.48s/it]
<pathpyG.visualisations.network_plots.TemporalNetworkPlot at 0x7f349995ccd0>
Dynamically Changing Customisations¶
So far, we only used customisations that you were already familiar with from other plotting backends. Manim offers four additional customisations:
Both node and edge colors can be specified for single time stamps with the
node_color
andedge_color
keyword arguments.e.g. :
node_color = {'a-1.0': 'yellow', 'a': 'green', 'b-3.0':'black'}
, where the keysnode_id-time_stamp
specify the node and the time stamp and the values the colors. If no time stamp is specified the first time stamp of the temporal graph is used.e.g. :
edge_color = {'a-b-1.0':'purple', 'd-c-4.0':'green'}
, where the keysnode_id_1-node_id_2-time_stamp
specify the nodes and the time stamp and the values the colorsAdditionally, the user can specify after how many time steps the layout is recalculated with the Fruchtermann Rheingold algorithm based on the edges that existed in the last interval with the
dynamic_layout_interval
keyword argument. Additionally the user can specify based on how many timesteps backwards and forwards the new layout is calculated with the keyword argumentslook_forward
andlook_behind
The background color can be changed with the
background_color
keyword argumentThe font size of the node labels is adjustable with the
font_size
keyword argument.
The following shows an example where all of the customisations described above are used:
pp.plot(
t,
backend="manim",
node_size=0.1,
edge_size=4,
edge_color={"a-b-1.0": "purple", "b-c-10.0": "green"},
node_color={"a-1.0": "yellow", "a": "green", "b-3.0": "black"},
node_label=t.mapping.node_ids.tolist(),
font_size=40,
dynamic_layout_interval=5,
)
100%|██████████| 21/21 [00:28<00:00, 1.36s/it]
<pathpyG.visualisations.network_plots.TemporalNetworkPlot at 0x7f3499a02250>
Real-World Example¶
As a final example, we show how to visualise a real-world temporal graph with Manim
. We use Netschleuder Online Repository (see our next tutorial our next tutorial Graph Learning in Netzschleuder Data for more information) to obtain a temporal interaction graph between baboons and color the types of interactions in different colors.
g = pp.io.read_netzschleuder_graph('sp_baboons', 'observational', time_attr='time')
colors = []
for category in g.data['edge_category']:
match category:
case 'Affiliative': colors.append('red')
case 'Agonistic': colors.append('green')
case 'Other': colors.append('grey')
pp.plot(
g,
backend="manim",
start=1560412200,
end=1560431041,
intervals=20,
dynamic_layout_interval=50,
edge_color=colors,
node_size=0.06,
edge_size=5,
node_label_size=20,
)
100%|██████████| 21/21 [00:38<00:00, 1.83s/it]
<pathpyG.visualisations.network_plots.TemporalNetworkPlot at 0x7f3670144dd0>