SNAP

This Jupyter notebook provides an example of using the Python packages gravis and SNAP (=Stanford Network Analysis Platform). The .ipynb file can be found here.

References

Installation

  • With pip: pip install snap-stanford

  • With conda: Not available except for MacOS

Import

[1]:
import os

import snap

import gravis as gv

Quick start

Example 1

[2]:
# Create a random graph
g = snap.GenForestFire(250, 0.35, 0.35)

# Plot it
gv.d3(g, zoom_factor=0.2)
[2]:
Details for selected element
General
App state
Display mode
Export
Data selection
Graph
Node label text
Edge label text
Node size
Minimum
Maximum
Edge size
Minimum
Maximum
Nodes
Visibility
Size
Scaling factor
Position
Drag behavior
Hover behavior
Node images
Visibility
Size
Scaling factor
Node labels
Visibility
Size
Scaling factor
Rotation
Angle
Edges
Visibility
Size
Scaling factor
Form
Curvature
Hover behavior
Edge labels
Visibility
Size
Scaling factor
Rotation
Angle
Layout algorithm
Simulation
Many-body force
Strength
Theta
Min
Max
Links force
Collision force
Radius
Strength
x-positioning force
Strength
y-positioning force
Strength
Centering force

Graph construction

1) Manual graph construction

1.a) TUNGraph

undirected, with self-loop (max 1 per node), without parallel edges, without attributes

  • TUNGraph

    • AddNode(NId)

    • AddNode(NodeI)

    • AddEdge(SrcNId, DstNId)

    • AddEdge(EdgeI)

[3]:
ug = snap.TUNGraph.New()


# Node with automatic id (starts from 0 or highest user-defined id)
ug.AddNode(-1)  # argument: -1 for auto

# Node with user-defined id
ug.AddNode(5)   # argument: int
ug.AddNode(7)


# Nodes
# ~ Not supported (only via node iterator from other graph) ~


# Edge (nodes need to exist already)
ug.AddEdge(0, 5)
ug.AddEdge(5, 7)
ug.AddEdge(7, 0)
ug.AddEdge(5, 5)
ug.AddEdge(7, 7)


# Edges
# ~ Not supported (only via edge iterator from other graph) ~


gv.d3(ug, graph_height=200)
[3]:
Details for selected element
General
App state
Display mode
Export
Data selection
Graph
Node label text
Edge label text
Node size
Minimum
Maximum
Edge size
Minimum
Maximum
Nodes
Visibility
Size
Scaling factor
Position
Drag behavior
Hover behavior
Node images
Visibility
Size
Scaling factor
Node labels
Visibility
Size
Scaling factor
Rotation
Angle
Edges
Visibility
Size
Scaling factor
Form
Curvature
Hover behavior
Edge labels
Visibility
Size
Scaling factor
Rotation
Angle
Layout algorithm
Simulation
Many-body force
Strength
Theta
Min
Max
Links force
Collision force
Radius
Strength
x-positioning force
Strength
y-positioning force
Strength
Centering force

1.b) TNGraph

directed, with self-loop (max 1), without parallel edges, without attributes

[4]:
dg = snap.TNGraph.New()


# Node with automatic id
dg.AddNode(-1)  # argument: -1 for auto

# Node with user-defined id
dg.AddNode(5)   # argument: int
dg.AddNode(7)


# Nodes
# ~ Not supported (only via node iterator from other graph) ~


# Edge (nodes need to exist already)
dg.AddEdge(0, 5)
dg.AddEdge(5, 0)
dg.AddEdge(5, 7)
dg.AddEdge(7, 0)
dg.AddEdge(5, 5)
dg.AddEdge(7, 7)


# Edges
# ~ Not supported (only via edge iterator from other graph) ~


gv.d3(dg, graph_height=200)
[4]:
Details for selected element
General
App state
Display mode
Export
Data selection
Graph
Node label text
Edge label text
Node size
Minimum
Maximum
Edge size
Minimum
Maximum
Nodes
Visibility
Size
Scaling factor
Position
Drag behavior
Hover behavior
Node images
Visibility
Size
Scaling factor
Node labels
Visibility
Size
Scaling factor
Rotation
Angle
Edges
Visibility
Size
Scaling factor
Form
Curvature
Hover behavior
Edge labels
Visibility
Size
Scaling factor
Rotation
Angle
Layout algorithm
Simulation
Many-body force
Strength
Theta
Min
Max
Links force
Collision force
Radius
Strength
x-positioning force
Strength
y-positioning force
Strength
Centering force

1.c) TUndirNet (similar to TUNGraph)

directed, with self-loop (max 1 per node), without parallel edges, without attributes

[5]:
umg = snap.TUndirNet.New()


# Node with automatic id
umg.AddNode(-1)  # argument: -1 for auto

# Node with user-defined id
umg.AddNode(5)   # argument: int
umg.AddNode(7)


# Nodes
# ~ Not supported (only via node iterator from other graph) ~


# Edge (nodes need to exist already)
umg.AddEdge(0, 5)
umg.AddEdge(5, 0)
umg.AddEdge(5, 7)
umg.AddEdge(7, 0)
umg.AddEdge(5, 5)
umg.AddEdge(7, 7)


# Edges
# ~ Not supported (only via edge iterator from other graph) ~


gv.d3(umg, graph_height=200)
[5]:
Details for selected element
General
App state
Display mode
Export
Data selection
Graph
Node label text
Edge label text
Node size
Minimum
Maximum
Edge size
Minimum
Maximum
Nodes
Visibility
Size
Scaling factor
Position
Drag behavior
Hover behavior
Node images
Visibility
Size
Scaling factor
Node labels
Visibility
Size
Scaling factor
Rotation
Angle
Edges
Visibility
Size
Scaling factor
Form
Curvature
Hover behavior
Edge labels
Visibility
Size
Scaling factor
Rotation
Angle
Layout algorithm
Simulation
Many-body force
Strength
Theta
Min
Max
Links force
Collision force
Radius
Strength
x-positioning force
Strength
y-positioning force
Strength
Centering force

1.d) TDirNet (similar to TNGraph)

undirected, with self-loop (max 1 per node), without parallel edges, without attributes

[6]:
dmg = snap.TDirNet.New()


# Node with automatic id
dmg.AddNode(-1)  # argument: -1 for auto

# Node with user-defined id
dmg.AddNode(5)   # argument: int
dmg.AddNode(7)


# Nodes
# ~ Not supported (only via node iterator from other graph) ~


# Edge (nodes need to exist already)
dmg.AddEdge(0, 5)
dmg.AddEdge(5, 0)
dmg.AddEdge(5, 7)
dmg.AddEdge(7, 0)
dmg.AddEdge(5, 5)
dmg.AddEdge(7, 7)


# Edges
# ~ Not supported (only via edge iterator from other graph) ~


gv.d3(dmg, graph_height=200)
[6]:
Details for selected element
General
App state
Display mode
Export
Data selection
Graph
Node label text
Edge label text
Node size
Minimum
Maximum
Edge size
Minimum
Maximum
Nodes
Visibility
Size
Scaling factor
Position
Drag behavior
Hover behavior
Node images
Visibility
Size
Scaling factor
Node labels
Visibility
Size
Scaling factor
Rotation
Angle
Edges
Visibility
Size
Scaling factor
Form
Curvature
Hover behavior
Edge labels
Visibility
Size
Scaling factor
Rotation
Angle
Layout algorithm
Simulation
Many-body force
Strength
Theta
Min
Max
Links force
Collision force
Radius
Strength
x-positioning force
Strength
y-positioning force
Strength
Centering force

1.e) TNEANet

undirected, with self-loops, with parallel edges, with attributes (no graph attributes, node and edge attributes after explicit declaration)

[7]:
dmg = snap.TNEANet.New()


# Node with automatic id
dmg.AddNode(-1)  # argument: -1 for auto

# Node with user-defined id
dmg.AddNode(1)   # argument: int
dmg.AddNode(2)
dmg.AddNode()
dmg.AddNode(4)
dmg.AddNode()
dmg.AddNode(6)
dmg.AddNode(7)


# Nodes
# ~ Not supported (only via node iterator from other graph) ~


# Edge (nodes need to exist already)
dmg.AddEdge(0, 1)
dmg.AddEdge(1, 2)
dmg.AddEdge(2, 3)
dmg.AddEdge(3, 4)
dmg.AddEdge(4, 5)
dmg.AddEdge(5, 6)
dmg.AddEdge(6, 7)
dmg.AddEdge(7, 0)
dmg.AddEdge(0, 0)
dmg.AddEdge(0, 0)
dmg.AddEdge(0, 1)
dmg.AddEdge(0, 1)


# Edges
# ~ Not supported (only via edge iterator from other graph) ~


gv.d3(dmg, graph_height=200)
[7]:
Details for selected element
General
App state
Display mode
Export
Data selection
Graph
Node label text
Edge label text
Node size
Minimum
Maximum
Edge size
Minimum
Maximum
Nodes
Visibility
Size
Scaling factor
Position
Drag behavior
Hover behavior
Node images
Visibility
Size
Scaling factor
Node labels
Visibility
Size
Scaling factor
Rotation
Angle
Edges
Visibility
Size
Scaling factor
Form
Curvature
Hover behavior
Edge labels
Visibility
Size
Scaling factor
Rotation
Angle
Layout algorithm
Simulation
Many-body force
Strength
Theta
Min
Max
Links force
Collision force
Radius
Strength
x-positioning force
Strength
y-positioning force
Strength
Centering force

Assign attributes to a created graph

[8]:
g = snap.TNEANet.New()
for node in [0, 1, 2, 3, 4, 5, 6, 7]:
    g.AddNode(node)
for source, target in [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 0)]:
    g.AddEdge(source, target)
1) Graph attributes
[9]:
# ~ Not supported ~
2) Node attributes
[10]:
# Define node attributes
g.AddIntAttrN('size')     # int
g.AddFltAttrN('opacity')  # float
g.AddStrAttrN('color')    # str
g.AddStrAttrN('shape')    # str

# Nodes
num_nodes = len(list(g.Nodes()))
for i in range(num_nodes):
    g.AddIntAttrDatN(i, 5 + i*5, 'size')
    g.AddStrAttrDatN(i, 'lightblue', 'color')

# Node
g.AddStrAttrDatN(3, 'darkred', 'color')
g.AddStrAttrDatN(3, 'hexagon', 'shape')
g.AddIntAttrDatN(3, 40, 'size')
g.AddFltAttrDatN(3, 0.3, 'opacity')
[10]:
0
3) Edge attributes
[11]:
# Define edge attributes
g.AddIntAttrE('size')     # int
# g.AddFltAttrE('opacity')  # float
g.AddStrAttrE('color')    # str

# Edges
num_edges = len(list(g.Edges()))
for i in range(num_edges):
    g.AddIntAttrDatE(i, 1 + i, 'size')
    g.AddStrAttrDatE(i, 'lightgreen', 'color')

# Edge
g.AddIntAttrDatE(3, 1, 'size')
# g.AddFltAttrDatE(3, 1.0, 'opacity')
g.AddStrAttrDatE(3, 'red', 'color')
[11]:
0
[12]:
gv.d3(g, graph_height=200)
[12]:
Details for selected element
General
App state
Display mode
Export
Data selection
Graph
Node label text
Edge label text
Node size
Minimum
Maximum
Edge size
Minimum
Maximum
Nodes
Visibility
Size
Scaling factor
Position
Drag behavior
Hover behavior
Node images
Visibility
Size
Scaling factor
Node labels
Visibility
Size
Scaling factor
Rotation
Angle
Edges
Visibility
Size
Scaling factor
Form
Curvature
Hover behavior
Edge labels
Visibility
Size
Scaling factor
Rotation
Angle
Layout algorithm
Simulation
Many-body force
Strength
Theta
Min
Max
Links force
Collision force
Radius
Strength
x-positioning force
Strength
y-positioning force
Strength
Centering force

2) Algorithmic graph construction

[13]:
num_nodes = 20
num_edges = 10
[14]:
g = snap.GenForestFire(num_nodes, 0.35, 0.35)

# A random Erdos-Renyi directed graph
g = snap.GenRndGnm(snap.PNGraph, num_nodes, num_edges)

# A Preferential Attachment graph with out-degree 3
g = snap.GenPrefAttach(num_nodes, 3)

3) Graph loading from an internal collection

[15]:
# TODO

4) Graph import and export

Import

[16]:
filepath = os.path.join('data', 'snap_graph.net')
g = snap.LoadPajek(snap.PNGraph, filepath)

# TODO

Export

[17]:
filepath = os.path.join('data', 'snap_graph.net')
snap.SavePajek(g, filepath)

# Other methods
# snap.SaveEdgeList(g, 'snap_graph_edge_list.txt')
# TODO

Basic graph inspection

1) Graph and its properties

[18]:
print('Type:', type(g))
print('Directed:', )
print('Number of nodes:', g.GetNodes())
print('Number of edges:', g.GetEdges())
print('Well-formed:', g.IsOk())
print('Approximate graph diameter:', snap.GetBfsFullDiam(g, 10))
print('Number of triads:', snap.GetTriads(g))
print('Clustering coefficient', snap.GetClustCf(g))
Type: <class 'snap.PNGraph'>
Directed:
Number of nodes: 50
Number of edges: 100
Well-formed: True
Approximate graph diameter: 5
Number of triads: 9
Clustering coefficient 0.08790476190476189

2) Nodes and their properties

[19]:
#g.AddIntAttrN("NValInt", 0)
for node in g.Nodes():
    print('Class:', type(node))
    print("Id:", node.GetId())
    print("In degree:", node.GetInDeg())
    print("Out degree:", node.GetOutDeg())
    break
    #g.AddIntAttrDatN(node_id, 42, "NValInt")
Class: <class 'snap.TNGraphNodeI'>
Id: 1
In degree: 0
Out degree: 2

3) Edges and their properties

[20]:
for edge in g.Edges():
    print('Class:', type(edge))
    print("Id:", edge.GetId())
    print("Source node id:", edge.GetSrcNId())
    print("Target node id:", edge.GetDstNId())
    break
Class: <class 'snap.TNGraphEdgeI'>
Id: (1, 4)
Source node id: 1
Target node id: 4

Calculating graph measures and metrics

1) Quantitative measures

[21]:
snap.GetClustCf(g)
[21]:
0.08790476190476189

2) Structure inference

Community detection

[22]:
g = snap.GenRndGnm(snap.PUNGraph, 50, 100)

CmtyV = snap.TCnComV()
modularity = snap.CommunityGirvanNewman(g, CmtyV)

CmtyV = snap.TCnComV()
modularity = snap.CommunityCNM(g, CmtyV)

Other kinds of groups

[23]:
g = snap.GenRndGnm(snap.PUNGraph, 50, 100)

snap.GetTriads(g)
[23]:
4

Graph visualization

[24]:
# TODO