import altair as alt
import networkx as nx
import nx_altair as nxa
G = nx.fast_gnp_random_graph(n=50, p=.1)
# show graph with nx_altair
nxa.draw_networkx(G)
G = nx.Graph()
G.add_node("Ada")
G.add_node("Bob")
G.add_node("Cai")
G.add_node("Don")
G.add_node("Eva")
G.add_edge("Ada", "Bob")
G.add_edge("Ada", "Cai")
G.add_edge("Ada", "Eva")
G.add_edge("Bob", "Cai")
G.add_edge("Bob", "Don")
G.add_edge("Cai", "Don")
nxa.draw_networkx(G)
G = nx.Graph([("Ada", "Bob"),
("Ada", "Cai"),
("Ada", "Eva"),
("Bob", "Cai"),
("Bob", "Don"),
("Cai", "Don")])
G = nx.Graph()
G.add_node(1, time='3pm')
G.nodes[1]
G.nodes[1]['room'] = 5842
G.nodes.data()
G.add_edge(1, 2, weight=4.7)
G.edges[1, 2]['weight'] = 3.2
G.edges.data()
import requests
url = "http://bost.ocks.org/mike/miserables/miserables.json"
# Run the HTTP request and transform it into a JSON object.
lesmis = requests.get(url).json()
# we specify that the dataset is not a multigraph, there are no self-loops
# or multiedges, multiple edges between nodes
G = nx.readwrite.json_graph.node_link_graph(lesmis, multigraph=False)
nxa.draw_networkx(G, node_tooltip="name")
G.number_of_nodes()
G.number_of_edges()
density = nx.density(G)
print("Network density:", density)
names = ("Napoleon", "Jondrette")
ids = [x for x,y in G.nodes(data=True) if y['name'] in names]
ids
path = nx.shortest_path(G, source=ids[0], target=ids[1])
print("Shortest path between {} & {}:".format(names[0], names[1]), path)
print("Length of above path:", len(path)-1)
degrees = dict(G.degree(G.nodes()))
# save the degrees as a node attribute
nx.set_node_attributes(G, degrees, 'degree')
# check what has been saved
G.nodes.data()
# reverse sort of the degrees
sorted_degree = sorted(degrees.items(), key=lambda x: x[1], reverse=True)
# above x[1] refers to degree as items() returns both keys and values in tuples
print("Top 10 nodes by degree:\n")
for d in sorted_degree[:10]:
print( " - {} has {} neighbors".format(G.nodes[d[0]]["name"], d[1]) )
between = nx.betweenness_centrality(G)
nx.set_node_attributes(G, between, 'between')
sorted_between = sorted(between.items(), key=lambda x: x[1], reverse=True)
print("Top 10 nodes by between:\n")
for d in sorted_between[:10]:
print( " - {}: {} ".format(G.nodes[d[0]]["name"], d[1]) )
nxa.draw_networkx(G, node_tooltip='name').properties(width=500, height=500)
pos = nx.spring_layout(G, iterations=100)
nxa.draw_networkx(G, pos, node_tooltip='name').properties(width=500, height=500)
pos = nx.spring_layout(G)
nxa.draw_networkx(G, pos, node_tooltip='name').properties(width=500, height=500)
nxa.draw_networkx(G, pos=pos,
node_size='degree:Q',
node_color='group:N',
cmap = "category10", # pass colormap that is used
node_tooltip='name:N',
linewidths=0, # remove borders from circles
).properties(width=500, height=500)
# rectangular selection in the network view
selection = alt.selection_interval(encodings=['x', 'y'])
# group selection in the bar chart
selection2 = alt.selection_point(fields=['group'])
# first we create the force-directed layout
chart = nxa.draw_networkx( G, pos=pos,
node_size=100,
node_color='group:N',
width='value:Q',
node_tooltip='name',
linewidths=0
)
# get node and edge layers from chart
edges = chart.layer[0]
nodes = chart.layer[1]
# group numbers (needed to keep bar chart stable during selections)
groups = list(range(1,10))
# separate color definition used across both charts
color = alt.Color('group:N', scale=alt.Scale(domain=groups), legend=None)
# adjust node opacity and fill color according to selections
nodes = nodes.encode(
opacity=alt.condition(selection, alt.value(1), alt.value(0.25)),
fill=alt.condition(selection2, color, alt.value('lightgray')),
).add_params(selection,selection2)
# interactive bar chart
bars = alt.Chart(nodes.data).mark_bar().encode(
x=alt.X('count()', scale=alt.Scale(domain=(0,20))),
y = alt.Y('group:O', scale=alt.Scale(domain=(groups))),
color=color,
opacity=alt.condition(selection2, alt.value(1), alt.value(0.25)),
).transform_filter(selection).add_params(selection2)
# concatenate all layers into one multi-view layout
alt.vconcat(edges+nodes, bars)