LAGO
Dynamic Community Detection for Temporal Networks
LAGO detects communities (modules) that evolve over time in fine-grained temporal networks (link streams). Unlike static methods, it finds groups that form, merge, split, and dissolve as interactions happen.
No time window needed. Traditional approaches require aggregating interactions into snapshots (e.g., daily or hourly networks), losing temporal precision and forcing you to choose an arbitrary window size. LAGO works directly on the raw timestamped data—no aggregation, no information loss.
A link stream with 5 nodes showing two dynamic communities (blue and green) that evolve over time.
Installation
pip install dcd-lago # Core library (no dependencies)
pip install dcd-lago[viz] # With visualization (numpy, pandas, matplotlib, scikit-learn)
Quick Start
from lago import LinkStream, lago_modules
# Create a temporal network
ls = LinkStream()
ls.add_links([
(0, 1, 0), (1, 2, 0), (0, 2, 0), # Triangle at t=0
(0, 1, 1), (1, 2, 1), # Path at t=1
(3, 4, 0), (3, 4, 1), (3, 4, 2), # Pair at t=0,1,2
(2, 3, 2), # Bridge at t=2
])
# Detect temporal communities
communities = lago_modules(ls)
# Explore results
for module in communities.iter_modules():
print(f"Community {module.label}: nodes {module.nodes}, duration {module.duration}")
Note: LAGO works on discrete integer timestamps. For best results, normalize your timestamps so that the smallest time gap is 1 (e.g., divide all timestamps by their GCD).
Features
| Feature | Description |
|---|---|
| Temporal precision | Handles exact timestamps, not time windows |
| Quality metric | Built-in Longitudinal Modularity scoring |
| Flexible input | Weighted, directed, delayed, continuous, and k-partite networks |
| Rich output | Track node trajectories, community evolution, and transitions |
| Visualization | Publication-ready longitudinal plots |
Usage Examples
Evaluate Community Quality
from lago import longitudinal_modularity
result = longitudinal_modularity(ls, communities, lex="MM")
print(f"Quality score: {result.value:.4f}")
Visualize Results
from lago.viz import LongitudinalModulesPlot
plot = LongitudinalModulesPlot(communities, linkstream=ls, width=1200, height=600)
plot.configure_nodes(auto_ordering=True)
plot.configure_edges(show_activity=True)
plot.configure_modules(color_palette="tab10")
plot.draw()
plot.save("communities.png", dpi=150)
Explore Results
# Track a specific node
trajectory = communities.get_node_trajectory(node=0)
print(f"Node 0 was in communities: {trajectory}")
# Get community membership at a specific time
membership = communities.get_nodes_modules_membership_at_time(time=1)
print(f"At t=1: {membership}")
# Save/load results
communities.to_json("results.json")
Key Parameters
lago_modules()
| Parameter | Default | Description |
|---|---|---|
lex |
"MM" |
Expectation type: "MM" (flexible) or "JM" (stable communities) |
omega |
2 |
Temporal smoothness (higher = fewer community switches) |
gamma |
1 |
Resolution (higher = smaller communities) |
refinement |
"STEM" |
Refinement strategy: None, "STNM", or "STEM" |
nb_iter |
1 |
Number of runs (keeps best result) |
seed |
None |
Exploration order to follow. Results are reproducible with or without it; different seeds reach different optima, which nb_iter exploits |
n_jobs |
1 |
Processes over which to spread the nb_iter runs (same result as 1; memory grows with it) |
longitudinal_modularity()
| Parameter | Default | Description |
|---|---|---|
lex |
"MM" |
Expectation type: "MM", "JM", or "CM" |
omega |
2.0 |
Weight for temporal penalty |
gamma |
1.0 |
Weight for expectation term |
ndigits |
5 |
Decimal places of the returned value |
Performance
Nothing to configure: pip install dcd-lago gives the fastest implementation your platform supports.
- From a binary wheel, the hot modules of the search and the metric's counting kernel come compiled (Cython). From a source install they are compiled when a C compiler is available and run as pure Python otherwise. Both give the same results, bit for bit — the pure-Python sources are the reference and ship alongside the compiled modules.
lago_modulesis deterministic: the same input and parameters give the same modules, in any process.seedselects the exploration order,nb_itertries several orders and keeps the best, andn_jobsruns those in parallel processes (memory and platform notes in the docstring).- To see what is running:
lago.accel.core_name()is"compiled"or"python",lago.accel.backend_nameis"cython"or"python"for the metric kernel.LAGO_CORE=pythonforces the pure sources. In a checkout,python setup.py build_ext --inplacebuilds the compiled modules next to the sources.
Against release 1.1.0: 8× (pure Python) to 12× (compiled) on small streams over every parameter combination, 6–109× on streams of 4k–96k interactions, JM at the speed of MM — see docs/BENCHMARK_PYPI_VS_CURRENT.md.
Documentation
📖 Guides
- Getting Started — Concepts and first steps
- API Reference — Complete function documentation
- Changelog — What changed in each release
- Performance notes — How the implementation is optimised and verified; the compiled build
📁 Examples (examples/)
- LinkStream Types — Weighted, directed, continuous, delayed, k-partite networks
- Community Detection — Using
lago_modulesand exploring results - Modularity — Computing and understanding quality scores
- Visualization — Creating publication-ready plots
💡 Practical Guides
- Real-World Preprocessing — Working with names and date strings
The examples are Jupyter notebooks (Getting Started is a page); run jupyter notebook in the examples folder.
📄 Papers
- LAGO Method (ICDM) — Algorithm details and experiments
- Longitudinal Modularity (EPJ Data Science) — Quality function theory
Citation
If you use LAGO in your research, please cite:
LAGO Method:
@INPROCEEDINGS{11391928,
author={Brabant, Victor and Bonifati, Angela and Cazabet, Rémy},
booktitle={2025 IEEE International Conference on Data Mining (ICDM)},
title={Discovering Communities in Continuous-Time Temporal Networks by Optimizing L-Modularity},
year={2025},
volume={},
number={},
pages={1065-1074},
keywords={Accuracy;Network analyzers;Benchmark testing;Market research;Data mining;Optimization;Guidelines;temporal networks;community detection;dynamic communities;link stream;modularity},
doi={10.1109/ICDM65498.2025.00115}}
Longitudinal Modularity:
@article{Brabant2025lmod,
title={Longitudinal modularity, a modularity for link streams},
author={Brabant, Victor and Asgari, Yasaman and Borgnat, Pierre and Bonifati, Angela and Cazabet, Rémy},
journal={EPJ Data Science},
volume={14},
number={1},
year={2025},
doi={10.1140/epjds/s13688-025-00529-x},
}
Contributing
Questions, suggestions, or issues? Please open a GitHub issue.
Acknowledgements
We thank Jean-Loup Guillaume for the discussions that helped improve this project.
License
MIT License — see LICENSE.txt
Metadata
Release files for dcd-lago 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dcd_lago-1.2.0.tar.gz | 1.6 MB | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dcd_lago-1.2.0-cp313-cp313-macosx_15_0_arm64.whl | CPython 3.13 | CPython 3.13 | macOS 15.0+ ARM64 | Details |
| dcd_lago-1.2.0-cp311-cp311-macosx_15_0_arm64.whl | CPython 3.11 | CPython 3.11 | macOS 15.0+ ARM64 | Details |
Total release size: 3.3 MB
Release files / dcd_lago-1.2.0.tar.gz
| Download URL | dcd_lago-1.2.0.tar.gz |
|---|---|
| Size | 1.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
35535c0376fbabf944ce124d6c66c6a3439a5986b3ddf5c8d19941d66a50e427
|
|
BLAKE2b-256 checksum How to use checksums |
415cf071d22943c89df760325daf4719644ebb82186bec9efe5e77d46f3ed8b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.11
|
Release files / dcd_lago-1.2.0-cp313-cp313-macosx_15_0_arm64.whl
| Download URL | dcd_lago-1.2.0-cp313-cp313-macosx_15_0_arm64.whl |
|---|---|
| Size | 882.9 kB |
| Tags | CPython 3.13 macOS 15.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
09207d746f7346a607acdcd1bd33122b7a3a00065c2cdd7fee4958299605ccb1
|
|
BLAKE2b-256 checksum How to use checksums |
d90d122e0e3300423496b764150a4909ab0d900fb8a0a9ae4ff6de546c7b382b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.11
|
Release files / dcd_lago-1.2.0-cp311-cp311-macosx_15_0_arm64.whl
| Download URL | dcd_lago-1.2.0-cp311-cp311-macosx_15_0_arm64.whl |
|---|---|
| Size | 873.3 kB |
| Tags | CPython 3.11 macOS 15.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
a93a1b70d3b856ea34b83d21af79ca996e6456f69e05b036e175afd0b8fb6074
|
|
BLAKE2b-256 checksum How to use checksums |
cd542ee041f42145e845cf730f313ba6756f00450e7adf358ba8a34d965af6c0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.11
|