Skip to main content

LAGO

Dynamic Community Detection for Temporal Networks

PyPI version License: MIT Python 3.11+

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.

Temporal communities example
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_modules is deterministic: the same input and parameters give the same modules, in any process. seed selects the exploration order, nb_iter tries several orders and keeps the best, and n_jobs runs 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_name is "cython" or "python" for the metric kernel. LAGO_CORE=python forces the pure sources. In a checkout, python setup.py build_ext --inplace builds 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

📁 Examples (examples/)

💡 Practical Guides

The examples are Jupyter notebooks (Getting Started is a page); run jupyter notebook in the examples folder.

📄 Papers

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)

Source distribution for dcd-lago 1.2.0
File Size Uploaded
dcd_lago-1.2.0.tar.gz 1.6 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for dcd-lago 1.2.0
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

1.2.0 This release

3 release files

1.1.0

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page