How to Load and Build Networks

Goal: Create multilayer networks from scratch or load them from files.

Prerequisites: Basic Python knowledge. For conceptual background, see The py3plex Core Model.

Start from the format you already have: add edges directly if you are prototyping, or load from files/dataframes when your data is already tabular. The examples below always build a network object you can reuse in later steps.

Creating Networks from Scratch

Use these options when you want to assemble a small network interactively or generate synthetic structures.

Method 2: Add Nodes First

For more control over node attributes and to ensure edges only connect existing nodes:

from py3plex.core import multinet

network = multinet.multi_layer_network()

# Add nodes explicitly (as node-layer tuples)
network.add_nodes([
    ('Alice', 'friends'),
    ('Bob', 'friends'),
    ('Carol', 'friends'),
    ('Alice', 'colleagues'),
    ('Bob', 'colleagues'),
    ('Dave', 'colleagues')
])

# Add edges between existing nodes
network.add_edges([
    [('Alice', 'friends'), ('Bob', 'friends'), 1.0],
    [('Bob', 'friends'), ('Carol', 'friends'), 1.0]
])

Method 3: Use Dictionary Format

For networks with edge attributes and mixed field names (timestamps, types, etc.):

from py3plex.core import multinet

network = multinet.multi_layer_network()

# Add edges with custom attributes
network.add_edges([
    {
        'source': 'Alice',
        'source_type': 'friends',
        'target': 'Bob',
        'target_type': 'friends',
        'weight': 1.0,
        'timestamp': '2024-01-15',
        'interaction_type': 'message'
    },
    {
        'source': 'Bob',
        'source_type': 'friends',
        'target': 'Carol',
        'target_type': 'friends',
        'weight': 2.5,
        'timestamp': '2024-01-16'
    }
], input_type="dict")

Loading Networks from Files

Use file-based loading when your data already lives on disk. Edge lists remain the most compact choice; JSON is convenient for richer metadata. Each snippet builds the same network interface shown above.

Load Edge Lists

Most common format: one edge per line. The multiedgelist loader expects source source_layer target target_layer weight (weight defaults to 1.0 if omitted).

File format (stored as datasets/simple_multiplex.txt in the repository):

Alice friends Bob friends 1.0
Bob friends Carol friends 1.0
Alice colleagues Bob colleagues 1.0

Load it:

from py3plex.core import multinet

network = multinet.multi_layer_network()

# Option 1: Load from repository file
network.load_network(
    "datasets/simple_multiplex.txt",
    input_type="multiedgelist"
)

# Option 2: Create from data directly (recommended for examples)
network.add_edges([
    ['Alice', 'friends', 'Bob', 'friends', 1.0],
    ['Bob', 'friends', 'Carol', 'friends', 1.0],
    ['Alice', 'colleagues', 'Bob', 'colleagues', 1.0],
], input_type="list")

network.basic_stats()

Load from Pandas DataFrame

Convert tabular data to networks (each row becomes an edge). Use separate layer columns if endpoints belong to different layers.

import pandas as pd
from py3plex.core import multinet

# Your data
df = pd.DataFrame({
    'source': ['Alice', 'Bob', 'Alice'],
    'layer': ['friends', 'friends', 'work'],
    'target': ['Bob', 'Carol', 'Carol'],
    'weight': [1.0, 1.0, 2.0]
})

# Convert to network
network = multinet.multi_layer_network()

for _, row in df.iterrows():
    network.add_edge(
        row['source'], row['layer'],
        row['target'], row['layer'],
        weight=row['weight']
    )

# If your dataframe has ``source_layer`` and ``target_layer`` columns,
# pass those instead of a single ``layer`` column:
# network.add_edge(
#     row['source'], row['source_layer'],
#     row['target'], row['target_layer'],
#     weight=row['weight']
# )

network.basic_stats()

Load from JSON

For complex networks with metadata (define both nodes and edges explicitly). Keep edge dictionaries consistent: source, source_layer, target, target_layer, plus any other attributes you want to preserve.

import json
from py3plex.core import multinet

# Load JSON
with open('network.json', 'r') as f:
    data = json.load(f)

network = multinet.multi_layer_network()

# Assuming JSON structure: {"edges": [...], "nodes": [...]}
for edge in data['edges']:
    network.add_edge(
        edge['source'], edge['source_layer'],
        edge['target'], edge['target_layer'],
        **edge.get('attributes', {})
    )

# Optionally, add nodes first if your JSON includes node attributes
# for node in data.get('nodes', []):
#     network.add_nodes([(node['id'], node['layer'])])

network.basic_stats()

Load from NetworkX

Convert existing single-layer networks by assigning a default layer name. If the original graph has edge attributes, pass them through add_edge as keyword arguments.

import networkx as nx
from py3plex.core import multinet

# Existing NetworkX graph
G = nx.karate_club_graph()

# Convert to multilayer (single layer)
network = multinet.multi_layer_network()

for u, v in G.edges():
    network.add_edge(u, 'layer1', v, 'layer1')

Loading with Inter-layer Edges

To represent the same entity across layers, connect node-layer tuples that share the same node identifier:

network = multinet.multi_layer_network()

# Intra-layer edges
network.add_edges([
    ['Alice', 'friends', 'Bob', 'friends', 1.0],
    ['Alice', 'work', 'Carol', 'work', 1.0],
], input_type="list")

# Inter-layer edges (same person across layers)
network.add_edge('Alice', 'friends', 'Alice', 'work', type='interlayer')
network.add_edge('Bob', 'friends', 'Bob', 'work', type='interlayer')

Common Patterns

Pick a template that matches your data model, then extend it with attributes as needed.

Pattern 1: Social Networks

Multiple relationship types between same people:

network = multinet.multi_layer_network()
network.add_edges([
    ['Alice', 'twitter', 'Bob', 'twitter', 1],
    ['Alice', 'linkedin', 'Bob', 'linkedin', 1],
    ['Bob', 'twitter', 'Carol', 'twitter', 1],
], input_type="list")

Pattern 2: Heterogeneous Networks

Different entity types:

# Author-Paper bipartite network
network = multinet.multi_layer_network()
network.add_edges([
    ['Alice', 'authors', 'Paper1', 'papers', 1],
    ['Bob', 'authors', 'Paper1', 'papers', 1],
    ['Alice', 'authors', 'Paper2', 'papers', 1],
], input_type="list")

Pattern 3: Temporal Networks

Time-stamped edges:

network = multinet.multi_layer_network()
network.add_edges([
    {
        'source': 'Alice',
        'source_type': 'social',
        'target': 'Bob',
        'target_type': 'social',
        't': '2024-01-15T10:00:00'  # Point in time
    },
    {
        'source': 'Bob',
        'source_type': 'social',
        'target': 'Carol',
        'target_type': 'social',
        't_start': '2024-01-15',     # Time range
        't_end': '2024-01-20'
    }
], input_type="dict")

See API Documentation for temporal network details.

Verifying Your Network

After loading, verify the structure to catch layer/weight mistakes early:

# Basic stats
network.basic_stats()

# Get specific information
layers = network.get_layers()
print(f"Layers: {layers}")

num_nodes = len(list(network.get_nodes()))
print(f"Total nodes: {num_nodes}")

# Check a specific layer
from py3plex.dsl import Q, L
layer_nodes = Q.nodes().from_layers(L["friends"]).execute(network)
print(f"Friends layer: {len(layer_nodes)} nodes")

Expected output:

Layers: ['friends', 'colleagues']
Total nodes: 6
Friends layer: 3 nodes

Next Steps