Network Visualization

With the rise of interest in network studies, many tools have been developed to visualize networks. Here I am going to introduce two of them, the Python NetworkX module and the D3.js based on Javascript.

Construct Network

We used the Bilateral Remittance Matrix 2012 download from here to construct a country-based network of money flows.

import random
from pylab import *
import numpy as np
import networkx as nx
import matplotlib.cm as cm


a = [line for line in open('/Users/csid/Desktop/BRM2012.txt','r')]
b = a[0].split('\r')
countries = b[1].split('\t')[1:-2]
G = nx.DiGraph()
for i in b[2:-8]:
    x = i.split('\t')[0]
    y = i.split('\t')[1:-2]
    for j in range(len(y)):
        if y[j] and float(y[j])>0:
            G.add_edge(x,countries[j],weight=float(y[j]))

Network Properties

Good visualizations tell stories. In visualizing networks we usually calculate network properties and integrate this information in the final output. Here I calculate the flow distance of each node from "source" and use it to cluster nodes.

H = flowBalancing(G)
L = flowDistanceFromSource(H)
T = H.out_degree(weight='weight')
pos = nx.spring_layout(G)
del L['sink']

The network G has 201 nodes and 7,660 edges.

dis = sorted(L.items(),key=lambda x:x[1])
x,y = np.array([pos[i] for i,l in dis]).T
t = np.array([T[i] for i,l in dis])
r = np.array([np.ceil(l) for i,l in dis])
#
cmap = cm.get_cmap('RdYlGn_r', int(max(r)))
fig = plt.figure(figsize=(10, 8),facecolor='white')
nx.draw_networkx_edges(G,pos,alpha=0.02,width=1,arrows=False)
cax = scatter(x,y,s=np.log(t+1)*30,c=r,cmap=cmap,edgecolor='gray',alpha=1)
cbar = fig.colorbar(cax, ticks=[1, 2, 3, 4])
axis('off')
xlim(-0.05,1.05)
ylim(-0.05,1.05)
tight_layout()
show()
#savefig('/Users/csid/Desktop/test.png', bbox_inches='tight')

The above code gives this figure

D3.js

Constrained by the power of browser engines, D3.js is not suitable for networks that contain more than thousands of edges and nodes. So we'd better select a part of the network.

g = nx.DiGraph()
for x,y in G.edges():
    w = G[x][y]['weight']
    if w > 100:
        g.add_edge(x,y,weight=w)

The above code give a new network which has 137 nodes and 548 edges.Now we write Javascript codes in Python.

nodes = [{"name" : i, "group" : int(L[i])} for i in g.nodes()]
maxw = max([G[x][y]['weight'] for x,y in g.edges()])
edges = [{ "source" : g.nodes().index(x), "target" : g.nodes().index(y),\
          "value" : g[x][y]['weight']/maxw} for x,y in g.edges()]

a='''
<body>
 <style>
.link {
stroke: #666;
opacity: 0.9;
stroke-width: 1.5px;
}
.node circle {
stroke: #fff;
opacity: 0.9;
stroke-width: 1.5px;
}
.node:not(:hover) .nodetext {
display: none;
}
text {
font: 7px serif;
opacity: 0.9;
pointer-events: none;
}
</style>
<script src=http://d3js.org/d3.v3.min.js></script>
<script>
 var links =
'''

b='''
;
var nodes =
'''

c='''
;
 var width = 800
height = 800;

var color = d3.scale.category10();

var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(50)
.charge(-50)
.on("tick", tick)
.start();

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

var link = svg.selectAll(".link")
.data(force.links())
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.value); });

var node = svg.selectAll(".node")
.data(force.nodes())
.enter().append("g")
.attr("class", "node")
.style("fill", function(d) { return color(d.group); })
.style("opacity", 0.9)
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.call(force.drag);

node.append("circle")
.attr("r", 6)

node.append("svg:text")
.attr("class", "nodetext")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) { return d.name });

function tick() {
link
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });

node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}

function mouseover() {
d3.select(this).select("circle").transition()
.duration(750)
.attr("r", 16);
d3.select(this).select("text").transition()
.duration(750)
.attr("x", 13)
.style("stroke-width", ".5px")
.style("font", "17.5px serif")
.style("opacity", 1);
}

function mouseout() {
d3.select(this).select("circle").transition()
.duration(750)
.attr("r", 8);
}

</script>
</body>
'''

open('/Users/csid/Desktop/moneyflow.html', "wb").write(a+str(edges)+b+str(nodes)+c)

The above codes create a .html file that gives the following interactive visualization:

results matching ""

    No results matching ""