annotate plot_adjacency.py @ 1:65551439a6bb draft default tip

Uploaded
author bornea
date Wed, 18 Oct 2017 15:29:22 -0400
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
65551439a6bb Uploaded
bornea
parents:
diff changeset
1 import sys
65551439a6bb Uploaded
bornea
parents:
diff changeset
2 def readTab(infile): # read in txt file
65551439a6bb Uploaded
bornea
parents:
diff changeset
3 with open(infile, 'r') as input_file:
65551439a6bb Uploaded
bornea
parents:
diff changeset
4 # read in tab-delim text
65551439a6bb Uploaded
bornea
parents:
diff changeset
5 output = []
65551439a6bb Uploaded
bornea
parents:
diff changeset
6 for input_line in input_file:
65551439a6bb Uploaded
bornea
parents:
diff changeset
7 input_line = input_line.strip()
65551439a6bb Uploaded
bornea
parents:
diff changeset
8 temp = input_line.split('\t')
65551439a6bb Uploaded
bornea
parents:
diff changeset
9 output.append(temp)
65551439a6bb Uploaded
bornea
parents:
diff changeset
10 return output
65551439a6bb Uploaded
bornea
parents:
diff changeset
11 def network2JSON(nodes_att_file, edge_file):
65551439a6bb Uploaded
bornea
parents:
diff changeset
12 nodes = readTab(nodes_att_file)
65551439a6bb Uploaded
bornea
parents:
diff changeset
13 edges = readTab(edge_file)
65551439a6bb Uploaded
bornea
parents:
diff changeset
14
65551439a6bb Uploaded
bornea
parents:
diff changeset
15 start = """{"nodes": ["""
65551439a6bb Uploaded
bornea
parents:
diff changeset
16 node_numbers = {}
65551439a6bb Uploaded
bornea
parents:
diff changeset
17 cnt=0
65551439a6bb Uploaded
bornea
parents:
diff changeset
18 for i in nodes[1:]:
65551439a6bb Uploaded
bornea
parents:
diff changeset
19 node_numbers[i[0]] = cnt
65551439a6bb Uploaded
bornea
parents:
diff changeset
20 cnt+=1
65551439a6bb Uploaded
bornea
parents:
diff changeset
21 start = start + '{"name":'+'"'+i[0]+'", "EV":'+i[2]+', "group":'+i[1]+"},"
65551439a6bb Uploaded
bornea
parents:
diff changeset
22 start = start[:-1]
65551439a6bb Uploaded
bornea
parents:
diff changeset
23 start = start+"""], "links": ["""
65551439a6bb Uploaded
bornea
parents:
diff changeset
24 for i in edges:
65551439a6bb Uploaded
bornea
parents:
diff changeset
25 start = start + """{"source":"""+str(node_numbers[i[0]])+""","target":"""+str(node_numbers[i[1]])+""","value":1},"""
65551439a6bb Uploaded
bornea
parents:
diff changeset
26 start = start[:-1]
65551439a6bb Uploaded
bornea
parents:
diff changeset
27 start = start + """]}"""
65551439a6bb Uploaded
bornea
parents:
diff changeset
28 return start
65551439a6bb Uploaded
bornea
parents:
diff changeset
29 def labelCentrality(nodes_att_file):
65551439a6bb Uploaded
bornea
parents:
diff changeset
30 nodes = readTab(nodes_att_file)
65551439a6bb Uploaded
bornea
parents:
diff changeset
31 if nodes[0][2] == "eigen":
65551439a6bb Uploaded
bornea
parents:
diff changeset
32 return "Eigenvector Centrality"
65551439a6bb Uploaded
bornea
parents:
diff changeset
33 if nodes[0][2] == "closeness":
65551439a6bb Uploaded
bornea
parents:
diff changeset
34 return "Closeness Centrality"
65551439a6bb Uploaded
bornea
parents:
diff changeset
35 if nodes[0][2] == "betweenness":
65551439a6bb Uploaded
bornea
parents:
diff changeset
36 return "Betweenness Centrality"
65551439a6bb Uploaded
bornea
parents:
diff changeset
37 if nodes[0][2] == "page":
65551439a6bb Uploaded
bornea
parents:
diff changeset
38 return "Page Rank"
65551439a6bb Uploaded
bornea
parents:
diff changeset
39
65551439a6bb Uploaded
bornea
parents:
diff changeset
40
65551439a6bb Uploaded
bornea
parents:
diff changeset
41
65551439a6bb Uploaded
bornea
parents:
diff changeset
42 adjacency_start = """
65551439a6bb Uploaded
bornea
parents:
diff changeset
43 <!DOCTYPE html>
65551439a6bb Uploaded
bornea
parents:
diff changeset
44 <html><head>
65551439a6bb Uploaded
bornea
parents:
diff changeset
45 <meta charset="utf-8">
65551439a6bb Uploaded
bornea
parents:
diff changeset
46 <style>
65551439a6bb Uploaded
bornea
parents:
diff changeset
47 .background {fill: #fff;}
65551439a6bb Uploaded
bornea
parents:
diff changeset
48 line {stroke: #000;}
65551439a6bb Uploaded
bornea
parents:
diff changeset
49 text.active {fill: red;font-weight:bold;}
65551439a6bb Uploaded
bornea
parents:
diff changeset
50 </style>
65551439a6bb Uploaded
bornea
parents:
diff changeset
51 <script src="http://d3js.org/d3.v2.min.js" charset="utf-8"></script>
65551439a6bb Uploaded
bornea
parents:
diff changeset
52 <script src="https://cdn.rawgit.com/eligrey/Blob.js/0cef2746414269b16834878a8abc52eb9d53e6bd/Blob.js""></script>
65551439a6bb Uploaded
bornea
parents:
diff changeset
53 <script src="https://cdn.rawgit.com/eligrey/FileSaver.js/e9d941381475b5df8b7d7691013401e171014e89/FileSaver.min.js"></script>
65551439a6bb Uploaded
bornea
parents:
diff changeset
54 </head>
65551439a6bb Uploaded
bornea
parents:
diff changeset
55 <aside style = "margin-top: 80px">
65551439a6bb Uploaded
bornea
parents:
diff changeset
56 <p>Order: <select id="order">
65551439a6bb Uploaded
bornea
parents:
diff changeset
57 <option value="name">Name</option>
65551439a6bb Uploaded
bornea
parents:
diff changeset
58 <option value="EV">""" + labelCentrality(sys.argv[1]) + """</option>
65551439a6bb Uploaded
bornea
parents:
diff changeset
59 <option value="group">Modularity</option>
65551439a6bb Uploaded
bornea
parents:
diff changeset
60 </select>
65551439a6bb Uploaded
bornea
parents:
diff changeset
61 <button id="generate">Save as SVG</button>
65551439a6bb Uploaded
bornea
parents:
diff changeset
62 </aside>
65551439a6bb Uploaded
bornea
parents:
diff changeset
63
65551439a6bb Uploaded
bornea
parents:
diff changeset
64 <script>
65551439a6bb Uploaded
bornea
parents:
diff changeset
65 var margin = {top: 200, right: 0, bottom: 10, left: 200},
65551439a6bb Uploaded
bornea
parents:
diff changeset
66 width = 720,
65551439a6bb Uploaded
bornea
parents:
diff changeset
67 height = 720;
65551439a6bb Uploaded
bornea
parents:
diff changeset
68
65551439a6bb Uploaded
bornea
parents:
diff changeset
69 var x = d3.scale.ordinal().rangeBands([0, width]),
65551439a6bb Uploaded
bornea
parents:
diff changeset
70 z = d3.scale.linear().domain([0, 4]).clamp(true),
65551439a6bb Uploaded
bornea
parents:
diff changeset
71 c = d3.scale.category10().domain(d3.range(10));
65551439a6bb Uploaded
bornea
parents:
diff changeset
72
65551439a6bb Uploaded
bornea
parents:
diff changeset
73 var svg = d3.select("body").append("svg")
65551439a6bb Uploaded
bornea
parents:
diff changeset
74 .attr("id","adjmatrix")
65551439a6bb Uploaded
bornea
parents:
diff changeset
75 .attr("width", width + margin.left + margin.right)
65551439a6bb Uploaded
bornea
parents:
diff changeset
76 .attr("height", height + margin.top + margin.bottom)
65551439a6bb Uploaded
bornea
parents:
diff changeset
77 //.style("margin-left", -margin.left + "px")
65551439a6bb Uploaded
bornea
parents:
diff changeset
78 .append("g")
65551439a6bb Uploaded
bornea
parents:
diff changeset
79 .attr("transform", "translate(" + margin.left + "," + margin.top + ")");"""
65551439a6bb Uploaded
bornea
parents:
diff changeset
80
65551439a6bb Uploaded
bornea
parents:
diff changeset
81
65551439a6bb Uploaded
bornea
parents:
diff changeset
82 ################# Create JSON formatted Network ################
65551439a6bb Uploaded
bornea
parents:
diff changeset
83
65551439a6bb Uploaded
bornea
parents:
diff changeset
84 jsondata = """\njsondata ='""" + network2JSON(sys.argv[1],sys.argv[2])+"'"
65551439a6bb Uploaded
bornea
parents:
diff changeset
85
65551439a6bb Uploaded
bornea
parents:
diff changeset
86 ################################################################
65551439a6bb Uploaded
bornea
parents:
diff changeset
87 adjacency_end = """;
65551439a6bb Uploaded
bornea
parents:
diff changeset
88 var data = JSON.parse(jsondata);
65551439a6bb Uploaded
bornea
parents:
diff changeset
89
65551439a6bb Uploaded
bornea
parents:
diff changeset
90 function plot_adjacency(data) {
65551439a6bb Uploaded
bornea
parents:
diff changeset
91 var matrix = [],
65551439a6bb Uploaded
bornea
parents:
diff changeset
92 nodes = data.nodes,
65551439a6bb Uploaded
bornea
parents:
diff changeset
93 n = nodes.length;
65551439a6bb Uploaded
bornea
parents:
diff changeset
94
65551439a6bb Uploaded
bornea
parents:
diff changeset
95 // Compute index per node.
65551439a6bb Uploaded
bornea
parents:
diff changeset
96 nodes.forEach(function(node, i) {
65551439a6bb Uploaded
bornea
parents:
diff changeset
97 node.index = i;
65551439a6bb Uploaded
bornea
parents:
diff changeset
98 node.count = 0;
65551439a6bb Uploaded
bornea
parents:
diff changeset
99 matrix[i] = d3.range(n).map(function(j) { return {x: j, y: i, z: 0}; });
65551439a6bb Uploaded
bornea
parents:
diff changeset
100 });
65551439a6bb Uploaded
bornea
parents:
diff changeset
101
65551439a6bb Uploaded
bornea
parents:
diff changeset
102 // Convert edges to matrix
65551439a6bb Uploaded
bornea
parents:
diff changeset
103 data.links.forEach(function(link) {
65551439a6bb Uploaded
bornea
parents:
diff changeset
104 matrix[link.source][link.target].z += link.value;
65551439a6bb Uploaded
bornea
parents:
diff changeset
105 matrix[link.target][link.source].z += link.value;
65551439a6bb Uploaded
bornea
parents:
diff changeset
106 matrix[link.source][link.source].z += link.value; // self loop
65551439a6bb Uploaded
bornea
parents:
diff changeset
107 matrix[link.target][link.target].z += link.value; // self loop
65551439a6bb Uploaded
bornea
parents:
diff changeset
108
65551439a6bb Uploaded
bornea
parents:
diff changeset
109 });
65551439a6bb Uploaded
bornea
parents:
diff changeset
110
65551439a6bb Uploaded
bornea
parents:
diff changeset
111 // order based on modularity, name and eigenvector centrality
65551439a6bb Uploaded
bornea
parents:
diff changeset
112 var orders = {
65551439a6bb Uploaded
bornea
parents:
diff changeset
113 name: d3.range(n).sort(function(a, b) { return d3.ascending(nodes[a].name, nodes[b].name); }),
65551439a6bb Uploaded
bornea
parents:
diff changeset
114 EV: d3.range(n).sort(function(a, b) { return nodes[b].EV - nodes[a].EV; }),
65551439a6bb Uploaded
bornea
parents:
diff changeset
115 group: d3.range(n).sort(function(a, b) { return nodes[b].group - nodes[a].group; })
65551439a6bb Uploaded
bornea
parents:
diff changeset
116 };
65551439a6bb Uploaded
bornea
parents:
diff changeset
117
65551439a6bb Uploaded
bornea
parents:
diff changeset
118 // The default sort order.
65551439a6bb Uploaded
bornea
parents:
diff changeset
119 x.domain(orders.name);
65551439a6bb Uploaded
bornea
parents:
diff changeset
120
65551439a6bb Uploaded
bornea
parents:
diff changeset
121 svg.append("rect")
65551439a6bb Uploaded
bornea
parents:
diff changeset
122 .attr("class", "background")
65551439a6bb Uploaded
bornea
parents:
diff changeset
123 .attr("width", width)
65551439a6bb Uploaded
bornea
parents:
diff changeset
124 .attr("height", height)
65551439a6bb Uploaded
bornea
parents:
diff changeset
125 .attr("fill-opacity",0);
65551439a6bb Uploaded
bornea
parents:
diff changeset
126
65551439a6bb Uploaded
bornea
parents:
diff changeset
127 var row = svg.selectAll(".row")
65551439a6bb Uploaded
bornea
parents:
diff changeset
128 .data(matrix)
65551439a6bb Uploaded
bornea
parents:
diff changeset
129 .enter().append("g")
65551439a6bb Uploaded
bornea
parents:
diff changeset
130 .attr("class", "row")
65551439a6bb Uploaded
bornea
parents:
diff changeset
131 .attr("transform", function(d, i) { return "translate(0," + x(i) + ")"; })
65551439a6bb Uploaded
bornea
parents:
diff changeset
132 .each(row);
65551439a6bb Uploaded
bornea
parents:
diff changeset
133
65551439a6bb Uploaded
bornea
parents:
diff changeset
134 row.append("line")
65551439a6bb Uploaded
bornea
parents:
diff changeset
135 .attr("x2", width)
65551439a6bb Uploaded
bornea
parents:
diff changeset
136 .attr("stroke","black");
65551439a6bb Uploaded
bornea
parents:
diff changeset
137
65551439a6bb Uploaded
bornea
parents:
diff changeset
138 row.append("text")
65551439a6bb Uploaded
bornea
parents:
diff changeset
139 .attr("x", -6)
65551439a6bb Uploaded
bornea
parents:
diff changeset
140 .attr("y", x.rangeBand() / 2)
65551439a6bb Uploaded
bornea
parents:
diff changeset
141 .attr("dy", ".32em")
65551439a6bb Uploaded
bornea
parents:
diff changeset
142 .attr("text-anchor", "end")
65551439a6bb Uploaded
bornea
parents:
diff changeset
143 .attr("font-size", 850 * (1/nodes.length))
65551439a6bb Uploaded
bornea
parents:
diff changeset
144 .text(function(d, i) { return nodes[i].name; });
65551439a6bb Uploaded
bornea
parents:
diff changeset
145
65551439a6bb Uploaded
bornea
parents:
diff changeset
146 var column = svg.selectAll(".column")
65551439a6bb Uploaded
bornea
parents:
diff changeset
147 .data(matrix)
65551439a6bb Uploaded
bornea
parents:
diff changeset
148 .enter().append("g")
65551439a6bb Uploaded
bornea
parents:
diff changeset
149 .attr("class", "column")
65551439a6bb Uploaded
bornea
parents:
diff changeset
150 .attr("transform", function(d, i) { return "translate(" + x(i) + ")rotate(-90)"; });
65551439a6bb Uploaded
bornea
parents:
diff changeset
151
65551439a6bb Uploaded
bornea
parents:
diff changeset
152 column.append("line")
65551439a6bb Uploaded
bornea
parents:
diff changeset
153 .attr("x1", -width)
65551439a6bb Uploaded
bornea
parents:
diff changeset
154 .attr("stroke","black");
65551439a6bb Uploaded
bornea
parents:
diff changeset
155
65551439a6bb Uploaded
bornea
parents:
diff changeset
156 column.append("text")
65551439a6bb Uploaded
bornea
parents:
diff changeset
157 .attr("x", 6)
65551439a6bb Uploaded
bornea
parents:
diff changeset
158 .attr("y", x.rangeBand() / 2)
65551439a6bb Uploaded
bornea
parents:
diff changeset
159 .attr("dy", ".32em")
65551439a6bb Uploaded
bornea
parents:
diff changeset
160 .attr("text-anchor", "start")
65551439a6bb Uploaded
bornea
parents:
diff changeset
161 .style("font-style","15px")
65551439a6bb Uploaded
bornea
parents:
diff changeset
162 .attr("font-size", 850 * (1/nodes.length))
65551439a6bb Uploaded
bornea
parents:
diff changeset
163 .text(function(d, i) { return nodes[i].name; });
65551439a6bb Uploaded
bornea
parents:
diff changeset
164
65551439a6bb Uploaded
bornea
parents:
diff changeset
165 function row(row) {
65551439a6bb Uploaded
bornea
parents:
diff changeset
166 var cell = d3.select(this).selectAll(".cell")
65551439a6bb Uploaded
bornea
parents:
diff changeset
167 .data(row.filter(function(d) { return d.z; }))
65551439a6bb Uploaded
bornea
parents:
diff changeset
168 .enter().append("rect")
65551439a6bb Uploaded
bornea
parents:
diff changeset
169 .attr("class", "cell")
65551439a6bb Uploaded
bornea
parents:
diff changeset
170 .attr("x", function(d) { return x(d.x); })
65551439a6bb Uploaded
bornea
parents:
diff changeset
171 .attr("width", x.rangeBand())
65551439a6bb Uploaded
bornea
parents:
diff changeset
172 .attr("height", x.rangeBand())
65551439a6bb Uploaded
bornea
parents:
diff changeset
173 .style("fill-opacity", function(d) { return 0.4 * d.z; })
65551439a6bb Uploaded
bornea
parents:
diff changeset
174 .style("fill", function(d) { return nodes[d.x].group == nodes[d.y].group ? c(nodes[d.x].group) : null; })
65551439a6bb Uploaded
bornea
parents:
diff changeset
175 .on("mouseover", mouseover)
65551439a6bb Uploaded
bornea
parents:
diff changeset
176 .on("mouseout", mouseout);
65551439a6bb Uploaded
bornea
parents:
diff changeset
177 }
65551439a6bb Uploaded
bornea
parents:
diff changeset
178
65551439a6bb Uploaded
bornea
parents:
diff changeset
179 function mouseover(p) {
65551439a6bb Uploaded
bornea
parents:
diff changeset
180 d3.selectAll(".row text").classed("active", function(d, i) { return i == p.y; });
65551439a6bb Uploaded
bornea
parents:
diff changeset
181 d3.selectAll(".column text").classed("active", function(d, i) { return i == p.x; });
65551439a6bb Uploaded
bornea
parents:
diff changeset
182 }
65551439a6bb Uploaded
bornea
parents:
diff changeset
183
65551439a6bb Uploaded
bornea
parents:
diff changeset
184 function mouseout() {
65551439a6bb Uploaded
bornea
parents:
diff changeset
185 d3.selectAll("text").classed("active", false);
65551439a6bb Uploaded
bornea
parents:
diff changeset
186 }
65551439a6bb Uploaded
bornea
parents:
diff changeset
187
65551439a6bb Uploaded
bornea
parents:
diff changeset
188 d3.select("#order").on("change", function() {
65551439a6bb Uploaded
bornea
parents:
diff changeset
189 clearTimeout(timeout);
65551439a6bb Uploaded
bornea
parents:
diff changeset
190 order(this.value);
65551439a6bb Uploaded
bornea
parents:
diff changeset
191 });
65551439a6bb Uploaded
bornea
parents:
diff changeset
192
65551439a6bb Uploaded
bornea
parents:
diff changeset
193
65551439a6bb Uploaded
bornea
parents:
diff changeset
194 function order(value) {
65551439a6bb Uploaded
bornea
parents:
diff changeset
195 x.domain(orders[value]);
65551439a6bb Uploaded
bornea
parents:
diff changeset
196
65551439a6bb Uploaded
bornea
parents:
diff changeset
197 var t = svg.transition().duration(2500);
65551439a6bb Uploaded
bornea
parents:
diff changeset
198
65551439a6bb Uploaded
bornea
parents:
diff changeset
199 t.selectAll(".row")
65551439a6bb Uploaded
bornea
parents:
diff changeset
200 .delay(function(d, i) { return x(i) * 4; })
65551439a6bb Uploaded
bornea
parents:
diff changeset
201 .attr("transform", function(d, i) { return "translate(0," + x(i) + ")"; })
65551439a6bb Uploaded
bornea
parents:
diff changeset
202 .selectAll(".cell")
65551439a6bb Uploaded
bornea
parents:
diff changeset
203 .delay(function(d) { return x(d.x) * 4; })
65551439a6bb Uploaded
bornea
parents:
diff changeset
204 .attr("x", function(d) { return x(d.x); });
65551439a6bb Uploaded
bornea
parents:
diff changeset
205
65551439a6bb Uploaded
bornea
parents:
diff changeset
206 t.selectAll(".column")
65551439a6bb Uploaded
bornea
parents:
diff changeset
207 .delay(function(d, i) { return x(i) * 4; })
65551439a6bb Uploaded
bornea
parents:
diff changeset
208 .attr("transform", function(d, i) { return "translate(" + x(i) + ")rotate(-90)"; });
65551439a6bb Uploaded
bornea
parents:
diff changeset
209 }
65551439a6bb Uploaded
bornea
parents:
diff changeset
210
65551439a6bb Uploaded
bornea
parents:
diff changeset
211 var timeout = setTimeout(function() {
65551439a6bb Uploaded
bornea
parents:
diff changeset
212 order("group");
65551439a6bb Uploaded
bornea
parents:
diff changeset
213 d3.select("#order").property("selectedIndex", 2).node().focus();
65551439a6bb Uploaded
bornea
parents:
diff changeset
214 }, 5000);
65551439a6bb Uploaded
bornea
parents:
diff changeset
215
65551439a6bb Uploaded
bornea
parents:
diff changeset
216
65551439a6bb Uploaded
bornea
parents:
diff changeset
217 };
65551439a6bb Uploaded
bornea
parents:
diff changeset
218 plot_adjacency(data);
65551439a6bb Uploaded
bornea
parents:
diff changeset
219 d3.select("#generate")
65551439a6bb Uploaded
bornea
parents:
diff changeset
220 .on("click", writeDownloadLink);
65551439a6bb Uploaded
bornea
parents:
diff changeset
221
65551439a6bb Uploaded
bornea
parents:
diff changeset
222 function writeDownloadLink(){ //saving entire file instead of just SVG element
65551439a6bb Uploaded
bornea
parents:
diff changeset
223 try {
65551439a6bb Uploaded
bornea
parents:
diff changeset
224 var isFileSaverSupported = !!new Blob();
65551439a6bb Uploaded
bornea
parents:
diff changeset
225 } catch (e) {
65551439a6bb Uploaded
bornea
parents:
diff changeset
226 alert("blob not supported");
65551439a6bb Uploaded
bornea
parents:
diff changeset
227 }
65551439a6bb Uploaded
bornea
parents:
diff changeset
228
65551439a6bb Uploaded
bornea
parents:
diff changeset
229 var html = document.getElementById("adjmatrix").outerHTML
65551439a6bb Uploaded
bornea
parents:
diff changeset
230
65551439a6bb Uploaded
bornea
parents:
diff changeset
231 var blob = new Blob([html], {type: "image/svg+xml"});
65551439a6bb Uploaded
bornea
parents:
diff changeset
232 saveAs(blob, "myProfile.svg");
65551439a6bb Uploaded
bornea
parents:
diff changeset
233 };
65551439a6bb Uploaded
bornea
parents:
diff changeset
234 </script>
65551439a6bb Uploaded
bornea
parents:
diff changeset
235
65551439a6bb Uploaded
bornea
parents:
diff changeset
236
65551439a6bb Uploaded
bornea
parents:
diff changeset
237 </body></html>
65551439a6bb Uploaded
bornea
parents:
diff changeset
238 """
65551439a6bb Uploaded
bornea
parents:
diff changeset
239 with open(sys.argv[3],"w") as x:
65551439a6bb Uploaded
bornea
parents:
diff changeset
240 x.write(adjacency_start+jsondata+adjacency_end)