10-Minute Tutorial: Getting Started with py3plex
This tutorial provides a quick introduction to py3plex, covering the most common tasks for working with multilayer networks.
What You Will Learn
In 10 minutes, you will learn how to:
Create and load multilayer networks
Perform basic network analysis
Compute multilayer statistics
Detect communities
Perform random walks for embeddings
Visualize networks
Prerequisites
Make sure py3plex is installed:
pip install git+https://github.com/SkBlaz/py3plex.git
1. Creating Your First Multilayer Network (2 minutes)
Start by creating a simple multilayer network from scratch:
from py3plex.core import multinet
# Create a new multilayer network
network = multinet.multi_layer_network()
# Add edges within layers (this automatically creates nodes)
# Format: [source_node, source_layer, target_node, target_layer, weight]
network.add_edges([
['A', 'layer1', 'B', 'layer1', 1],
['B', 'layer1', 'C', 'layer1', 1],
['A', 'layer2', 'B', 'layer2', 1],
['B', 'layer2', 'D', 'layer2', 1]
], input_type="list")
# Display basic statistics
network.basic_stats()
Output:
Number of nodes: 5
Number of edges: 4
Number of unique nodes (as node-layer tuples): 5
Number of unique node IDs (across all layers): 4
Nodes per layer:
Layer 'layer1': 3 nodes
Layer 'layer2': 3 nodes
2. Loading Networks from Files (1 minute)
py3plex supports multiple input formats. Here is how to load from an edge list:
from py3plex.core import multinet
# Load from a multiedgelist file
# Format: source target layer
network = multinet.multi_layer_network().load_network(
"datasets/multiedgelist.txt",
input_type="multiedgelist",
directed=False
)
# Check what we loaded
network.basic_stats()
Output:
Number of nodes: 5
Number of edges: 4
Number of unique nodes (as node-layer tuples): 5
Number of unique node IDs (across all layers): 5
Nodes per layer:
Layer '1': 3 nodes
Layer '2': 2 nodes
Supported formats:
multiedgelist- source, target, layeredgelist- simple source, target pairsgpickle- NetworkX pickle formatgml,graphml- standard graph formats
3. Exploring Network Structure (2 minutes)
Iterate Through Nodes and Edges
# Loop through all nodes
print("Nodes:")
for node in network.get_nodes(data=True):
print(node)
# Loop through all edges
print("\nEdges:")
for edge in network.get_edges(data=True):
print(edge)
# Get neighbors of a specific node in a layer
node_of_interest = "1"
layer_id = "1"
neighbors = list(network.get_neighbors(node_of_interest, layer_id=layer_id))
print(f"\nNeighbors of {node_of_interest} in layer {layer_id}:", neighbors)
Output (first few items):
Nodes (first 5):
(('1', '1'), {'type': '1'})
(('2', '1'), {'type': '1'})
(('6', '2'), {'type': '2'})
(('3', '1'), {'type': '1'})
(('5', '2'), {'type': '2'})
Edges (first 5):
(('1', '1'), ('2', '1'), {'weight': '1'})
(('1', '1'), ('3', '1'), {'weight': '1'})
(('2', '1'), ('6', '2'), {'weight': '1'})
(('3', '1'), ('5', '2'), {'weight': '1'})
Neighbors of 1 in layer 1: [('2', '1'), ('3', '1')]
Extract Subnetworks
# Extract a single layer
layer_1 = network.subnetwork(['1'], subset_by="layers")
print("Layer 1 nodes:", list(layer_1.get_nodes()))
# Extract specific nodes
node_subset = network.subnetwork(['1', '2'], subset_by="node_names")
print("Node subset:", list(node_subset.get_nodes()))
# Extract specific node-layer pairs
specific_pairs = network.subnetwork(
[('1', '1'), ('2', '1')],
subset_by="node_layer_names"
)
print("Specific pairs:", list(specific_pairs.get_nodes()))
Output:
Layer 1 nodes: 3 nodes
Node subset: 2 node-layer pairs
Specific pairs: [('2', '1'), ('1', '1')]
4. Computing Network Metrics (2 minutes)
Basic Centrality Measures
# Get a single layer as NetworkX graph
layer_1 = network.subnetwork(['1'], subset_by="layers")
# Compute degree centrality using NetworkX wrapper
degree_centrality = layer_1.monoplex_nx_wrapper("degree_centrality")
print("Degree centrality:", degree_centrality)
# Compute betweenness centrality
betweenness = layer_1.monoplex_nx_wrapper("betweenness_centrality")
print("Betweenness centrality:", betweenness)
Output (top nodes shown):
Degree centrality (first 5):
('1', '1'): 1.0000
('2', '1'): 0.5000
('3', '1'): 0.5000
Betweenness centrality (first 5):
('1', '1'): 1.0000
('2', '1'): 0.0000
('3', '1'): 0.0000
Multilayer Centrality
For multilayer-specific centrality measures:
from py3plex.algorithms.multilayer_algorithms.centrality import MultilayerCentrality
# Initialize centrality calculator
calc = MultilayerCentrality(network)
# Compute multilayer degree centrality (considers node participation across layers)
ml_degree = calc.overlapping_degree_centrality(weighted=False)
print("Multilayer degree centrality:", ml_degree)
# Compute multilayer betweenness centrality
ml_betweenness = calc.multilayer_betweenness_centrality()
print("Multilayer betweenness centrality:", ml_betweenness)
Output (top nodes shown):
Multilayer degree centrality (first 5):
1: 2.0000
2: 1.0000
3: 1.0000
5: 0.0000
6: 0.0000
Multilayer betweenness centrality (first 5):
('1', '1'): 0.6667
('2', '1'): 0.5000
('3', '1'): 0.5000
('6', '2'): 0.0000
('5', '2'): 0.0000
5. Multilayer Network Statistics (2 minutes)
py3plex provides many specialized statistics for analyzing multilayer networks. Here are the most commonly used:
Basic Layer Statistics
from py3plex.algorithms.statistics import multilayer_statistics as mls
# Measure how densely connected each layer is
density_layer1 = mls.layer_density(network, 'layer1')
density_layer2 = mls.layer_density(network, 'layer2')
print(f"Layer 1 density: {density_layer1:.3f}")
print(f"Layer 2 density: {density_layer2:.3f}")
# Measure diversity across layers
entropy = mls.entropy_of_multiplexity(network)
print(f"Layer diversity (entropy): {entropy:.3f} bits")
Output:
Layer 1 density: 0.667
Layer 2 density: 0.000
Layer diversity (entropy): 0.000 bits
Node-Level Statistics
# Compute node activity (how many layers a node participates in)
activity = mls.node_activity(network, node='1')
print(f"Node activity for node 1: {activity:.3f}")
Output:
Node activity for node 1: 0.500
Network-Level Statistics
# Measure how much layers differ in structure (edge overlap)
edge_overlap_value = mls.edge_overlap(network, 'layer1', 'layer2')
print(f"Edge overlap between layers: {edge_overlap_value:.3f}")
# Measure layer similarity using Jaccard index
jaccard = mls.layer_similarity(network, 'layer1', 'layer2', method='jaccard')
print(f"Jaccard similarity between layers: {jaccard:.3f}")
Output:
Edge overlap between layers: 0.000
Jaccard similarity between layers: 0.000
Available statistics:
See the py3plex.algorithms.statistics.multilayer_statistics module for all available statistics including:
layer_density- Density of edges within a layerentropy_of_multiplexity- Diversity across layersnode_activity- Number of layers a node participates inedge_overlap- Edge overlap between layerslayer_similarity- Similarity between layers (Jaccard, Pearson, etc.)algebraic_connectivity- Connectivity measure from Laplaciancommunity_participation_coefficient- How communities span layersinterdependence- Layer interdependence measuremultilayer_clustering_coefficient- Clustering in multilayer contextmultiplex_betweenness_centrality- Betweenness in multiplex networksmultiplex_closeness_centrality- Closeness in multiplex networksAnd more…
6. Community Detection (2 minutes)
py3plex provides Louvain-based community detection that works across multiple layers:
from py3plex.algorithms.community_detection.multilayer_modularity import (
louvain_multilayer
)
# Detect communities using multilayer Louvain
partition = louvain_multilayer(
network,
gamma=1.0, # Resolution parameter
omega=1.0, # Inter-layer coupling
random_state=42 # For reproducibility
)
# Examine results
print("Number of communities:", len(set(partition.values())))
print("\nNode assignments (first 10):")
for node, community in list(partition.items())[:10]:
print(f" Node {node}: Community {community}")
# Count community sizes
from collections import Counter
community_sizes = Counter(partition.values())
print("\nCommunity sizes:", dict(community_sizes))
Output:
Number of communities: 3
Node assignments (first 10):
Node ('1', '1'): Community 0
Node ('2', '1'): Community 0
Node ('6', '2'): Community 1
Node ('3', '1'): Community 0
Node ('5', '2'): Community 2
Community sizes (top 5): {0: 3, 1: 1, 2: 1}
Note: The louvain_multilayer function performs community detection across all layers simultaneously, taking into account both intra-layer and inter-layer connections. Parameters:
gamma: Resolution parameter (higher values = more communities)omega: Inter-layer coupling strength (higher values = more consistency across layers)random_state: Seed for reproducibility
7. Random Walks (1 minute)
Random walks are fundamental for graph embeddings (Node2Vec, DeepWalk) and analyzing network structure:
Basic Random Walk
from py3plex.algorithms.general.walkers import basic_random_walk
# Load a network
network = multinet.multi_layer_network().load_network(
"datasets/test.edgelist",
input_type="edgelist",
directed=False
)
G = network.core_network
# Perform a random walk
start_node = list(G.nodes())[0]
walk = basic_random_walk(
G,
start_node=start_node,
walk_length=10,
weighted=True,
seed=42
)
print(f"Random walk: {walk[:5]}... (length: {len(walk)})")
Output:
Random walk from ('0', 'null'): [('0', 'null'), ('1', 'null'), ('4872', 'null'), ('786', 'null'), ('5382', 'null')]... (length: 11)
Note: When loading a simple edgelist file (without explicit layer information), py3plex assigns nodes to a default layer named 'null'. Nodes are represented as tuples (node_id, layer_name).
Node2Vec Biased Walks
from py3plex.algorithms.general.walkers import node2vec_walk
# Biased walk with Node2Vec parameters
# p: return parameter (higher = less likely to return)
# q: in-out parameter (higher = stay local, lower = explore)
walk_bfs = node2vec_walk(
G, start_node, walk_length=20,
p=1.0, q=2.0, # BFS-like (local)
seed=42
)
walk_dfs = node2vec_walk(
G, start_node, walk_length=20,
p=1.0, q=0.5, # DFS-like (explore)
seed=42
)
Output (first 10 nodes of each walk):
Node2Vec BFS-like walk: [('0', 'null'), ('1', 'null'), ('5829', 'null'), ('1', 'null'), ('3842', 'null'), ('1', 'null'), ('6364', 'null'), ('1', 'null'), ('3422', 'null'), ('1', 'null')]
Node2Vec DFS-like walk: [('0', 'null'), ('1', 'null'), ('4872', 'null'), ('786', 'null'), ('5382', 'null'), ('260', 'null'), ('2861', 'null'), ('260', 'null'), ('5128', 'null'), ('260', 'null')]
Generating Multiple Walks
from py3plex.algorithms.general.walkers import generate_walks
# Generate walks from all nodes for embeddings
walks = generate_walks(
G,
num_walks=10, # Walks per node
walk_length=10, # Steps per walk
p=1.0, q=1.0, # Node2Vec parameters
seed=42
)
print(f"Generated {len(walks)} walks")
# Use with Word2Vec for node embeddings
# walks_str = [[str(node) for node in walk] for walk in walks]
# model = Word2Vec(walks_str, vector_size=128, window=10)
Output:
Generated 63870 walks
Example walk: [('4528', 'null'), ('2611', 'null'), ('4267', 'null'), ('2611', 'null'), ('2894', 'null'), ('2611', 'null'), ('6234', 'null'), ('2611', 'null'), ('3073', 'null'), ('479', 'null'), ('3125', 'null')]
Key parameters:
walk_length: Number of steps in the walkp: Return parameter (controls backtracking)q: In-out parameter (controls exploration vs. local search)weighted: Use edge weights in samplingseed: Random seed for reproducibility
8. Basic Visualization (1 minute)
Visualize your multilayer network:
from py3plex.visualization.multilayer import hairball_plot
import matplotlib.pyplot as plt
# Get network for visualization
network_colors, graph = network.get_layers(style="hairball")
# Create a simple hairball plot
plt.figure(figsize=(10, 10))
hairball_plot(
graph,
network_colors,
layout_algorithm="force",
layout_parameters={"iterations": 50}
)
plt.title("Multilayer Network Visualization")
plt.savefig("my_network.png", dpi=150, bbox_inches='tight')
plt.close()
print("Visualization saved to my_network.png")
Output:
Visualization saved to my_network.png
For more advanced visualizations with community colors:
from py3plex.visualization.colors import colors_default
# Get communities
partition = louvain_multilayer(network)
# Select top N communities
top_n = 5
community_counts = Counter(partition.values())
top_communities = [c for c, _ in community_counts.most_common(top_n)]
# Assign colors
color_map = dict(zip(
top_communities,
colors_default[:top_n]
))
network_colors = [
color_map.get(partition.get(node), "gray")
for node in network.get_nodes()
]
# Plot with community colors
plt.figure(figsize=(10, 10))
hairball_plot(graph, network_colors, layout_algorithm="force")
plt.title("Multilayer Network with Communities")
plt.savefig("my_network_communities.png", dpi=150, bbox_inches='tight')
plt.close()
print("Community visualization saved to my_network_communities.png")
Output:
Community visualization saved to my_network_communities.png
Complete Example: Putting It All Together
Here’s a complete workflow:
from py3plex.core import multinet
from py3plex.algorithms.community_detection.multilayer_modularity import louvain_multilayer
from py3plex.visualization.multilayer import hairball_plot
from py3plex.visualization.colors import colors_default
from collections import Counter
import matplotlib.pyplot as plt
# Load network
network = multinet.multi_layer_network().load_network(
"datasets/multiedgelist2.txt",
input_type="multiedgelist",
directed=False
)
# Analyze structure
print("=== Network Statistics ===")
network.basic_stats()
# Compute centrality for one layer
layer_1 = network.subnetwork(['1'], subset_by="layers")
degree_cent = layer_1.monoplex_nx_wrapper("degree_centrality")
print("\n=== Top 5 Nodes by Degree (Layer 1) ===")
for node, score in sorted(degree_cent.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f"{node}: {score:.3f}")
# Detect communities using multilayer method
partition = louvain_multilayer(network, gamma=1.0, omega=1.0, random_state=42)
print(f"\n=== Communities ===")
print(f"Number of communities: {len(set(partition.values()))}")
# Visualize with communities
network_colors, graph = network.get_layers(style="hairball")
top_n = 3
community_counts = Counter(partition.values())
top_communities = [c for c, _ in community_counts.most_common(top_n)]
color_map = dict(zip(top_communities, colors_default[:top_n]))
network_colors = [
color_map.get(partition.get(node), "lightgray")
for node in network.get_nodes()
]
plt.figure(figsize=(12, 12))
hairball_plot(graph, network_colors, layout_algorithm="force")
plt.title("Multilayer Network Analysis")
plt.savefig("complete_analysis.png", dpi=150, bbox_inches='tight')
plt.close()
print("\nComplete analysis saved to complete_analysis.png")
Output:
=== Network Statistics ===
Number of nodes: 184
Number of edges: 1691
Number of unique nodes (as node-layer tuples): 184
Number of unique node IDs (across all layers): 46
Nodes per layer:
Layer '1': 46 nodes
Layer '2': 46 nodes
Layer '3': 46 nodes
Layer '4': 46 nodes
=== Top 5 Nodes by Degree (Layer 1) ===
('15', '1'): 0.244
('7', '1'): 0.244
('27', '1'): 0.244
('28', '1'): 0.244
('1', '1'): 0.244
=== Communities ===
Number of communities: 46
Complete analysis saved to complete_analysis.png
Note: In this example, the high number of communities (equal to the number of nodes) indicates that the network structure or parameters may need adjustment for meaningful community detection. In practice, adjust gamma (resolution) and omega (inter-layer coupling) parameters to achieve desired community granularity.
Next Steps
Now that you’ve completed this tutorial, explore more advanced features:
Multilayer Statistics: Explore all available statistics in
py3plex.algorithms.statistics.multilayer_statisticsMultilayer Centrality: See examples in
examples/network_analysis/More Examples: Check the
examples/directory for 80+ examples organized by topicFull Documentation: Visit https://skblaz.github.io/py3plex/
Common Issues
File Not Found
Make sure you’re running from the repository root or use absolute paths:
import os
base_path = "/path/to/py3plex"
network = multinet.multi_layer_network().load_network(
os.path.join(base_path, "datasets/multiedgelist.txt"),
input_type="multiedgelist",
directed=False
)
Visualization Not Showing
If using Jupyter, add %matplotlib inline at the top of your notebook. For scripts, use plt.show() instead of plt.close().
Missing Dependencies
Some features require optional dependencies:
# For advanced visualization
pip install plotly
# For community detection with Infomap
pip install infomap
# For all extras
pip install git+https://github.com/SkBlaz/py3plex.git#egg=py3plex[viz,algos]
Tips for Success
Start Simple: Begin with small test networks before scaling to large datasets
Check Stats: Always run
basic_stats()after loading to verify your networkUse Subnetworks: Extract layers or subsets for faster prototyping
Seed Your Random: Use
seedparameters in algorithms for reproducible resultsVisualize Early: Quick plots help catch data loading issues early
Happy network analysis!