This notebook as been adapted from the original notebook to plot with Bokeh instead of matplotlib.
NetworkX is a Python language software package for the creation, manipulation, and study of the structure, dynamics, and function of complex networks.
With NetworkX you can load and store networks in standard and nonstandard data formats, generate many types of random and classic networks, analyze network structure, build network models, design new network algorithms, draw networks, and much more.
Library documentation: https://networkx.github.io/
import networkx as nx
G = nx.Graph()
# basic add nodes
G.add_node(1)
G.add_nodes_from([2, 3])
# add a group of nodes at once
H = nx.path_graph(10)
G.add_nodes_from(H)
# add another graph itself as a node
G.add_node(H)
# add edges using similar methods
G.add_edge(1, 2)
e = (2, 3)
G.add_edge(*e)
G.add_edges_from([(1, 2), (1, 3)])
G.add_edges_from(H.edges())
# can also remove or clear
G.remove_node(H)
G.clear()
# repeats are ignored
G.add_edges_from([(1,2),(1,3)])
G.add_node(1)
G.add_edge(1,2)
G.add_node('spam') # adds node "spam"
G.add_nodes_from('spam') # adds 4 nodes: 's', 'p', 'a', 'm'
# get the number of nodes and edges
G.number_of_nodes(), G.number_of_edges()
(8, 2)
# access graph edges
G[1]
{2: {}, 3: {}}
G[1][2]
{}
# set an attribute of an edge
G.add_edge(1,3)
G[1][3]['color'] = 'blue'
FG = nx.Graph()
FG.add_weighted_edges_from([(1, 2, 0.125), (1, 3, 0.75), (2, 4, 1.2), (3, 4, 0.375)])
for n, nbrs in FG.adjacency_iter():
for nbr, eattr in nbrs.items():
data = eattr['weight']
if data < 0.5: print('(%d, %d, %.3f)' % (n, nbr, data))
(1, 2, 0.125) (2, 1, 0.125) (3, 4, 0.375) (4, 3, 0.375)
# graph attribte
G = nx.Graph(day='Friday')
G.graph
{'day': 'Friday'}
# modifying an attribute
G.graph['day'] = 'Monday'
G.graph
{'day': 'Monday'}
# node attributes
G.add_node(1, time='5pm')
G.add_nodes_from([3], time='2pm')
G.node[1]['room'] = 714
G.nodes(data=True)
[(1, {'room': 714, 'time': '5pm'}), (3, {'time': '2pm'})]
# edge attributes (weight is a special numeric attribute)
G.add_edge(1, 2, weight=4.7)
G.add_edges_from([(3, 4), (4, 5)], color='red')
G.add_edges_from([(1, 2 ,{'color': 'blue'}), (2, 3, {'weight' :8})])
G[1][2]['weight'] = 4.7
G.edge[1][2]['weight'] = 4
# directed graph
DG = nx.DiGraph()
DG.add_weighted_edges_from([(1, 2 ,0.5), (3, 1, 0.75)])
DG.out_degree(1, weight='weight')
0.5
DG.degree(1, weight='weight')
1.25
DG.successors(1)
[2]
DG.predecessors(1)
[3]
# convert to undirected graph
H = nx.Graph(G)
from bokeh.plotting import figure, show
from bokeh.resources import CDN
from bokeh.io import output_notebook
output_notebook( resources=CDN )
There are a few layouts available in NetworkX graphs.
pts = nx.circular_layout(G)
p = figure(
x_range = (-.1,1.1),
y_range = (-.1,1.1),
height= 400,
width= 400,
)
for edge in G.edges():
p.line(
x= [pts[pt][0] for pt in edge],
y= [pts[pt][1] for pt in edge],
)
for node in G.nodes():
p.circle(
x= [pts[node][0]],
y= [pts[node][1]],
radius=.05
)
show(p)
pts = nx.random_layout(G)
p = figure(
x_range = (-.1,1.1),
y_range = (-.1,1.1),
height= 400,
width= 400,
)
for edge in G.edges():
p.line(
x= [pts[pt][0] for pt in edge],
y= [pts[pt][1] for pt in edge],
)
for node in G.nodes():
p.circle(
x= [pts[node][0]],
y= [pts[node][1]],
radius=.05
)
show(p)
pts = nx.shell_layout(G)
p = figure(
x_range = (-1.1,1.1),
y_range = (-1.1,1.1),
height= 400,
width= 400,
)
for edge in G.edges():
p.line(
x= [pts[pt][0] for pt in edge],
y= [pts[pt][1] for pt in edge],
)
for node in G.nodes():
p.circle(
x= [pts[node][0]],
y= [pts[node][1]],
radius=.05
)
show(p)
pts = nx.spring_layout(G)
p = figure(
x_range = (-.1,1.1),
y_range = (-.1,1.1),
height= 400,
width= 400,
)
for edge in G.edges():
p.line(
x= [pts[pt][0] for pt in edge],
y= [pts[pt][1] for pt in edge],
)
for node in G.nodes():
p.circle(
x= [pts[node][0]],
y= [pts[node][1]],
radius=.05,
)
show(p)
pts = nx.spectral_layout(G)
p = figure(
x_range = (-.1,1.1),
y_range = (-.1,1.1),
height= 400,
width= 400,
)
for edge in G.edges():
p.line(
x= [pts[pt][0] for pt in edge],
y= [pts[pt][1] for pt in edge],
)
for node in G.nodes():
p.circle(
x= [pts[node][0]],
y= [pts[node][1]],
radius=.05,
)
show(p)