Commit 25fa0bfee2798ab831c75ced310a05bc1b73b929

Authored by Pavel Govyadinov
1 parent 7c54fa21

Stable, pre-vispy update

GraphCanvas.py
... ... @@ -12,6 +12,7 @@ from vispy import gloo, scene
12 12 from vispy.gloo import set_viewport, set_state, clear, set_blend_color, context
13 13 from vispy.util.transforms import perspective, translate, rotate, scale
14 14 import vispy.gloo.gl as glcore
  15 +from vispy import app
15 16  
16 17 import numpy as np
17 18 import math
... ... @@ -94,7 +95,7 @@ class GraphCanvas(scene.SceneCanvas):
94 95 n = 10
95 96 ne = 10
96 97 #Init dummy structures
97   - self.uniforms = [('u_graph_size', np.float32, 3)]
  98 + #self.uniforms = [('u_graph_size', np.float32, 3)]
98 99 self.data = np.zeros(n, dtype=[('a_position', np.float32, 3),
99 100 ('a_fg_color', np.float32, 4),
100 101 ('a_bg_color', np.float32, 4),
... ... @@ -102,13 +103,30 @@ class GraphCanvas(scene.SceneCanvas):
102 103 ('a_linewidth', np.float32, 1),
103 104 ('a_unique_id', np.float32, 4),
104 105 ])
  106 +
  107 + self.line_data = np.zeros(ne, dtype=[('a_position', np.float32, 3),
  108 + ('a_normal', np.float32, 2),
  109 + ('a_fg_color', np.float32, 4),
  110 + ('a_linewidth', np.float32, 1),
  111 + ])
  112 +
  113 +
  114 + self.clusters = np.zeros(n*4, dtype=[('a_position', np.float32, 3),
  115 + ('a_value', np.float32, 2),
  116 + ('a_bg_color', np.float32, 4),
  117 + ('a_cluster_color', np.float32, 4),
  118 + ('a_arc_length', np.float32, 1),
  119 + ('a_outer_arc_length', np.float32, 4),
  120 + ('a_unique_id', np.float32, 4),
  121 + ])
105 122  
106   - self.clusters = np.zeros(n, dtype=[('a_position', np.float32, 3),
107   - ('a_bg_color', np.float32, 4),
108   - ('a_value', np.float32, 2),
109   - ('a_unique_id', np.float32, 4),
110   - ])
  123 + self.cluster_line_data = np.zeros(ne, dtype=[('a_position', np.float32, 3),
  124 + ('a_normal', np.float32, 2),
  125 + ('a_fg_color', np.float32, 4),
  126 + ('a_linewidth', np.float32, 1),
  127 + ])
111 128  
  129 +
112 130 self.edges = np.random.randint(size=(ne, 2), low=0,
113 131 high=n-1).astype(np.uint32)
114 132 self.edges_s = np.random.randint(size=(ne, 4), low=0,
... ... @@ -134,7 +152,7 @@ class GraphCanvas(scene.SceneCanvas):
134 152 self.vbo = gloo.VertexBuffer(self.data)
135 153 self.vbo_s = gloo.VertexBuffer(self.clusters)
136 154  
137   - #Need to initialize thick lines.
  155 + #Need to initialize thic/k lines.
138 156 self.index = gloo.IndexBuffer(self.edges)
139 157 self.index_s = gloo.IndexBuffer(self.edges_s)
140 158  
... ... @@ -151,35 +169,36 @@ class GraphCanvas(scene.SceneCanvas):
151 169 self.program['u_model'] = self.model
152 170 self.program['u_view'] = self.view
153 171 self.program['u_projection'] = self.projection
154   - self.program['u_graph_size'] = [1.0, 1.0, 1.0]
  172 + #self.program['u_graph_size'] = [1.0, 1.0, 1.0]
155 173 self.program['u_picking'] = False
156 174  
  175 + self.vbo_line = gloo.VertexBuffer(self.line_data)
157 176 #init shades used for the edges in the graph
158 177 self.program_e = gloo.Program(vs, fs)
159   - self.program_e['u_size'] = 1
  178 +# self.program_e['u_size'] = 1
160 179 self.program_e['u_model'] = self.model
161 180 self.program_e['u_view'] = self.view
162 181 self.program_e['u_projection'] = self.projection
163 182 #self.program_e['l_color'] = self.linecolor.astype(np.float32)
164   - self.program_e.bind(self.vbo)
165   -
  183 + self.program_e.bind(self.vbo_line)
  184 +
166 185 #init shaders used to the vertices in the subgraph graph.
167 186 self.program_s = gloo.Program(vert_s, frag_s)
168 187 self.program_s.bind(self.vbo_s)
169 188 self.program_s['u_model'] = self.model
170 189 self.program_s['u_view'] = self.view
171 190 self.program_s['u_projection'] = self.projection
172   - self.program_s['u_graph_size'] = [1.0, 1.0, 1.0]
  191 + #self.program_s['u_graph_size'] = [1.0, 1.0, 1.0]
173 192 self.program_s['u_picking'] = False
174 193  
175 194 #init shaders used for the subgraph-edges
176 195 self.program_e_s = gloo.Program(vs_s, fs_s)
177   - self.program_e_s['u_size'] = 1
178 196 self.program_e_s['u_model'] = self.model
179 197 self.program_e_s['u_view'] = self.view
180 198 self.program_e_s['u_projection'] = self.projection
181 199 #self.program_e['l_color'] = self.linecolor.astype(np.float32)
182   - self.program_e_s.bind(self.vbo_s)
  200 + self.vbo_cluster_lines = gloo.VertexBuffer(self.cluster_line_data)
  201 + self.program_e_s.bind(self.vbo_cluster_lines)
183 202  
184 203  
185 204 #set up the viewport and the gl state.
... ... @@ -187,6 +206,86 @@ class GraphCanvas(scene.SceneCanvas):
187 206  
188 207 set_state(clear_color='white', depth_test=True, blend=True,
189 208 blend_func=('src_alpha', 'one_minus_src_alpha'), depth_func = ('lequal'))
  209 +
  210 +
  211 + self.timer = app.Timer('auto', connect=self.on_timer, start=False)
  212 +
  213 + def on_timer(self, event):
  214 + #get the temporary positions of the vertices (and edges)
  215 + self.old_pos = np.add(self.old_pos, self.slopes)
  216 + #during each iteration set the new positions in the GPU
  217 + self.data['a_position'] = self.old_pos
  218 + #Adjust the edges
  219 + edges = self.G.get_edges()
  220 + for e in range(edges.shape[0]):
  221 + idx = int(4*edges[e][2])
  222 + p0 = self.old_pos[edges[e][0], :]
  223 + p1 = self.old_pos[edges[e][1], :]
  224 + d = np.subtract(p1, p0)
  225 + #d_norm = np.multiply(d, 1/np.sqrt(np.power(d[0],2) + np.power(d[1],2)))
  226 + d_norm = d[0:2]
  227 + d_norm = d_norm / np.sqrt(np.power(d_norm[0],2) + np.power(d_norm[1],2))
  228 + norm = np.zeros((2,), dtype=np.float32)
  229 + norm[0] = d_norm[1]
  230 + norm[1] = d_norm[0]*-1
  231 +
  232 + self.edge_dict[int(edges[e][0]), int(edges[e][1])] = int(edges[e][2])
  233 + self.line_data['a_position'][idx] = p0
  234 + self.line_data['a_normal'][idx] = norm
  235 +
  236 + self.line_data['a_position'][idx+1] = p1
  237 + self.line_data['a_normal'][idx+1] = norm
  238 +
  239 + self.line_data['a_position'][idx+2] = p0
  240 + self.line_data['a_normal'][idx+2] = -norm
  241 +
  242 + self.line_data['a_position'][idx+3] = p1
  243 + self.line_data['a_normal'][idx+3] = -norm
  244 +
  245 + #send data to GPU renderer
  246 + self.vbo.set_data(self.data)
  247 + self.program.bind(self.vbo)
  248 + self.vbo_line = gloo.VertexBuffer(self.line_data)
  249 + self.program_e.bind(self.vbo_line)
  250 +
  251 +
  252 + self.update_clusters(self.old_pos)
  253 + edges = self.G_cluster.get_edges()
  254 +# #generate the vertex buffer and the connections buffer.
  255 + for e in range(edges.shape[0]):
  256 + idx = int(4*edges[e][2])
  257 + p0 = self.cluster_pos[int(edges[e][0])]
  258 + p1 = self.cluster_pos[int(edges[e][1])]
  259 + #p0 = self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(edges[e][0])]
  260 + #p1 = self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(edges[e][1])]
  261 + d = np.subtract(p1, p0)
  262 + #d_norm = np.multiply(d, 1/np.sqrt(np.power(d[0],2) + np.power(d[1],2)))
  263 + d_norm = d[0:2]
  264 + d_norm = d_norm / np.sqrt(np.power(d_norm[0],2) + np.power(d_norm[1],2))
  265 + norm = np.zeros((2,), dtype=np.float32)
  266 + norm[0] = d_norm[1]
  267 + norm[1] = d_norm[0]*-1
  268 + #print(np.sqrt(norm[0]*norm[0] + norm[1]*norm[1]))
  269 + #thickness = G.edge_properties["thickness"][e]
  270 + #self.cluster_dict[int(edges[e][0]), int(edges[e][1])] = int(edges[e][2])
  271 + self.cluster_line_data['a_position'][idx] = p0
  272 + self.cluster_line_data['a_normal'][idx] = norm
  273 +
  274 + self.cluster_line_data['a_position'][idx+1] = p1
  275 + self.cluster_line_data['a_normal'][idx+1] = norm
  276 +
  277 + self.cluster_line_data['a_position'][idx+2] = p0
  278 + self.cluster_line_data['a_normal'][idx+2] = -norm
  279 +
  280 + self.cluster_line_data['a_position'][idx+3] = p1
  281 + self.cluster_line_data['a_normal'][idx+3] = -norm
  282 +
  283 + self.vbo_cluster_lines.set_data(self.cluster_line_data)
  284 + self.vbo_s.set_data(self.clusters)
  285 + self.program_s.bind(self.vbo_s)
  286 + self.program_e_s.bind(self.vbo_cluster_lines)
  287 +
  288 + self.update()
190 289  
191 290 """
192 291 Function that recolors vertices based on the selected statistic
... ... @@ -377,6 +476,14 @@ class GraphCanvas(scene.SceneCanvas):
377 476 else:
378 477 G.edge_properties["RGBA"][e] = [0.0, 0.0, 0.0, 0.8]
379 478  
  479 + """
  480 + Test function that only binds the buffer
  481 + """
  482 + def gen_vertex_vbo_minimalist(self):
  483 + self.update()
  484 + self.vbo.set_data(self.data)
  485 + self.program.bind(self.vbo)
  486 + self.update()
380 487  
381 488 """
382 489 Helper function that generates the framebuffer object that stores the vertices
... ... @@ -418,7 +525,7 @@ class GraphCanvas(scene.SceneCanvas):
418 525 self.data['a_selection'] = G.vertex_properties["selection"].get_array()
419 526 #self.data['a_graph_size'] = [bbu-bbl]
420 527  
421   - self.program['u_graph_size'] = [self.bbu-self.bbl]
  528 + #self.program['u_graph_size'] = [self.bbu-self.bbl]
422 529  
423 530 self.vbo = gloo.VertexBuffer(self.data)
424 531 self.gen_line_vbo(G)
... ... @@ -499,7 +606,7 @@ class GraphCanvas(scene.SceneCanvas):
499 606 #self.program_e['l_color'] = self.linecolor.astype(np.float32)
500 607 self.vbo_line = gloo.VertexBuffer(self.line_data)
501 608 self.index = gloo.IndexBuffer(self.edges)
502   - self.program_e['u_size'] = 1
  609 +# self.program_e['u_size'] = 1
503 610 self.program_e['u_model'] = self.model
504 611 self.program_e['u_view'] = self.view
505 612 self.program_e['u_projection'] = self.projection
... ... @@ -591,7 +698,6 @@ class GraphCanvas(scene.SceneCanvas):
591 698 self.index_clusters_s = gloo.IndexBuffer(self.cluster_edges)
592 699 self.vbo_cluster_lines = gloo.VertexBuffer(self.cluster_line_data)
593 700  
594   - self.program_e_s['u_size'] = 1
595 701 self.program_e_s['u_model'] = self.model
596 702 self.program_e_s['u_view'] = self.view
597 703 self.program_e_s['u_projection'] = self.projection
... ... @@ -648,8 +754,7 @@ class GraphCanvas(scene.SceneCanvas):
648 754 self.program_e_s = gloo.Program(vs_s, fs_s)
649 755 self.index_clusters_s = gloo.IndexBuffer(self.cluster_edges)
650 756 self.vbo_cluster_lines = gloo.VertexBuffer(self.cluster_line_data)
651   -
652   - self.program_e_s['u_size'] = 1
  757 +
653 758 self.program_e_s['u_model'] = self.model
654 759 self.program_e_s['u_view'] = self.view
655 760 self.program_e_s['u_projection'] = self.projection
... ... @@ -721,78 +826,99 @@ class GraphCanvas(scene.SceneCanvas):
721 826 def expand_based_on_clusters(self, G, n):
722 827 pos = G.vertex_properties["pos"].get_2d_array(range(3)).T
723 828 for p in range(pos.shape[0]):
724   - pos[p][0] = pos[p][0] + self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][0]
725   - pos[p][1] = pos[p][1] + self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][1]
726   - pos[p][2] = pos[p][2] + self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][2]
  829 + pos[p][0] = pos[p][0] - self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][0]
  830 + pos[p][1] = pos[p][1] - self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][1]
  831 + pos[p][2] = pos[p][2] - self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][2]
727 832 G.vertex_properties["pos"] = G.new_vertex_property("vector<double>", vals = pos)
728   - for i in range(n):
729   - index = 4*i
730   - #generate the vertex filter for this cluster
731   - num_v_in_cluster = len(np.argwhere(self.labels == i))
732   - vfilt = np.zeros([G.num_vertices(), 1], dtype="bool")
733   - vfilt[np.argwhere(self.labels == i)] = 1
734   - vfilt_prop = G.new_vertex_property("bool", vals = vfilt)
735   - G.set_vertex_filter(vfilt_prop)
  833 +# for i in range(n):
  834 +# index = 4*i
  835 +# #generate the vertex filter for this cluster
  836 +# num_v_in_cluster = len(np.argwhere(self.labels == i))
  837 +# vfilt = np.zeros([G.num_vertices(), 1], dtype="bool")
  838 +# vfilt[np.argwhere(self.labels == i)] = 1
  839 +# vfilt_prop = G.new_vertex_property("bool", vals = vfilt)
  840 +# G.set_vertex_filter(vfilt_prop)
  841 +#
  842 +# #get the filtered properties
  843 +# g = nwt.gt.Graph(G, prune=True, directed=False)
  844 +# positions = g.vertex_properties["pos"].get_2d_array(range(3)).T
  845 +# position = np.sum(positions, 0)/num_v_in_cluster
  846 +# p, v = self.gen_cluster_coords(position, np.sum(g.vertex_properties['degree'].get_array()))
  847 +# self.clusters['a_position'][index:index+4] = np.asarray(p, dtype=np.float32)
  848 +# self.clusters['a_value'][index:index+4] = np.asarray(v, dtype=np.float32)
  849 +# G.clear_filters()
  850 +# self.cluster_pos[i] = position
  851 +# color = G.vertex_properties["RGBA"].get_2d_array(range(4)).T
  852 +# size = nwt.Network.map_vertices_to_range(G, [30*self.pixel_scale, 8*self.pixel_scale], 'degree').get_array()
  853 +#
  854 +# position = G.vertex_properties["pos"].get_2d_array(range(3)).T
  855 +# #for p in range(position.shape[0]):
  856 +# # position[p][0] = position[p][0] + self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][0]
  857 +# # position[p][1] = position[p][1] + self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][1]
  858 +# # position[p][2] = position[p][2] + self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][2]
  859 +# #G.vertex_properties["pos"] = G.new_vertex_property("vector<double>", vals = position)
  860 +#
  861 +#
  862 +# edges = G.get_edges();
  863 +# edges = edges[:, 0:2]
  864 +# #width = nwt.Network.map_edges_to_range(G, [1*self.pixel_scale, 5*self.pixel_scale], 'volume').get_array()
  865 +# #ecolor = G.edge_properties["RGBA"].get_2d_array(range(4)).T
  866 +#
  867 +# self.data = np.zeros(G.num_vertices(), dtype=[('a_position', np.float32, 3),
  868 +# ('a_fg_color', np.float32, 4),
  869 +# ('a_bg_color', np.float32, 4),
  870 +# ('a_size', np.float32, 1),
  871 +# ('a_linewidth', np.float32, 1),
  872 +# ('a_unique_id', np.float32, 4),
  873 +# ('a_selection', np.float32, 1),
  874 +# ])
  875 +#
  876 +# #self.edges = edges.astype(np.uint32)
  877 +# self.data['a_position'] = position
  878 +# #fg color is the color of the ring
  879 +# self.data['a_fg_color'] = 0, 0, 0, 1
  880 +# self.data['a_bg_color'] = color
  881 +# self.data['a_size'] = size
  882 +# self.data['a_linewidth'] = 4.*self.pixel_scale
  883 +# self.data['a_unique_id'] = self.gen_vertex_id(G)
  884 +# self.data['a_selection'] = G.vertex_properties["selection"].get_array()
  885 +# #self.data['a_graph_size'] = [bbu-bbl]
  886 +#
  887 +# self.program['u_graph_size'] = [self.bbu-self.bbl]
  888 +# self.vbo = gloo.VertexBuffer(self.data)
  889 +# self.gen_line_vbo(G)
  890 +# if(self.subgraphs):
  891 +# self.vbo_s = gloo.VertexBuffer(self.clusters)
  892 +# self.index_s = gloo.IndexBuffer(self.edges_s)
  893 +# #self.index = gloo.IndexBuffer(self.edges)
  894 +# self.program_e.bind(self.vbo_line)
  895 +# self.program.bind(self.vbo)
  896 +# if(self.subgraphs):
  897 +# #self.program_e_s.bind(self.vbo_s)
  898 +# self.program_s.bind(self.vbo_s)
  899 +# if DEBUG:
  900 +# print(self.view)
  901 +# self.update()
736 902  
737   - #get the filtered properties
738   - g = nwt.gt.Graph(G, prune=True, directed=False)
739   - positions = g.vertex_properties["pos"].get_2d_array(range(3)).T
740   - position = np.sum(positions, 0)/num_v_in_cluster
741   - p, v = self.gen_cluster_coords(position, np.sum(g.vertex_properties['degree'].get_array()))
  903 +
  904 + """
  905 + Function that updates the cluster positions based on new vertex positions
  906 + in the graph. Primarity used for animation.
  907 + """
  908 + def update_clusters(self, new_pos):
  909 + clusters = self.G.vertex_properties["clusters"].get_array().T
  910 + for i in range(self.n_c):
  911 + idx = np.argwhere(clusters == i)
  912 + pos = np.sum(new_pos[idx], 0)/len(idx)
  913 + self.cluster_pos[i] = pos.reshape(3)
  914 + index = i*4
  915 + p, v = self.gen_cluster_coords(self.cluster_pos[i], self.cluster_size[i])
742 916 self.clusters['a_position'][index:index+4] = np.asarray(p, dtype=np.float32)
743 917 self.clusters['a_value'][index:index+4] = np.asarray(v, dtype=np.float32)
744   - G.clear_filters()
745   - self.cluster_pos[i] = position
746   - color = G.vertex_properties["RGBA"].get_2d_array(range(4)).T
747   - size = nwt.Network.map_vertices_to_range(G, [30*self.pixel_scale, 8*self.pixel_scale], 'degree').get_array()
748   -
749   - position = G.vertex_properties["pos"].get_2d_array(range(3)).T
750   - #for p in range(position.shape[0]):
751   - # position[p][0] = position[p][0] + self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][0]
752   - # position[p][1] = position[p][1] + self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][1]
753   - # position[p][2] = position[p][2] + self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][2]
754   - #G.vertex_properties["pos"] = G.new_vertex_property("vector<double>", vals = position)
755   - edges = G.get_edges();
756   - edges = edges[:, 0:2]
757   - #width = nwt.Network.map_edges_to_range(G, [1*self.pixel_scale, 5*self.pixel_scale], 'volume').get_array()
758   - #ecolor = G.edge_properties["RGBA"].get_2d_array(range(4)).T
759   -
760   - self.data = np.zeros(G.num_vertices(), dtype=[('a_position', np.float32, 3),
761   - ('a_fg_color', np.float32, 4),
762   - ('a_bg_color', np.float32, 4),
763   - ('a_size', np.float32, 1),
764   - ('a_linewidth', np.float32, 1),
765   - ('a_unique_id', np.float32, 4),
766   - ('a_selection', np.float32, 1),
767   - ])
768   -
769   - #self.edges = edges.astype(np.uint32)
770   - self.data['a_position'] = position
771   - #fg color is the color of the ring
772   - self.data['a_fg_color'] = 0, 0, 0, 1
773   - self.data['a_bg_color'] = color
774   - self.data['a_size'] = size
775   - self.data['a_linewidth'] = 4.*self.pixel_scale
776   - self.data['a_unique_id'] = self.gen_vertex_id(G)
777   - self.data['a_selection'] = G.vertex_properties["selection"].get_array()
778   - #self.data['a_graph_size'] = [bbu-bbl]
779   -
780   - self.program['u_graph_size'] = [bbu-bbl]
781   - self.vbo = gloo.VertexBuffer(self.data)
782   - self.gen_line_vbo(G)
783   - if(self.subgraphs):
784   - self.vbo_s = gloo.VertexBuffer(self.clusters)
785   - self.index_s = gloo.IndexBuffer(self.edges_s)
786   - #self.index = gloo.IndexBuffer(self.edges)
787   - self.program_e.bind(self.vbo_line)
788   - self.program.bind(self.vbo)
789   - if(self.subgraphs):
790   - #self.program_e_s.bind(self.vbo_s)
791   - self.program_s.bind(self.vbo_s)
792   - if DEBUG:
793   - print(self.view)
794   - self.update()
795   -
  918 + self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(i)] = self.cluster_pos[i]
  919 +
  920 +
  921 +
796 922  
797 923 """
798 924 Function that generates the clusters for an unclustered graph
... ... @@ -827,7 +953,7 @@ class GraphCanvas(scene.SceneCanvas):
827 953 #self.clusters['a_fg_color'] = 1., 1., 1., 0.0
828 954 #self.clusters['a_linewidth'] = 4.*self.pixel_scale
829 955  
830   - G.vertex_properties["pos"] = nwt.gt.sfdp_layout(G, groups = G.vertex_properties["clusters"], pos = G.vertex_properties["pos"])
  956 + G.vertex_properties["pos"] = nwt.gt.sfdp_layout(G, groups = G.vertex_properties["clusters"], pos = G.vertex_properties["pos"], C = 1.0, K = 10)
831 957 temp = []
832 958 temp_pos = []
833 959 #Find the global total of the metric.
... ... @@ -897,14 +1023,11 @@ class GraphCanvas(scene.SceneCanvas):
897 1023 print(self.clusters['a_outer_arc_length'])
898 1024 maximum = max(temp)
899 1025 minimum = min(temp)
900   - if len(temp) > 1:
901   - temp = ((temp-minimum)/(maximum-minimum)*(60*self.pixel_scale)+20*self.pixel_scale)
902   - else:
903   - temp = [60*self.pixel_scale]
  1026 + temp = ((temp-minimum)/(maximum-minimum)*(60*self.pixel_scale)+20*self.pixel_scale)*2.0
904 1027 for i in range(num_clusters):
905 1028 index = i*4
906 1029 index_t = i*2
907   - p, v = self.gen_cluster_coords(temp_pos[i], temp[i]*2.0)
  1030 + p, v = self.gen_cluster_coords(temp_pos[i], temp[i])
908 1031 self.clusters['a_position'][index:index+4] = np.asarray(p, dtype=np.float32)
909 1032 self.clusters['a_value'][index:index+4] = np.asarray(v, dtype=np.float32)
910 1033  
... ... @@ -913,6 +1036,7 @@ class GraphCanvas(scene.SceneCanvas):
913 1036 #self.edges_s[i][0:4] = np.asarray(range(index, index+4), dtype=np.uint32)
914 1037 #self.edges_s[i]
915 1038 self.cluster_pos = temp_pos
  1039 + self.cluster_size = temp
916 1040 #self.expand_based_on_clusters(G, self.n_c)
917 1041 G.clear_filters()
918 1042 # self.edges_s[1][0:4] = np.asarray(range(0, 0+4), dtype=np.uint32)
... ... @@ -924,7 +1048,7 @@ class GraphCanvas(scene.SceneCanvas):
924 1048 # self.edges_s[0][5] = index+2
925 1049 #self.clusters['a_size'] = temp
926 1050 self.gen_cluster_line_vbo(G)
927   - self.program_s['u_graph_size'] = [bbu-bbl]
  1051 + #self.program_s['u_graph_size'] = [bbu-bbl]
928 1052 #if len(temp_e) > 0:
929 1053 # self.edges_s = np.unique(np.asarray(temp_e, np.uint32), axis=0)
930 1054 #else:
... ... @@ -1003,7 +1127,7 @@ class GraphCanvas(scene.SceneCanvas):
1003 1127 self.data['a_selection'] = G.vertex_properties["selection"].get_array()
1004 1128 #self.data['a_graph_size'] = [bbu-bbl]
1005 1129  
1006   - self.program['u_graph_size'] = [bbu-bbl]
  1130 + #self.program['u_graph_size'] = [bbu-bbl]
1007 1131  
1008 1132 self.vbo = gloo.VertexBuffer(self.data)
1009 1133 self.gen_line_vbo(G)
... ... @@ -1033,6 +1157,7 @@ class GraphCanvas(scene.SceneCanvas):
1033 1157 Overloaded function that is called during every self.update() call
1034 1158 """
1035 1159 def on_draw(self, event):
  1160 + gloo.clear()
1036 1161 clear(color='white', depth=True)
1037 1162 self.program_e.draw('triangles', indices=self.index)
1038 1163 self.program.draw('points')
... ... @@ -1041,6 +1166,49 @@ class GraphCanvas(scene.SceneCanvas):
1041 1166 self.program_e_s.draw('triangles', indices=self.index_clusters_s)
1042 1167 self.program_s.draw('triangles', indices=self.index_s)
1043 1168  
  1169 +
  1170 +# """
  1171 +# A function to animate from one layout to another layout given a new G.
  1172 +# """
  1173 + def animate(self, old_pos, new_pos):
  1174 +
  1175 +# old_pos = self.G.vertex_properties["pos"].get_2d_array(range(3)).T
  1176 +# new_pos = new_G.vertex_properties["pos"].get_2d_array(range(3)).T
  1177 + #we want to animate the move over 2 seconds. At 60 frames per second
  1178 + #we'd get 120 different positions along the transitional distance.
  1179 + self.new_pos = new_pos
  1180 + self.old_pos = old_pos
  1181 + self.slopes = np.zeros(old_pos.shape)
  1182 + for i in range(old_pos.shape[0]):
  1183 + self.slopes[i, 0] = (new_pos[i, 0] - old_pos[i, 0])/120.0
  1184 + self.slopes[i, 1] = (new_pos[i, 1] - old_pos[i, 1])/120.0
  1185 +
  1186 + #self.timer.start()
  1187 + #for i in range(120):
  1188 + #self.old_pos = np.add(old_pos, self.slopes)
  1189 + self.timer.start(iterations=120)
  1190 + #self.data['a_position'] = old_pos
  1191 + #self.gen_vertex_vbo_minimalist()
  1192 + #self.update()
  1193 +## self.gen_line_vbo(self.G)
  1194 +## self.program_e.bind(self.vbo_line)
  1195 +## self.program.bind(self.vbo)
  1196 +# self.update()
  1197 +# #self.program_e.draw('lines')
  1198 +# print(i)
  1199 + #self.timer.stop()
  1200 +
  1201 + #self.G = new_G
  1202 + #self.gen_vertex_vbo(self.G)
  1203 + #self.update()
  1204 +
  1205 +# def on_timer(self, event):
  1206 +# self.vbo = gloo.VertexBuffer(self.data)
  1207 +# #self.gen_line_vbo(self.G)
  1208 +# #self.program_e.bind(self.vbo_line)
  1209 +# self.program.bind(self.vbo)
  1210 +# self.update()
  1211 +# gloo.wrappers.flush()
1044 1212 """
1045 1213 Function performed during a mouse click (either right or left)
1046 1214 gets the unique id of the object drawn underneath the cursor
... ... @@ -1356,7 +1524,7 @@ class GraphCanvas(scene.SceneCanvas):
1356 1524  
1357 1525 #get the filtered properties
1358 1526 g = nwt.gt.Graph(G, prune=True, directed=False)
1359   - p, v = self.gen_cluster_coords(pos, np.sum(g.vertex_properties['degree'].get_array()))
  1527 + p, v = self.gen_cluster_coords(pos, self.cluster_size[c_id])
1360 1528 self.clusters['a_position'][index:index+4] = np.asarray(p, dtype=np.float32)
1361 1529 self.clusters['a_value'][index:index+4] = np.asarray(v, dtype=np.float32)
1362 1530 G.clear_filters()
... ...
GraphWidget.py
... ... @@ -10,6 +10,8 @@ from GraphCanvas import GraphCanvas
10 10 from pyqtgraph.Qt import QtCore, QtGui, QtWidgets
11 11 import network_dep as nwt
12 12  
  13 +import numpy as np
  14 +
13 15 DEBUG = False
14 16  
15 17 """
... ... @@ -69,6 +71,9 @@ class GraphWidget(QtGui.QWidget):
69 71 #EXP = menu.addAction('Export VTK')
70 72 #EXP_adv = menu.addAction('Export VTK Advanced')
71 73 NL = menu.addAction('New Layout')
  74 + NSL = menu.addAction('New Spring-Onion Layout (sum)')
  75 + NSLMI = menu.addAction('New Spring-Onion Layout(max)')
  76 + EXPAND = menu.addAction('Expand')
72 77 action = menu.exec_(event.native.globalPos())
73 78 if DEBUG:
74 79 print(action)
... ... @@ -108,11 +113,43 @@ class GraphWidget(QtGui.QWidget):
108 113 #self.cb.currentIndexChanged.connect(self.selection_change)
109 114 #self.cb.show()
110 115 if action == NL:
111   - self.canvas.G = nwt.Network.gen_new_fd_layout(self.canvas.G)
112   - self.canvas.gen_vertex_vbo(self.canvas.G)
  116 + old_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T
  117 + nG = nwt.Network.gen_new_fd_layout(self.canvas.G)
  118 + new_pos = nG.vertex_properties["pos"].get_2d_array(range(3)).T
  119 + self.canvas.animate(old_pos, new_pos)
  120 +
  121 + #self.canvas.gen_vertex_vbo(self.canvas.G)
113 122 #self.canvas.set_data(self.canvas.G, self.canvas.bbl, self.canvas.bbu)
  123 + #self.canvas.expand_clusters(self.canvas.G, self.canvas.n_c)
  124 + if action == NSL:
  125 + old_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T
  126 + nG = nwt.Network.gen_spring_onion_layout(self.canvas.G, 'degree', 1.0, 1000, 0.01, 1.0)
  127 + new_pos = nG.vertex_properties["pos"].get_2d_array(range(3)).T
  128 +
  129 + self.canvas.animate(old_pos, new_pos)
  130 + #self.canvas.set_data(nG, self.canvas.bbl, self.canvas.bbu)
  131 +
  132 + #self.canvas.gen_vertex_vbo(self.canvas.G)
  133 + #self.canvas.expand_clusters(self.canvas.G, self.canvas.n_c)
  134 + if action == NSLMI:
  135 + old_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T
  136 + nG = nwt.Network.gen_spring_onion_layout(self.canvas.G, 'degree', 1.0, 1000, 0.01, 1.0, False)
  137 + new_pos = nG.vertex_properties["pos"].get_2d_array(range(3)).T
  138 +
  139 + self.canvas.animate(old_pos, new_pos)
  140 + #self.canvas.set_data(nG, self.canvas.bbl, self.canvas.bbu)
  141 + #self.canvas.expand_clusters(self.canvas.G, self.canvas.n_c)
  142 +
  143 + #self.canvas.gen_vertex_vbo(self.canvas.G)
  144 +
  145 + if action == EXPAND:
  146 + #self.canvas.gen_vertex_vbo(self.canvas.G)
  147 + old_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T
114 148 self.canvas.expand_clusters(self.canvas.G, self.canvas.n_c)
115   -
  149 + new_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T
  150 + #self.canvas.expand_clusters(self.canvas.G, self.canvas.n_c)
  151 +
  152 + self.canvas.animate(old_pos, new_pos)
116 153 #self.canvas.size_vertices(self.canvas.G, 'degree_volume')
117 154 else:
118 155 if self.canvas.view[0][0] >= 0.0010:
... ... @@ -144,6 +181,12 @@ class GraphWidget(QtGui.QWidget):
144 181 def on_mouse_double_click(self, event):
145 182 self.canvas.update_path(event)
146 183 self.select.emit(self.canvas.get_path())
  184 + old_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T
  185 + nG = nwt.Network.gen_new_fd_layout(self.canvas.G)
  186 + # def animate(self, new_G):
  187 +#
  188 + new_pos = nG.vertex_properties["pos"].get_2d_array(range(3)).T
  189 + self.canvas.animate(old_pos, new_pos)
147 190  
148 191 """
149 192 Handles the mouse release event.
... ...
GuiVisPy_tube.py
... ... @@ -39,7 +39,6 @@ top = QtGui.QWidget()
39 39 top.resize(900, 900)
40 40  
41 41  
42   -hist = pg.PlotWidget()
43 42 #fibers = FiberView()
44 43 fibers = TubeWidget()
45 44 fibers.canvas.create_native()
... ... @@ -66,15 +65,16 @@ top.setLayout(layout)
66 65 top.show()
67 66  
68 67  
69   -def draw_histogram(G, value):
70   - vals = G.edge_properties[value].get_array()
71   - y, x = np.histogram(vals,40)
72   - hist.plot(x,y, stepMode=True, fillLevel=0, brush=(0,0,255,150))
  68 +#def draw_histogram(G, value):
  69 +# vals = G.edge_properties[value].get_array()
  70 +# y, x = np.histogram(vals,40)
  71 +# hist.plot(x,y, stepMode=True, fillLevel=0, brush=(0,0,255,150))
73 72  
74 73 def load_nwt(filepath):
75 74 net = nwt.Network(filepath)
76 75 G = net.createFullGraph_gt()
77 76 G = net.filterDisconnected(G)
  77 + #G = net.gen_spring_onion_layout(G, 'degree', 1.0, 1000, 0.01, 1.0)
78 78 #G = net.filterFullGraph_gt(G, erode=True)
79 79 #G = net.filterFullGraph_gt(G, erode=True)
80 80 #G = net.gen_new_fd_layout(G)
... ... @@ -104,7 +104,7 @@ center = (bbu-bbl)/2.0
104 104 #fibers.opts['distance'] = 5
105 105 # item = NodeItem(G)
106 106 # graph.addItem(item)
107   -draw_histogram(G, "length")
  107 +#draw_histogram(G, "length")
108 108 graph.canvas.set_data(G, bbl, bbu)
109 109 fibers.canvas.set_data(G, bbl, bbu, 16)
110 110 #fibers.draw_all(G, center, fibers, graph, node_tex)
... ...
TubeCanvas.py
... ... @@ -68,7 +68,7 @@ class TubeDraw(scene.SceneCanvas):
68 68 blend_func=('src_alpha', 'one_minus_src_alpha'), depth_func = ('lequal'))
69 69 #set_blend_color(color='black')
70 70 #set_state('translucent')
71   - self.program['u_LightPos'] = [0., 0., -1000.]
  71 + #self.program['u_LightPos'] = [0., 0., -1000.]
72 72 #self.camera = self.central_widget.add_view()
73 73 #self.camera.camera = 'turntable'
74 74 self.down = False
... ... @@ -107,7 +107,7 @@ class TubeDraw(scene.SceneCanvas):
107 107 self.projection = perspective(90.0, self.physical_size[0]/self.physical_size[1], 1.0, 1000.0)
108 108 #self.projection = perspective(90.0, 1.0, -1.0, 1.0)
109 109 self.program['u_model'] = self.model
110   - self.program['u_LightPos'] = [0., 0., 1000.]
  110 + #self.program['u_LightPos'] = [0., 0., 1000.]
111 111 #self.program['u_view'] = self.view
112 112 self.program['u_projection'] = self.projection
113 113 self.program.bind(self.vbo)
... ... @@ -481,8 +481,8 @@ class TubeDraw(scene.SceneCanvas):
481 481 #coord[1] = 0
482 482 #coord2[1] = 0
483 483  
484   - theta = (coord[0]-coord2[0])*360.0/2.0/np.pi
485   - phi = (coord[1]-coord2[1])*360.0/2.0/np.pi
  484 + phi = (coord[0]-coord2[0])*360.0/2.0/np.pi
  485 + theta = (coord[1]-coord2[1])*360.0/2.0/np.pi
486 486 if DEBUG:
487 487 print(theta*360.0/2.0/np.pi, -phi*360.0/2.0/np.pi)
488 488 self.camera = self.camera - self.translate
... ... @@ -533,7 +533,7 @@ class TubeDraw(scene.SceneCanvas):
533 533 print("current position ", self.camera, " and up vector ", self.up)
534 534 self.program['u_eye'] = self.camera
535 535 self.program['u_up'] = self.up
536   - self.program['u_LightPos'] = [self.camera[0], self.camera[1], self.camera[2]]
  536 + #self.program['u_LightPos'] = [self.camera[0], self.camera[1], self.camera[2]]
537 537 self.update()
538 538  
539 539 #reverts the mouse state during release.
... ...
TubeWidget.py
... ... @@ -14,7 +14,7 @@ Created on Mon Aug 5 15:53:16 2019
14 14 from pyqtgraph.Qt import QtCore, QtGui, QtWidgets
15 15 from TubeCanvas import TubeDraw
16 16 import numpy as np
17   -import trimesh as tm
  17 +#import trimesh as tm
18 18  
19 19 DEBUG = False
20 20  
... ...
graph_shaders.py
... ... @@ -14,14 +14,14 @@ vert = &quot;&quot;&quot;
14 14 #version 120
15 15 // Uniforms
16 16 // ------------------------------------
  17 +uniform float u_size;
  18 +uniform float u_antialias;
17 19 uniform mat4 u_model;
18 20 uniform mat4 u_view;
19 21 uniform mat4 u_projection;
20   -uniform float u_antialias;
21   -uniform float u_size;
  22 +//uniform vec3 u_graph_size;
22 23 uniform bool u_picking;
23 24  
24   -uniform vec3 u_graph_size;
25 25 // Attributes
26 26 // ------------------------------------
27 27 attribute vec3 a_position;
... ... @@ -65,7 +65,6 @@ uniform mat4 u_model;
65 65 uniform mat4 u_view;
66 66 uniform mat4 u_projection;
67 67 uniform float u_antialias;
68   -uniform float u_size;
69 68 uniform bool u_picking;
70 69  
71 70 // Varyings
... ... @@ -192,8 +191,6 @@ attribute vec3 a_position;
192 191 attribute vec2 a_normal;
193 192 attribute vec4 a_fg_color;
194 193 attribute float a_linewidth;
195   -//attribute vec4 a_unique_id;
196   -//attribute vec4 l_color;
197 194  
198 195 // Varyings
199 196 // ------------------------------------
... ... @@ -253,4 +250,4 @@ float new_alpha(float zoom_level)
253 250 return val;
254 251  
255 252 }
256   -"""
257 253 \ No newline at end of file
  254 +"""
... ...
network_dep.py
... ... @@ -1115,9 +1115,163 @@ class Network:
1115 1115 G_0.clear_filters()
1116 1116  
1117 1117 return graph
  1118 +
  1119 + '''
  1120 + Generates a layout based a 3 neighbors spring system.
  1121 + Vertices within 1 edge, 2 edges and 3 edges act upon one another based on
  1122 + Hooke's law. 1e springs are the stronges and strength decreases as edges get further away
  1123 +
  1124 + '''
  1125 + def gen_spring_onion_layout(G, v_property, k, n_steps, time_step, min_distance, Sum=True):
  1126 + start = time.time()
  1127 +
  1128 + one_neighbors = G.new_vertex_property("vector<int>")
  1129 + o1_n = []
  1130 + two_neighbors = G.new_vertex_property("vector<int>")
  1131 + o2_n = []
  1132 + three_neighbors = G.new_vertex_property("vector<int>")
  1133 + o3_n = []
  1134 + #generate the map of 1, 2 and 3 neighborhood vertices.
  1135 + for v in G.vertices():
  1136 + one_n = []
  1137 + two_n = []
  1138 + three_n = []
  1139 + #find all 1 neighbors
  1140 + for i in v.all_neighbors():
  1141 + one_n.append(int(i))
  1142 + if(len(one_n) == 0):
  1143 + print("WTF")
  1144 + #find all 2 neighbors
  1145 + for i in one_n:
  1146 + for j in G.vertex(i).all_neighbors():
  1147 + if(int(j) not in one_n):
  1148 + two_n.append(int(j))
  1149 +
  1150 + #find all 3 neighbors
  1151 + for i in two_n:
  1152 + for j in G.vertex(i).all_neighbors():
  1153 + if(int(j) not in one_n and int(j) not in two_n):
  1154 + three_n.append(int(j))
1118 1155  
  1156 + #we do not keep ones that have already counted, i.e. a vertex
  1157 + #appears in all 3 arrays only once.
  1158 + #it's ok to add self to any array because the distance -k(x=0) = 0
  1159 + one_neighbors[v] = np.asarray(one_n)
  1160 + o1_n.append(np.asarray(one_n))
  1161 + two_neighbors[v] = np.asarray(two_n)
  1162 + o2_n.append(np.asarray(two_n))
  1163 + three_neighbors[v] = np.asarray(three_n)
  1164 + o3_n.append(np.asarray(three_n))
1119 1165  
1120   -
  1166 + print("generating neighborhoods: ", time.time() - start)
  1167 + start = time.time()
  1168 + G.vertex_properties["1_neighbor"] = one_neighbors
  1169 + G.vertex_properties["2_neighbor"] = two_neighbors
  1170 + G.vertex_properties["3_neighbor"] = three_neighbors
  1171 +
  1172 + cooling = 1.0
  1173 + cooling_step = cooling/n_steps
  1174 +
  1175 +
  1176 +# #get points of the centers of every cluster
  1177 +# #generate voronoi region and plot it.
  1178 +# fig, ax = plt.subplots(2, 1, sharex='col', sharey='row')
  1179 +# fig.tight_layout()
  1180 +# grid = plt.GridSpec(2,1)
  1181 +# grid.update(wspace=0.025, hspace=0.2)
  1182 +# ax[0].axis('off')
  1183 +# ax[1].axis('off')
  1184 +#
  1185 +#
  1186 +# before = fig.add_subplot(grid[0])
  1187 +# after = fig.add_subplot(grid[1])
  1188 +# pts = G.vertex_properties["pos"].get_2d_array(range(2)).T
  1189 +# before.scatter(pts[:,0], pts[:, 1], marker="*")
  1190 +#
  1191 +# #plot the connections of the top level graph
  1192 +# for e in G.edges():
  1193 +# coord = G.vertex_properties["pos"][e.source()]
  1194 +# coord2 = G.vertex_properties["pos"][e.target()]
  1195 +# x = [coord[0], coord2[0]]
  1196 +# y = [coord[1], coord2[1]]
  1197 +# before.plot(x, y, 'go--', linewidth=1, markersize=1)
  1198 +#
  1199 +# #plot the connections of the top level graph
  1200 +# for e in G.edges():
  1201 +# coord = G.vertex_properties["pos"][e.source()]
  1202 +# coord2 = G.vertex_properties["pos"][e.target()]
  1203 +# x = [coord[0], coord2[0]]
  1204 +# y = [coord[1], coord2[1]]
  1205 +# before.plot(x, y, 'go--', linewidth=1, markersize=1)
  1206 +
  1207 + velocities = np.zeros([G.num_vertices(), 3])
  1208 + print("setting neighborhoods: ", time.time() - start)
  1209 + start = time.time()
  1210 +
  1211 + pos = G.vertex_properties["pos"].get_2d_array(range(3)).T
  1212 + weight = G.vertex_properties[v_property].get_array().T
  1213 +
  1214 + for n in range(n_steps+1):
  1215 + forces = np.zeros([G.num_vertices(), 3])
  1216 + #pos = G.vertex_properties["pos"].get_2d_array(range(2)).T
  1217 + if Sum:
  1218 + for v in G.vertices():
  1219 + for i in o1_n[int(v)]:
  1220 + x = pos[int(i), :] - pos[int(v), :]
  1221 + forces[int(v), 0] += -k*(x[0])
  1222 + forces[int(v), 1] += -k*(x[1])
  1223 + for i in o2_n[int(v)]:
  1224 + x = pos[int(i)] - pos[int(v)]
  1225 + forces[int(v), 0] += -k*(x[0])/2.0
  1226 + forces[int(v), 1] += -k*(x[1])/2.0
  1227 + for i in o3_n[int(v)]:
  1228 + x = pos[int(i)] - pos[int(v)]
  1229 + forces[int(v), 0] += -k*(x[0])/4.0
  1230 + forces[int(v), 1] += -k*(x[1])/4.0
  1231 + else:
  1232 + for v in G.vertices():
  1233 + for i in o3_n[int(v)]:
  1234 + x = pos[int(i)] - pos[int(v)]
  1235 + forces[int(v), 0] = -k*(x[0])/4.0
  1236 + forces[int(v), 1] = -k*(x[1])/4.0
  1237 +
  1238 + forces[:, 0] = forces[:, 0]/weight[:]
  1239 + forces[:, 1] = forces[:, 1]/weight[:]
  1240 +# if n < 1:
  1241 +# velocities = forces * time_step*G.num_vertices()
  1242 +# else:
  1243 +# pos += velocities * time_step
  1244 +# velocities = forces * time_step * cooling
  1245 +# cooling -= cooling_step
  1246 +#
  1247 +
  1248 + for v in G.vertices():
  1249 + if n < 1:
  1250 + velocities = forces * time_step
  1251 + #G.vertex_properties["pos"][v] = pos[int(v), :] + forces[int(v), :] * time_step
  1252 + else:
  1253 + pos[int(v), :] = pos[int(v), :] + velocities[int(v), :] * time_step
  1254 + velocities = forces * time_step * cooling
  1255 + cooling -= cooling_step
  1256 +
  1257 + G.vertex_properties["pos"] = G.new_vertex_property("vector<double>", vals = pos)
  1258 + print("calculating new positions: ", time.time() - start)
  1259 +# pts = G.vertex_properties["pos"].get_2d_array(range(2)).T
  1260 +# after.scatter(pts[:,0], pts[:, 1], marker="*")
  1261 +#
  1262 +# #plot the connections of the top level graph
  1263 +# for e in G.edges():
  1264 +# coord = G.vertex_properties["pos"][e.source()]
  1265 +# coord2 = G.vertex_properties["pos"][e.target()]
  1266 +# x = [coord[0], coord2[0]]
  1267 +# y = [coord[1], coord2[1]]
  1268 +# after.plot(x, y, 'go--', linewidth=1, markersize=1)
  1269 +#
  1270 +# plt.show()
  1271 + return G
  1272 +
  1273 +
  1274 +
1121 1275  
1122 1276 '''
1123 1277 Creates a graph from a list of nodes and a list of edges
... ... @@ -1537,8 +1691,9 @@ class Network:
1537 1691  
1538 1692  
1539 1693 def gen_new_fd_layout(G):
1540   - pos = gt.sfdp_layout(G, C = 1.0, K = 10)
1541   - G.vertex_properties["pos"] = pos
  1694 + G.vertex_properties["pos"] = gt.sfdp_layout(G, groups = G.vertex_properties["clusters"], pos = G.vertex_properties["pos"], C = 1.0, K = 10)
  1695 + #pos = gt.sfdp_layout(G, C = 1.0, K = 10)
  1696 + #G.vertex_properties["pos"] = pos
1542 1697 return G
1543 1698  
1544 1699 def map_edges_to_range(G, rng, propertymap):
... ... @@ -1668,7 +1823,7 @@ class Network:
1668 1823 G.vertex_properties["partition"] = G.new_vertex_property("vector<boolean>", array_cluster_bel)
1669 1824 G.edge_properties["partition"] = G.new_edge_property("vector<boolean>", array_ecluster_bel)
1670 1825 j = 0
1671   - gt.graph_draw(G, pos = gt.sfdp_layout(G), output="Graph_full.pdf")
  1826 + #gt.graph_draw(G, pos = gt.sfdp_layout(G), output="Graph_full.pdf")
1672 1827 for i in range(c):
1673 1828 TFv = G.new_vertex_property("bool", vals=array_cluster_bel[i,:])
1674 1829 TFe = G.new_edge_property("bool", vals=array_ecluster_bel[i,:])
... ...
subgraph_shaders.py
... ... @@ -14,7 +14,7 @@ vert_s = &quot;&quot;&quot;
14 14 uniform mat4 u_model;
15 15 uniform mat4 u_view;
16 16 uniform mat4 u_projection;
17   -uniform vec3 u_graph_size;
  17 +//uniform vec3 u_graph_size;
18 18 uniform bool u_picking;
19 19 // Attributes
20 20 // ------------------------------------
... ... @@ -214,8 +214,6 @@ attribute vec3 a_position;
214 214 attribute vec2 a_normal;
215 215 attribute vec4 a_fg_color;
216 216 attribute float a_linewidth;
217   -//attribute vec4 a_unique_id;
218   -//attribute vec4 l_color;
219 217  
220 218 // Varyings
221 219 // ------------------------------------
... ... @@ -273,4 +271,4 @@ float new_alpha(float zoom_level)
273 271 }
274 272 return val;
275 273 }
276   -"""
277 274 \ No newline at end of file
  275 +"""
... ...
tube_shaders.py
... ... @@ -11,7 +11,6 @@ VERT_SHADER = &quot;&quot;&quot;
11 11 // Uniforms
12 12 // ------------------------------------
13 13 uniform vec4 u_bb[26];
14   -uniform vec3 u_LightPost;
15 14 uniform mat4 u_model;
16 15 //uniform mat4 u_view;
17 16 uniform mat4 u_projection;
... ... @@ -53,8 +52,8 @@ void main (void) {
53 52 v_position = vec3(MV*vec4(a_position, 1.0));
54 53 vt_position = vec3(a_position);
55 54 v_fg_color = a_fg_color;
56   - v_selection = a_selection;
57 55 gl_Position = MVP * vec4(a_position, 1.0);
  56 + v_selection = a_selection;
58 57 }
59 58  
60 59 mat4 make_view(vec3 eye, vec3 target, vec3 up)
... ... @@ -87,7 +86,6 @@ FRAG_SHADER = &quot;&quot;&quot;
87 86 // Uniforms
88 87 // ------------------------------------
89 88 uniform vec3 u_bb[26];
90   -uniform vec3 u_LightPos;
91 89 uniform mat4 u_model;
92 90 //uniform mat4 u_view;
93 91 uniform mat4 u_projection;
... ... @@ -198,7 +196,7 @@ float new_alpha()
198 196 float bin_alpha(float alpha)
199 197 {
200 198  
201   -
  199 +
202 200 if(alpha > 0.8)
203 201 return 0.0;
204 202 else if(alpha > 0.6)
... ... @@ -211,7 +209,7 @@ float bin_alpha(float alpha)
211 209 return 1.0;
212 210 else
213 211 return 1.0;
214   -
  212 +
215 213 // if(alpha > 0.9)
216 214 // return 0.0;
217 215 // else if(alpha > 0.8)
... ...
voronoi_test.py
... ... @@ -31,32 +31,50 @@ import network_dep as nwt
31 31 class Polygon_mass:
32 32 def __init__(self, G):
33 33 self.G = G
  34 + print(nwt.gt.graph_tool.topology.is_planar(G))
34 35 self.get_aabb()
35 36 self.gen_polygon()
36 37 self.torque = []
  38 + self.forces_r = np.zeros(2)
  39 + self.forces_a = np.zeros(2)
37 40 self.vel = 0.0
38 41 self.aa = 0.0
  42 + self.degree = 0
39 43  
40 44  
41 45 def clear_torques(self):
42 46 self.torque = []
43 47  
  48 + def clear_forces(self):
  49 + self.forces_r = np.zeros(2)
  50 + self.forces_a = np.zeros(2)
  51 +
  52 + def set_degree(self, degree):
  53 + self.degree = degree
  54 +
44 55 def add_torque(self, p, f):
45 56 #direction of the torque = cross of (r, f)
46 57 #magnitude = ||r||*||f||*sin(theta)
47 58 #r = level arm vector
48 59 d = self.CoM - p
49   - r = np.linalg.norm(self.CoM - p)
50   - theta = math.acos(np.dot(d, f)/np.dot(d, d)/np.dot(f, f))
51   - torque = math.sin(theta) * np.sqrt(f[0]*f[0]+f[1]*f[1]) * np.sqrt(r[0]*r[0]+r[1]*r[1])
  60 + #r = np.linalg.norm(self.CoM - p)
  61 + value = np.dot(d, f)/np.dot(d, d)/np.dot(f, f)
  62 + if value < 1.0 and value > -1.0:
  63 + theta = math.acos(value)
  64 + torque = math.sin(theta) * np.sqrt(f[0]*f[0]+f[1]*f[1]) * np.sqrt(d[0]*d[0]+d[1]*d[1])
  65 + else:
  66 + #print("value = ", value)
  67 + torque = 0.0
  68 +
52 69 #if < 0 then clockwise, else counter
53   - direction = np.cross(r, f)
  70 + direction = np.cross(d, f)
54 71 if direction < 0:
55   - self.torque.append([torque, "clockwise"])
  72 + self.torque.append([torque, f, p, "counterclock"])
56 73 else:
57   - self.torque.append([torque, "counterclock"])
  74 + self.torque.append([torque, f, p, "clockwise"])
  75 +
58 76  
59   - def calculate_moment(self):
  77 + def calculate_moment(self, use_graph=False):
60 78  
61 79 #returns the area of a triangle defined by two points
62 80 def area(t):
... ... @@ -65,6 +83,7 @@ class Polygon_mass:
65 83  
66 84 def center(t):
67 85 output = np.asarray([(t[0,0]+t[1,0]+t[2,0])/3.0, (t[0,1]+t[1,1]+t[2,1])/3.0])
  86 + return output
68 87  
69 88 segs = []
70 89 pts = np.asarray(self.polygon.exterior.xy).T
... ... @@ -72,9 +91,19 @@ class Polygon_mass:
72 91 for k in range(pts.shape[0]-1):
73 92 segs.append([k, k+1])
74 93 segs.append([pts.shape[0]-1, 0])
  94 + if use_graph:
  95 + points = self.G.vertex_properties["pos"].get_2d_array(range(2)).T
  96 + segs2 = []
  97 + n_pts = pts.shape[0]
  98 + for e in self.G.edges():
  99 + segs2.append([int(e.source())+n_pts, int(e.target())+n_pts])
  100 + pts = np.concatenate((pts, points))
  101 + segs = segs + segs2
75 102 mesh = dict(vertices=pts, segments=segs)
76 103 #print(self.polygon.area())
77   - tri = triangulate(mesh, 'pq20D')
  104 + tri = triangulate(mesh, 'pq20Ds')
  105 + self.mesh = mesh
  106 + self.tri = tri
78 107 moment = 0.0
79 108 #NEED TO ADD MASS maybe?
80 109 for i in range(tri['triangles'].shape[0]):
... ... @@ -84,59 +113,75 @@ class Polygon_mass:
84 113 Moi = A+A*np.linalg.norm(C-self.CoM)**2
85 114 moment += Moi
86 115  
87   - self.MoI = moment
  116 + self.MoI = abs(math.log(moment))
  117 + #self.MoI = 10
  118 + print(self.MoI)
88 119 # triangle_plot(plt.gca(), **tri)
89 120 # plt.gca().set_title(str(self.polygon.area))
90   -
  121 +
  122 + def translate(self, step):
  123 + d = self.forces_a + self.forces_r
  124 + #print(self.forces_a, self.forces_r)
  125 + d0 = step*d
  126 + self.CoM = self.CoM + d0
  127 + pos = self.G.vertex_properties["pos"].get_2d_array(range(2)).T
  128 + pos = pos + d0
  129 + self.G.vertex_properties["pos"] = self.G.new_vertex_property("vector<double>", vals = pos)
  130 +
91 131 def rotate(self, phi, direction = "counterclock"):
92 132 if("counterclock"):
93   - for v in self.G.vertices:
94   - p = self.G.vertex_properties["pos"][v]
95   - p[0] = self.CoM[0] + math.cos(phi) * (self.CoM[0] - p[0]) - math.sin(phi) * (p[1] - self.CoM[1])
96   - p[1] = self.CoM[1] + math.sin(phi) * (self.CoM[0] - p[0]) + math.cos(phi) * (p[1] - self.CoM[1])
97   - self.G.vertex_properties["pos"][v] = p
  133 + for v in self.G.vertices():
  134 + p_prime = copy.deepcopy(self.G.vertex_properties["pos"][v])
  135 + p = copy.deepcopy(self.G.vertex_properties["pos"][v])
  136 + p_prime[0] = self.CoM[0] + math.cos(phi) * (p[0] - self.CoM[0]) - math.sin(phi) * (p[1] - self.CoM[1])
  137 + p_prime[1] = self.CoM[1] + math.sin(phi) * (p[0] - self.CoM[0]) + math.cos(phi) * (p[1] - self.CoM[1])
  138 + self.G.vertex_properties["pos"][v] = p_prime
  139 + #rotate points in mesh
  140 + points = copy.deepcopy(self.mesh['vertices'])
  141 + for v in range(points.shape[0]):
  142 + points[v][0] = self.CoM[0] + math.cos(phi) * (self.mesh['vertices'][v][0] - self.CoM[0]) - math.sin(phi) * (self.mesh['vertices'][v][1] - self.CoM[1])
  143 + points[v][1] = self.CoM[1] + math.sin(phi) * (self.mesh['vertices'][v][0] - self.CoM[0]) + math.cos(phi) * (self.mesh['vertices'][v][1] - self.CoM[1])
  144 + self.mesh['vertices'] = points
98 145 else:
99   - for v in self.G.vertices:
100   - p = self.G.vertex_properties["pos"][v]
101   - p[0] = self.CoM[0] + math.cos(phi) * (self.CoM[0] + p[0]) + math.sin(phi) * (p[1] - self.CoM[1])
102   - p[1] = self.CoM[1] + math.sin(phi) * (self.CoM[0] + p[0]) - math.cos(phi) * (p[1] - self.CoM[1])
103   - self.G.vertex_properties["pos"][v] = p
  146 + for v in self.G.vertices():
  147 + p_prime = copy.deepcopy(self.G.vertex_properties["pos"][v])
  148 + p = copy.deepcopy(self.G.vertex_properties["pos"][v])
  149 + p_prime[0] = self.CoM[0] + math.cos(phi) * (p[0] - self.CoM[0]) + math.sin(phi) * (p[1] - self.CoM[1])
  150 + p_prime[1] = self.CoM[1] - math.sin(phi) * (p[0] - self.CoM[0]) + math.cos(phi) * (p[1] - self.CoM[1])
  151 + self.G.vertex_properties["pos"][v] = p_prime
  152 + #rotate points in mesh
  153 + points = copy.deepcopy(self.mesh['vertices'])
  154 + for v in range(points.shape[0]):
  155 + points[v][0] = self.CoM[0] + math.cos(phi) * (self.mesh['vertices'][v][0] - self.CoM[0]) + math.sin(phi) * (self.mesh['vertices'][v][1] - self.CoM[1])
  156 + points[v][1] = self.CoM[1] - math.sin(phi) * (self.mesh['vertices'][v][0] - self.CoM[0]) + math.cos(phi) * (self.mesh['vertices'][v][1] - self.CoM[1])
  157 + self.mesh['vertices'] = points
104 158  
  159 +
105 160  
106 161  
107 162 def plot_graph(self, D, x, y):
108 163 plt.figure()
109 164 ext = [self.a[0], self.b[0], self.a[1], self.b[1]]
110   - plt.imshow(D, origin = 'lower', extent=ext)
  165 + #plt.imshow(D, origin = 'lower', extent=ext)
111 166 p = self.G.vertex_properties["pos"].get_2d_array(range(2)).T
112 167 plt.scatter(p[:,0], p[:,1], color='r')
113 168 plt.scatter(self.CoM[0], self.CoM[1], marker='*')
114 169  
  170 + #mesh = dict(vertices=pts, segments=segs)
  171 + #print(self.polygon.area())
  172 + #tri = triangulate(mesh, 'pq20Ds')
  173 + triangle_plot(plt.gca(), **self.mesh)
115 174  
116   - segs = []
117   - pts = np.asarray(self.polygon.exterior.xy).T
118   - pts = pts[:-1, :]
119   - for k in range(pts.shape[0]-1):
120   - segs.append([k, k+1])
121   - segs.append([pts.shape[0]-1, 0])
122   - points = self.G.vertex_properties["pos"].get_2d_array(range(2)).T
123   - segs2 = []
124   - n_pts = pts.shape[0]
125   - for e in self.G.edges():
126   - segs2.append([int(e.source())+n_pts, int(e.target())+n_pts])
127   -
  175 + #plot polygon
  176 + #plt.plot(*self.polygon.exterior.xy, color = 'r')
128 177  
129 178  
130   - pts = np.concatenate((pts, points))
131   - segs = segs + segs2
132   - mesh = dict(vertices=pts, segments=segs)
133   - #print(self.polygon.area())
134   - # tri = triangulate(mesh, 'pq20D')
135   - triangle_plot(plt.gca(), **mesh)
136   - for i in range(len(segs)):
137   - plt.plot((pts[segs[i][0]][0], pts[segs[i][0]][1]), (pts[segs[i][1]][0], pts[segs[i][1]][1]), color='b')
  179 +# for i in range(len(segs)):
  180 +# plt.plot((pts[segs[i][0]][0], pts[segs[i][1]][0]), (pts[segs[i][0]][1], pts[segs[i][1]][1]), color='b')
138 181 plt.gca().set_title(str(self.polygon.area))
139 182  
  183 + for e in self.torque:
  184 + plt.quiver(e[2][0], e[2][1], e[1][0], e[1][1], color='r')
140 185 #tri = Delaunay(np.asarray(self.polygon.exterior.coords.xy).T)
141 186 #tri = triangulate(mesh, 'pq20a' + str(self.polygon.area/100.0)+'D')
142 187 #delaunay_plot_2d(tri)
... ... @@ -159,8 +204,7 @@ class Polygon_mass:
159 204 # Y = [coord[1], coord2[1]]
160 205 # #all_plots.plot(x, y, 'go--', linewidth=1, markersize=1)
161 206 # plt.plot(X, Y, 'go--', linewidth=1, markersize=1)
162   -#
163   - plt.plot(*self.polygon.exterior.xy, color = 'r')
  207 +#
164 208 plt.show()
165 209  
166 210 def get_aabb(self):
... ... @@ -200,7 +244,7 @@ class Polygon_mass:
200 244 contour[: ,1] = Y(cn[0][:, 0])
201 245 self.polygon = Polygon(contour)
202 246 self.CoM = self.centroid_com(contour)
203   -
  247 + self.calculate_moment(True)
204 248 #cn = plt.contour(x, y, D, levels = [level])
205 249 #cn = plt.contour(x, y, D, levels = [level])
206 250 # plt.close()
... ... @@ -215,12 +259,11 @@ class Polygon_mass:
215 259 # #nlist = c.trace(level, level, 0)
216 260 # #segs = nlist[:len(nlist)//2]
217 261 #self.polygon = Polygon(pts)
218   - self.plot_graph(D, x, y)
  262 + #self.plot_graph(D, x, y)
219 263  
220 264  
221 265  
222 266 def distancefield(self):
223   -
224 267 #generate a meshgrid of the appropriate size and resolution to surround the network
225 268 #get the space occupied by the network
226 269 lower = self.a
... ... @@ -271,6 +314,9 @@ class Polygon_mass:
271 314 # R = (200, 200, 200)
272 315  
273 316 D, I = tree.query(Q)
  317 + self.D = D
  318 + self.x = x
  319 + self.y = y
274 320  
275 321 return D, x, y
276 322  
... ... @@ -301,23 +347,66 @@ def get_torques(G, masses):
301 347 #if the source and target cluster is not equal to each other
302 348 #add an inter subgraph edge.
303 349 if(G.vertex_properties["clusters"][e.source()] != G.vertex_properties["clusters"][e.target()]):
304   - pf0 = G.vertex_properties["pos"][e.target()].get_2D_array(range(2))
305   - pf1 = G.vertex_properties["pos"][e.source()].get_2D_array(range(2))
  350 + #index of the cluster
  351 + t0 = G.vertex_properties["clusters"][e.target()]
  352 + t1 = G.vertex_properties["clusters"][e.source()]
  353 + #index of the vertex outside of the subgraph
  354 + v0_index = G.vertex_properties["idx"][e.target()]
  355 + v1_index = G.vertex_properties["idx"][e.source()]
  356 + #location of torque arm in the subgraph
  357 + p0 = masses[t0].G.vertex_properties["pos"][np.argwhere(masses[t0].G.vertex_properties["idx"].get_array() == v0_index)]
  358 + p1 = masses[t1].G.vertex_properties["pos"][np.argwhere(masses[t1].G.vertex_properties["idx"].get_array() == v1_index)]
306 359  
307   - t0 = G.vertex_properties["clusters"][e.source()]
308   - t1 = G.vertex_properties["clusters"][e.target()]
  360 + f0 = np.subtract(p0, p1)
  361 + f1 = np.subtract(p1, p0)
  362 + masses[t0].add_torque(p0, f1)
  363 + masses[t1].add_torque(p1, f0)
  364 +'''
  365 + c1 scales the attractive force before log.
  366 + c2 scales the attractive force inside log.
  367 + c3 scales the repulsive force.
  368 +'''
  369 +def get_forces(G, masses, c1 = 50.0, c2 = 1.0, c3 = 1.0):
  370 + for i in range(len(masses)):
  371 + masses[i].clear_forces()
  372 + f_total = np.zeros(2)
  373 + for j in range(len(masses)):
  374 + if i != j:
  375 + f0 = np.subtract(masses[i].CoM, masses[j].CoM)
  376 + f1 = np.power(f0, 3.0)
  377 + f1[0] = c3/f1[0]*np.sign(f0[0])
  378 + f1[1] = c3/f1[1]*np.sign(f0[1])
  379 + f_total = np.add(f_total, f1)
  380 + masses[i].forces_r = f_total
309 381  
310   - v0_index = G.vertex_properties["idx"][e.source()]
311   - v1_index = G.vertex_properties["idx"][e.target()]
  382 + for e in G.edges():
  383 + #if the source and target cluster is not equal to each other
  384 + #add an inter subgraph edge.
  385 + if(G.vertex_properties["clusters"][e.source()] != G.vertex_properties["clusters"][e.target()]):
  386 + #index of the cluster
  387 + t0 = G.vertex_properties["clusters"][e.target()]
  388 + t1 = G.vertex_properties["clusters"][e.source()]
  389 + #index of the vertex outside of the subgraph
  390 + v0_index = G.vertex_properties["idx"][e.target()]
  391 + v1_index = G.vertex_properties["idx"][e.source()]
  392 + #location of torque arm in the subgraph
  393 + p0 = masses[t0].G.vertex_properties["pos"][np.argwhere(masses[t0].G.vertex_properties["idx"].get_array() == v0_index)]
  394 + p1 = masses[t1].G.vertex_properties["pos"][np.argwhere(masses[t1].G.vertex_properties["idx"].get_array() == v1_index)]
312 395  
313   - p0 = masses[t0].G.vertex_properties["pos"][masses[t0].G.vertex(v0_index)].get_2D_array(range(2))
314   - p1 = masses[t1].G.vertex_properties["pos"][masses[t1].G.vertex(v1_index)].get_2D_array(range(2))
  396 + f0 = np.subtract(p1, p0)
  397 + f0_1 = abs(f0)
  398 + f0_1 = c1*np.log(f0_1/c2)/masses[t0].degree
  399 + f0_1 = f0_1*np.sign(f0)
  400 + f1 = np.subtract(p0, p1)
  401 + f1_1 = abs(f1)
  402 + f1_1 = c1*np.log(f1_1/c2)/masses[t1].degree
  403 + f1_1 = f1_1*np.sign(f1)
  404 + masses[t0].forces_a = np.add(masses[t0].forces_a, f1_1)
  405 + masses[t1].forces_a = np.add(masses[t1].forces_a, f0_1)
315 406  
316   - f0 = pf0-p1
317   - f1 = pf1-p0
318   - masses[t0].add_torque(p0, f0)
319   - masses[t1].add_torque(p1, f1)
320   -
  407 +
  408 +
  409 +
321 410  
322 411 def voronoi_polygons(voronoi, diameter):
323 412 """Generate shapely.geometry.Polygon objects corresponding to the
... ... @@ -446,7 +535,7 @@ def gen_cluster_graph(G, num_clusters, cluster_pos):
446 535 G_cluster.vertex_properties["bc"] = vbetweeness_centrality
447 536 G_cluster.edge_properties["bc"] = ebetweeness_centrality
448 537 G_cluster.edge_properties["bc_scaled"] = G_cluster.new_edge_property("double", vals=ebc)
449   -
  538 + G_cluster.edge_properties["log"] = G_cluster.new_edge_property("double", vals=abs(np.log(G_cluster.edge_properties["volume"].get_array())))
450 539 dg = G_cluster.vertex_properties["degree"].get_array()
451 540 dg = 2*max(dg) - dg
452 541 d = G_cluster.new_vertex_property("int", vals=dg)
... ... @@ -570,7 +659,35 @@ def centroid_region(vertices):
570 659 C_y = (1.0 / (6.0 * A)) * C_y
571 660  
572 661 return np.array([C_x, C_y])
573   -
  662 +
  663 +def find_equlibrium(masses, t = 0.01):
  664 + for m in masses:
  665 + sum_torque = 0
  666 + for torque in m.torque:
  667 + if torque[3] == "clockwise":
  668 + sum_torque -= torque[0]
  669 + else:
  670 + sum_torque += torque[0]
  671 + m.vel = m.aa * t + m.vel
  672 + m.aa = sum_torque/m.MoI
  673 + #print(m.G.vertex_properties["clusters"][0], m.vel)
  674 + if m.vel != 0.0:
  675 + if m.vel < 0.0:
  676 + m.rotate(abs(m.vel * t),"counterclock")
  677 + else:
  678 + m.rotate(abs(m.vel * t), "clockwise")
  679 +
  680 +
  681 +def gen_Eades(G, masses, M = 10):
  682 + for i in range(M):
  683 + get_forces(G, masses)
  684 + for j in masses:
  685 + j.translate(0.001)
  686 +
  687 +def onion_springs(G, masses, min_length):
  688 + for v in G.vertices():
  689 +
  690 +
574 691  
575 692 def gen_image(G, G_c, itr, bb_flag = False, bb = None, reposition = False):
576 693 #def gen_image(G, G_c, vor, vor_filtered):
... ... @@ -580,18 +697,24 @@ def gen_image(G, G_c, itr, bb_flag = False, bb = None, reposition = False):
580 697  
581 698 #get points of the centers of every cluster
582 699 #generate voronoi region and plot it.
583   - fig, ax = plt.subplots(3, 1, sharex='col', sharey='row')
  700 + fig, ax = plt.subplots(4, 1, sharex='col', sharey='row')
584 701 fig.tight_layout()
585   - grid = plt.GridSpec(3,1)
  702 + grid = plt.GridSpec(4,1)
586 703 grid.update(wspace=0.025, hspace=0.2)
587 704 ax[0].axis('off')
588 705 ax[1].axis('off')
589 706 ax[2].axis('off')
  707 + ax[3].axis('off')
  708 +
590 709  
  710 + #Add plots to the axes and get their handles
591 711 all_plots = fig.add_subplot(grid[0])
592 712 ax[0].set_title(itr)
593 713 no_links = fig.add_subplot(grid[1], sharey=all_plots, sharex=all_plots)
594 714 voronoi = fig.add_subplot(grid[2], sharey=all_plots, sharex=all_plots)
  715 + rotated = fig.add_subplot(grid[3], sharey=all_plots, sharex=all_plots)
  716 +
  717 + #Get the points and generate the voronoi region
595 718 pts = G_c.vertex_properties["pos"].get_2d_array(range(2)).T
596 719 if bb_flag == False:
597 720 vor = Voronoi(pts)
... ... @@ -601,16 +724,20 @@ def gen_image(G, G_c, itr, bb_flag = False, bb = None, reposition = False):
601 724 a = voronoi.get_ylim()
602 725 b = voronoi.get_xlim()
603 726 bb = np.array([b[0], b[1], a[0], a[1]])
  727 +
  728 + #generate the polygons based on the voronoi regions
604 729 G_c, regions, vor = gen_polygons(G_c, bb)
605 730 if bb_flag == True:
606 731 voronoi_plot_2d(vor, all_plots)
607 732 voronoi_plot_2d(vor, no_links)
608 733 voronoi_plot_2d(vor, voronoi)
  734 +
609 735 #plot the top-level graph
610 736 pts = G_c.vertex_properties["pos"].get_2d_array(range(2)).T
611 737 all_plots.scatter(pts[:,0], pts[:, 1], s=20*G_c.vertex_properties["degree"].get_array(), marker="*")
612 738 no_links.scatter(pts[:,0], pts[:, 1], s=20*G_c.vertex_properties["degree"].get_array(), marker="*")
613 739 voronoi.scatter(pts[:,0], pts[:, 1], s=20*G_c.vertex_properties["degree"].get_array(), marker="*")
  740 +
614 741 #plot the connections of the top level graph
615 742 for e in G_c.edges():
616 743 coord = G_c.vertex_properties["pos"][e.source()]
... ... @@ -621,18 +748,25 @@ def gen_image(G, G_c, itr, bb_flag = False, bb = None, reposition = False):
621 748 no_links.plot(x, y, 'go--', linewidth=1, markersize=1)
622 749 voronoi.plot(x, y, 'go--', linewidth=1, markersize=1)
623 750  
624   - #for every subgraph generate a layout and plot the resulting Polygon_mass
  751 + #For every subgraph generate a layout and plot the resulting Polygon_mass
  752 + #These polygons are not the same as the voronoi polygons and instead surround
  753 + #graph.
625 754 masses = []
626 755 for i in range(num_clusters):
627 756 g, center = gen_subclusters(G, G_c, i, reposition)
628 757 d = G_c.vertex_properties["pos"][i] - center
629   - t = Polygon_mass(g)
630   - masses.append(g)
631   - #t.distancefield()
632 758 for v in g.vertices():
633 759 G.vertex_properties["pos"][g.vertex_properties["idx"][v]] = g.vertex_properties["pos"][v] + d
  760 + g.vertex_properties["pos"][v] = g.vertex_properties["pos"][v] + d
  761 + t = Polygon_mass(g)
  762 + t.set_degree(G_c.vertex_properties["degree"][i])
  763 + masses.append(t)
  764 + #t.distancefield()
634 765  
635   -
  766 + #get the torques generated by the positioning of the graphs.
  767 + get_torques(G, masses)
  768 +# for i in masses:
  769 +# i.plot_graph(i.D, i.x, i.y)
636 770 #g.vertex_properties["pos"][g.vertex_properties["idx"][v]] = g.vertex_properties["pos"][v] + d
637 771 #sub_pts = g.vertex_properties["pos"].get_2d_array(range(2)).T
638 772 #all_plots.scatter(pts[:,0], pts[:, 1], marker="*")
... ... @@ -642,7 +776,9 @@ def gen_image(G, G_c, itr, bb_flag = False, bb = None, reposition = False):
642 776 # x = [coord[0], coord2[0]]
643 777 # y = [coord[1], coord2[1]]
644 778 # plt.plot(x, y, 'ro--', linewidth=1, markersize=1)
645   -
  779 +
  780 +
  781 + #Plot the cluster level connections and the vertex level connections.
646 782 for e in G.edges():
647 783 coord = G.vertex_properties["pos"][e.source()]
648 784 coord2 = G.vertex_properties["pos"][e.target()]
... ... @@ -653,7 +789,8 @@ def gen_image(G, G_c, itr, bb_flag = False, bb = None, reposition = False):
653 789 no_links.plot(x, y, 'ro--', linewidth=1, markersize=1)
654 790 else:
655 791 all_plots.plot(x, y, 'bo--', linewidth=1, markersize=1)
656   -
  792 +
  793 + #Update the centroids based on the voronoi polygons
657 794 no_links.xaxis.set_visible(False)
658 795 all_plots.xaxis.set_visible(False)
659 796 for v in G_c.vertices():
... ... @@ -661,11 +798,16 @@ def gen_image(G, G_c, itr, bb_flag = False, bb = None, reposition = False):
661 798 centroid = centroid_region(region[0])
662 799 G_c.vertex_properties["pos"][v] = centroid
663 800  
  801 +
  802 + print(G_c.num_vertices(), G_c.num_edges())
  803 +
  804 + #Plots the vertices of the subgraphs
664 805 pts_temp = G_c.vertex_properties["pos"].get_2d_array(range(2)).T
665 806 all_plots.scatter(pts_temp[:,0], pts_temp[:, 1], marker='.', color='r')
666 807 no_links.scatter(pts_temp[:,0], pts_temp[:, 1], marker='.', color='r')
667 808 voronoi.scatter(pts_temp[:,0], pts_temp[:, 1], marker='.', color='r')
668 809  
  810 + #set the limits of the plots.
669 811 all_plots.set_xlim([bb[0], bb[1]])
670 812 all_plots.set_ylim([bb[2], bb[3]])
671 813  
... ... @@ -675,10 +817,44 @@ def gen_image(G, G_c, itr, bb_flag = False, bb = None, reposition = False):
675 817 voronoi.set_xlim([bb[0], bb[1]])
676 818 voronoi.set_ylim([bb[2], bb[3]])
677 819  
  820 + #show the plots.
678 821 plt.show()
679 822  
  823 +# for j in [7, 10, 15]:
  824 +# masses[j].plot_graph(masses[j].D, masses[j].x, masses[j].y)
  825 +
  826 + for j in range(10):
  827 + for i in range(100):
  828 + get_torques(G, masses)
  829 + find_equlibrium(masses)
  830 + gen_Eades(G, masses)
  831 +# for j in [7, 10]:
  832 +# masses[j].plot_graph(masses[j].D, masses[j].x, masses[j].y)
  833 +# for j in [7, 10, 15]:
  834 +# masses[j].plot_graph(masses[j].D, masses[j].x, masses[j].y)
  835 +
  836 + for i in masses:
  837 + for v in i.G.vertices():
  838 + G.vertex_properties["pos"][i.G.vertex_properties["idx"][v]] = i.G.vertex_properties["pos"][v]
  839 +
  840 +
  841 + #Plot the cluster level connections and the vertex level connections.
  842 + for e in G.edges():
  843 + coord = G.vertex_properties["pos"][e.source()]
  844 + coord2 = G.vertex_properties["pos"][e.target()]
  845 + x = [coord[0], coord2[0]]
  846 + y = [coord[1], coord2[1]]
  847 + if (G.vertex_properties["clusters"][e.source()] == G.vertex_properties["clusters"][e.target()]):
  848 + rotated.plot(x, y, 'ro--', linewidth=1, markersize=1)
  849 + else:
  850 + rotated.plot(x, y, 'bo--', linewidth=1, markersize=1)
  851 +
  852 + pts_temp = G.vertex_properties["pos"].get_2d_array(range(2)).T
  853 + rotated.scatter(pts_temp[:,0], pts_temp[:, 1], marker='.', color='r')
  854 +
  855 +
680 856  
681   - return G, G_c, bb
  857 + return G, G_c, bb, masses
682 858  
683 859  
684 860  
... ... @@ -691,19 +867,25 @@ def gen_image(G, G_c, itr, bb_flag = False, bb = None, reposition = False):
691 867  
692 868 G, bbl, bbu = load_nwt("/home/pavel/Documents/Python/GraphGuiQt/network_4.nwt")
693 869 G_c, G = gen_clusters(G, bbl, bbu)
  870 +
694 871 num_clusters = 20
695 872  
696 873 #G_c.vertex_properties["pos"] = nwt.gt.radial_tree_layout(G_c, root=np.argwhere(G_c.vertex_properties["degree"].get_array() == max(G_c.vertex_properties["degree"].get_array())), node_weight = G_c.vertex_properties["10-degree"], r= 2.0)
697 874 G_c.vertex_properties["pos"] = nwt.gt.sfdp_layout(G_c, eweight=G_c.edge_properties["volume"], vweight=G_c.vertex_properties["degree"], C = 1.0, K = 10)
698 875  
699   -G, G_c, bb = gen_image(G, G_c, "base", reposition = True)
  876 +
  877 +
  878 +G, G_c, bb, masses = gen_image(G, G_c, "base", reposition = True)
  879 +
  880 +print("Planarity test: G_c, G = " , nwt.gt.graph_tool.topology.is_planar(G_c), nwt.gt.graph_tool.topology.is_planar(G))
  881 +
700 882 itr = 0
701 883  
702 884 #for itr in range(5):
703   -# G, G_c, bb = gen_image(G, G_c, itr, True, bb)
  885 +# G, G_c, bb, masses = gen_image(G, G_c, itr, True, bb)
704 886 # itr+=1
705 887  
706   -g, center = gen_subclusters(G, G_c)
  888 +#g, center = gen_subclusters(G, G_c)
707 889 #d = G_c.vertex_properties["pos"][0] - center
708 890 #for v in g.vertices():
709 891 # g.vertex_properties["pos"][v] = g.vertex_properties["pos"][v] + d
... ...