Commit 17e4b25a127e9bb5b3f69616f8d0a5649894954e

Authored by Pavel Govyadinov
1 parent 4407a915

Bug fixes, Dual version, histograms, cluster exploration, vertex exploration, to…

… do: path exploration and hover-over
@@ -13,6 +13,18 @@ from vispy.gloo import set_viewport, set_state, clear, set_blend_color, context @@ -13,6 +13,18 @@ from vispy.gloo import set_viewport, set_state, clear, set_blend_color, context
13 from vispy.util.transforms import perspective, translate, rotate, scale 13 from vispy.util.transforms import perspective, translate, rotate, scale
14 import vispy.gloo.gl as glcore 14 import vispy.gloo.gl as glcore
15 from vispy import app 15 from vispy import app
  16 +#from shapely.geometry import Polygon
  17 +#from shapely.geometry import Point
  18 +#from shapely.geometry import MultiPoint
  19 +from scipy.spatial import ConvexHull
  20 +from scipy.spatial import Delaunay
  21 +#import scipy.spatial.ConvexHull
  22 +
  23 +from vispy.scene.visuals import Text
  24 +from vispy.scene.visuals import ColorBar
  25 +
  26 +
  27 +
16 import copy 28 import copy
17 29
18 import numpy as np 30 import numpy as np
@@ -211,6 +223,10 @@ class GraphCanvas(scene.SceneCanvas): @@ -211,6 +223,10 @@ class GraphCanvas(scene.SceneCanvas):
211 self.timer = app.Timer('auto', connect=self.on_timer, start=False) 223 self.timer = app.Timer('auto', connect=self.on_timer, start=False)
212 #self.constant = app.Timer('auto', connect=self.update, start=True) 224 #self.constant = app.Timer('auto', connect=self.update, start=True)
213 self.num=0 225 self.num=0
  226 + self.current_color = ""
  227 + self.update_text(self.current_color)
  228 + self.update_color_bar(self.current_color)
  229 +
214 print(self.context.config) 230 print(self.context.config)
215 231
216 def on_timer(self, event): 232 def on_timer(self, event):
@@ -251,42 +267,42 @@ class GraphCanvas(scene.SceneCanvas): @@ -251,42 +267,42 @@ class GraphCanvas(scene.SceneCanvas):
251 self.vbo_line = gloo.VertexBuffer(self.line_data) 267 self.vbo_line = gloo.VertexBuffer(self.line_data)
252 self.program_e.bind(self.vbo_line) 268 self.program_e.bind(self.vbo_line)
253 269
254 -  
255 - self.update_clusters(self.old_pos)  
256 - edges = self.G_cluster.get_edges()  
257 -# #generate the vertex buffer and the connections buffer.  
258 - for e in range(edges.shape[0]):  
259 - idx = int(4*edges[e][2])  
260 - p0 = self.cluster_pos[int(edges[e][0])]  
261 - p1 = self.cluster_pos[int(edges[e][1])]  
262 - #p0 = self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(edges[e][0])]  
263 - #p1 = self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(edges[e][1])]  
264 - d = np.subtract(p1, p0)  
265 - #d_norm = np.multiply(d, 1/np.sqrt(np.power(d[0],2) + np.power(d[1],2)))  
266 - d_norm = d[0:2]  
267 - d_norm = d_norm / np.sqrt(np.power(d_norm[0],2) + np.power(d_norm[1],2))  
268 - norm = np.zeros((2,), dtype=np.float32)  
269 - norm[0] = d_norm[1]  
270 - norm[1] = d_norm[0]*-1  
271 - #print(np.sqrt(norm[0]*norm[0] + norm[1]*norm[1]))  
272 - #thickness = G.edge_properties["thickness"][e]  
273 - #self.cluster_dict[int(edges[e][0]), int(edges[e][1])] = int(edges[e][2])  
274 - self.cluster_line_data['a_position'][idx] = p0  
275 - self.cluster_line_data['a_normal'][idx] = norm  
276 -  
277 - self.cluster_line_data['a_position'][idx+1] = p1  
278 - self.cluster_line_data['a_normal'][idx+1] = norm  
279 -  
280 - self.cluster_line_data['a_position'][idx+2] = p0  
281 - self.cluster_line_data['a_normal'][idx+2] = -norm  
282 -  
283 - self.cluster_line_data['a_position'][idx+3] = p1  
284 - self.cluster_line_data['a_normal'][idx+3] = -norm  
285 -  
286 - self.vbo_cluster_lines.set_data(self.cluster_line_data)  
287 - self.vbo_s.set_data(self.clusters)  
288 - self.program_s.bind(self.vbo_s)  
289 - self.program_e_s.bind(self.vbo_cluster_lines) 270 + if(self.subgraphs):
  271 + self.update_clusters(self.old_pos)
  272 + edges = self.G_cluster.get_edges()
  273 + # #generate the vertex buffer and the connections buffer.
  274 + for e in range(edges.shape[0]):
  275 + idx = int(4*edges[e][2])
  276 + p0 = self.cluster_pos[int(edges[e][0])]
  277 + p1 = self.cluster_pos[int(edges[e][1])]
  278 + #p0 = self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(edges[e][0])]
  279 + #p1 = self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(edges[e][1])]
  280 + d = np.subtract(p1, p0)
  281 + #d_norm = np.multiply(d, 1/np.sqrt(np.power(d[0],2) + np.power(d[1],2)))
  282 + d_norm = d[0:2]
  283 + d_norm = d_norm / np.sqrt(np.power(d_norm[0],2) + np.power(d_norm[1],2))
  284 + norm = np.zeros((2,), dtype=np.float32)
  285 + norm[0] = d_norm[1]
  286 + norm[1] = d_norm[0]*-1
  287 + #print(np.sqrt(norm[0]*norm[0] + norm[1]*norm[1]))
  288 + #thickness = G.edge_properties["thickness"][e]
  289 + #self.cluster_dict[int(edges[e][0]), int(edges[e][1])] = int(edges[e][2])
  290 + self.cluster_line_data['a_position'][idx] = p0
  291 + self.cluster_line_data['a_normal'][idx] = norm
  292 +
  293 + self.cluster_line_data['a_position'][idx+1] = p1
  294 + self.cluster_line_data['a_normal'][idx+1] = norm
  295 +
  296 + self.cluster_line_data['a_position'][idx+2] = p0
  297 + self.cluster_line_data['a_normal'][idx+2] = -norm
  298 +
  299 + self.cluster_line_data['a_position'][idx+3] = p1
  300 + self.cluster_line_data['a_normal'][idx+3] = -norm
  301 +
  302 + self.vbo_cluster_lines.set_data(self.cluster_line_data)
  303 + self.vbo_s.set_data(self.clusters)
  304 + self.program_s.bind(self.vbo_s)
  305 + self.program_e_s.bind(self.vbo_cluster_lines)
290 306
291 self.refresh() 307 self.refresh()
292 308
@@ -309,6 +325,8 @@ class GraphCanvas(scene.SceneCanvas): @@ -309,6 +325,8 @@ class GraphCanvas(scene.SceneCanvas):
309 self.vbo = gloo.VertexBuffer(self.data) 325 self.vbo = gloo.VertexBuffer(self.data)
310 self.program.bind(self.vbo) 326 self.program.bind(self.vbo)
311 #self.program_e.bind(self.vbo) 327 #self.program_e.bind(self.vbo)
  328 + self.update_text(self.current_color)
  329 + self.update_color_bar(self.current_color)
312 self.refresh() 330 self.refresh()
313 331
314 def update_color_buffers(self): 332 def update_color_buffers(self):
@@ -622,7 +640,7 @@ class GraphCanvas(scene.SceneCanvas): @@ -622,7 +640,7 @@ class GraphCanvas(scene.SceneCanvas):
622 two. 640 two.
623 """ 641 """
624 def gen_cluster_line_vbo(self, G): 642 def gen_cluster_line_vbo(self, G):
625 - #create a graph that stores the edges of between the clusters 643 +
626 self.G_cluster = nwt.gt.Graph(directed=False) 644 self.G_cluster = nwt.gt.Graph(directed=False)
627 self.G_cluster.vertex_properties["pos"] = self.G_cluster.new_vertex_property("vector<double>", val=np.zeros((3,1), dtype=np.float32)) 645 self.G_cluster.vertex_properties["pos"] = self.G_cluster.new_vertex_property("vector<double>", val=np.zeros((3,1), dtype=np.float32))
628 self.G_cluster.vertex_properties["RGBA"] = self.G_cluster.new_vertex_property("vector<double>", val=np.zeros((4,1), dtype=np.float32)) 646 self.G_cluster.vertex_properties["RGBA"] = self.G_cluster.new_vertex_property("vector<double>", val=np.zeros((4,1), dtype=np.float32))
@@ -630,22 +648,73 @@ class GraphCanvas(scene.SceneCanvas): @@ -630,22 +648,73 @@ class GraphCanvas(scene.SceneCanvas):
630 self.G_cluster.add_vertex() 648 self.G_cluster.add_vertex()
631 self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(v)] = np.asarray(self.cluster_pos[v], dtype=np.float32) 649 self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(v)] = np.asarray(self.cluster_pos[v], dtype=np.float32)
632 self.G_cluster.edge_properties["weight"] = self.G_cluster.new_edge_property("int", val = 0) 650 self.G_cluster.edge_properties["weight"] = self.G_cluster.new_edge_property("int", val = 0)
  651 + self.G_cluster.edge_properties["volume"] = self.G_cluster.new_edge_property("float", val = 0.0)
633 #for each edge in the original graph, generate appropriate subgraph edges without repretiions 652 #for each edge in the original graph, generate appropriate subgraph edges without repretiions
634 #i.e. controls the thichness of the edges in the subgraph view. 653 #i.e. controls the thichness of the edges in the subgraph view.
635 for e in G.edges(): 654 for e in G.edges():
636 #if the source and target cluster is not equal to each other 655 #if the source and target cluster is not equal to each other
637 #add an inter subgraph edge. 656 #add an inter subgraph edge.
638 if(G.vertex_properties["clusters"][e.source()] != G.vertex_properties["clusters"][e.target()]): 657 if(G.vertex_properties["clusters"][e.source()] != G.vertex_properties["clusters"][e.target()]):
  658 + t0 = e.source()
  659 + t1 = e.target()
  660 + ct0 = self.G_cluster.vertex(G.vertex_properties["clusters"][t0])
  661 + ct1 = self.G_cluster.vertex(G.vertex_properties["clusters"][t1])
  662 + if(self.G_cluster.edge(ct0, ct1) == None):
  663 + if(self.G_cluster.edge(ct1, ct0) == None):
639 #temp_e.append([G.vertex_properties["clusters"][e.source()], G.vertex_properties["clusters"][e.target()]]) 664 #temp_e.append([G.vertex_properties["clusters"][e.source()], G.vertex_properties["clusters"][e.target()]])
640 - self.G_cluster.add_edge(self.G_cluster.vertex(G.vertex_properties["clusters"][e.source()]), \  
641 - self.G_cluster.vertex(G.vertex_properties["clusters"][e.target()]))  
642 - self.G_cluster.edge_properties["weight"][self.G_cluster.edge(self.G_cluster.vertex(G.vertex_properties["clusters"][e.source()]), \  
643 - self.G_cluster.vertex(G.vertex_properties["clusters"][e.target()]))] += 1  
644 - self.G_cluster.vertex_properties["RGBA"][self.G_cluster.vertex(G.vertex_properties["clusters"][e.source()])] \  
645 - = G.vertex_properties["RGBA"][e.source()]  
646 - self.G_cluster.vertex_properties["RGBA"][self.G_cluster.vertex(G.vertex_properties["clusters"][e.target()])] \  
647 - = G.vertex_properties["RGBA"][e.target()]  
648 - 665 + self.G_cluster.add_edge(self.G_cluster.vertex(G.vertex_properties["clusters"][t0]), \
  666 + self.G_cluster.vertex(G.vertex_properties["clusters"][t1]))
  667 + self.G_cluster.edge_properties["weight"][self.G_cluster.edge(self.G_cluster.vertex(G.vertex_properties["clusters"][t0]), \
  668 + self.G_cluster.vertex(G.vertex_properties["clusters"][t1]))] += 1
  669 + self.G_cluster.edge_properties["volume"][self.G_cluster.edge(self.G_cluster.vertex(G.vertex_properties["clusters"][t0]), \
  670 + self.G_cluster.vertex(G.vertex_properties["clusters"][t1]))] += G.edge_properties["volume"][e]
  671 + self.G_cluster.vertex_properties["RGBA"][self.G_cluster.vertex(G.vertex_properties["clusters"][t0])] \
  672 + = G.vertex_properties["RGBA"][t0]
  673 + self.G_cluster.vertex_properties["RGBA"][self.G_cluster.vertex(G.vertex_properties["clusters"][t1])] \
  674 + = G.vertex_properties["RGBA"][t1]
  675 + else:
  676 + self.G_cluster.edge_properties["weight"][self.G_cluster.edge(self.G_cluster.vertex(G.vertex_properties["clusters"][t1]), \
  677 + self.G_cluster.vertex(G.vertex_properties["clusters"][t0]))] += 1
  678 + self.G_cluster.edge_properties["volume"][self.G_cluster.edge(self.G_cluster.vertex(G.vertex_properties["clusters"][t1]), \
  679 + self.G_cluster.vertex(G.vertex_properties["clusters"][t0]))] += G.edge_properties["volume"][e]
  680 + self.G_cluster.vertex_properties["RGBA"][self.G_cluster.vertex(G.vertex_properties["clusters"][t1])] \
  681 + = G.vertex_properties["RGBA"][t1]
  682 + self.G_cluster.vertex_properties["RGBA"][self.G_cluster.vertex(G.vertex_properties["clusters"][t0])] \
  683 + = G.vertex_properties["RGBA"][t0]
  684 + else:
  685 + self.G_cluster.edge_properties["weight"][self.G_cluster.edge(self.G_cluster.vertex(G.vertex_properties["clusters"][t0]), \
  686 + self.G_cluster.vertex(G.vertex_properties["clusters"][t1]))] += 1
  687 + self.G_cluster.edge_properties["volume"][self.G_cluster.edge(self.G_cluster.vertex(G.vertex_properties["clusters"][t0]), \
  688 + self.G_cluster.vertex(G.vertex_properties["clusters"][t1]))] += G.edge_properties["volume"][e]
  689 + self.G_cluster.vertex_properties["RGBA"][self.G_cluster.vertex(G.vertex_properties["clusters"][t0])] \
  690 + = G.vertex_properties["RGBA"][t0]
  691 + self.G_cluster.vertex_properties["RGBA"][self.G_cluster.vertex(G.vertex_properties["clusters"][t1])] \
  692 + = G.vertex_properties["RGBA"][t1]
  693 + #create a graph that stores the edges of between the clusters
  694 +# self.G_cluster = nwt.gt.Graph(directed=False)
  695 +# self.G_cluster.vertex_properties["pos"] = self.G_cluster.new_vertex_property("vector<double>", val=np.zeros((3,1), dtype=np.float32))
  696 +# self.G_cluster.vertex_properties["RGBA"] = self.G_cluster.new_vertex_property("vector<double>", val=np.zeros((4,1), dtype=np.float32))
  697 +# for v in range(len(self.cluster_pos)):
  698 +# self.G_cluster.add_vertex()
  699 +# self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(v)] = np.asarray(self.cluster_pos[v], dtype=np.float32)
  700 +# self.G_cluster.edge_properties["weight"] = self.G_cluster.new_edge_property("int", val = 0)
  701 +# #for each edge in the original graph, generate appropriate subgraph edges without repretiions
  702 +# #i.e. controls the thichness of the edges in the subgraph view.
  703 +# for e in G.edges():
  704 +# #if the source and target cluster is not equal to each other
  705 +# #add an inter subgraph edge.
  706 +# if(G.vertex_properties["clusters"][e.source()] != G.vertex_properties["clusters"][e.target()]):
  707 +# #temp_e.append([G.vertex_properties["clusters"][e.source()], G.vertex_properties["clusters"][e.target()]])
  708 +# self.G_cluster.add_edge(self.G_cluster.vertex(G.vertex_properties["clusters"][e.source()]), \
  709 +# self.G_cluster.vertex(G.vertex_properties["clusters"][e.target()]))
  710 +# self.G_cluster.edge_properties["weight"][self.G_cluster.edge(self.G_cluster.vertex(G.vertex_properties["clusters"][e.source()]), \
  711 +# self.G_cluster.vertex(G.vertex_properties["clusters"][e.target()]))] += 1
  712 +# self.G_cluster.vertex_properties["RGBA"][self.G_cluster.vertex(G.vertex_properties["clusters"][e.source()])] \
  713 +# = G.vertex_properties["RGBA"][e.source()]
  714 +# self.G_cluster.vertex_properties["RGBA"][self.G_cluster.vertex(G.vertex_properties["clusters"][e.target()])] \
  715 +# = G.vertex_properties["RGBA"][e.target()]
  716 +
  717 + self.G_cluster.vertex_properties["degree"] = self.G_cluster.degree_property_map("total")
649 self.cluster_line_data = np.zeros(self.G_cluster.num_edges()*4, dtype=[('a_position', np.float32, 3), 718 self.cluster_line_data = np.zeros(self.G_cluster.num_edges()*4, dtype=[('a_position', np.float32, 3),
650 ('a_normal', np.float32, 2), 719 ('a_normal', np.float32, 2),
651 ('a_fg_color', np.float32, 4), 720 ('a_fg_color', np.float32, 4),
@@ -824,6 +893,62 @@ class GraphCanvas(scene.SceneCanvas): @@ -824,6 +893,62 @@ class GraphCanvas(scene.SceneCanvas):
824 893
825 894
826 """ 895 """
  896 + Generates a hierarchical layout based on the cluster graph (spdf) and subclusters
  897 + """
  898 + def voronoi_layout(self, G = None, n_c = None, G_c = None):
  899 +
  900 + def gen_subclusters(G, G_cluster, i, reposition = False):
  901 + vfilt = np.zeros([G.num_vertices(), 1], dtype='bool')
  902 + labels = G.vertex_properties["clusters"].get_array()
  903 + num_v_in_cluster = len(np.argwhere(labels == i))
  904 + vfilt[np.argwhere(labels == i)] = 1
  905 + vfilt_prop = G.new_vertex_property("bool", vals = vfilt)
  906 + G.set_vertex_filter(vfilt_prop)
  907 +
  908 + g = nwt.gt.Graph(G, prune=True, directed=False)
  909 +
  910 +
  911 + if reposition == True:
  912 + vbetweeness_centrality = g.new_vertex_property("double")
  913 + ebetweeness_centrality = g.new_edge_property("double")
  914 + nwt.gt.graph_tool.centrality.betweenness(g, vprop=vbetweeness_centrality, eprop=ebetweeness_centrality, norm=True)
  915 + g.vertex_properties["bc"] = vbetweeness_centrality
  916 + g.edge_properties["bc"] = ebetweeness_centrality
  917 + g.vertex_properties["pos"] = nwt.gt.sfdp_layout(g, eweight = ebetweeness_centrality)
  918 +
  919 + positions = g.vertex_properties["pos"].get_2d_array(range(2)).T
  920 + center = np.sum(positions, 0)/num_v_in_cluster
  921 + G.clear_filters()
  922 + return g, center
  923 +
  924 + if G_c == None:
  925 + G_c = self.G_cluster
  926 + 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)
  927 + if(G == None):
  928 + G = self.G
  929 + if(n_c == None):
  930 + n_c = self.n_c
  931 + else:
  932 + if(G == None):
  933 + G = self.G
  934 + if(n_c == None):
  935 + n_c = self.n_c
  936 + if self.n_c == G_c.num_vertices():
  937 + for i in range(n_c):
  938 + self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(i)] = G_c.vertex_properties["pos"][G_c.vertex(i)]
  939 +
  940 +
  941 + for i in range(n_c):
  942 + g, center = gen_subclusters(G, G_c, i, reposition=True)
  943 + d = G_c.vertex_properties["pos"][i] - center
  944 + for v in g.vertices():
  945 + G.vertex_properties["pos"][g.vertex_properties["idx"][v]] = g.vertex_properties["pos"][v] + d
  946 + g.vertex_properties["pos"][v] = g.vertex_properties["pos"][v] + d
  947 + #print("stuff")
  948 +
  949 +
  950 +
  951 + """
827 Layout algorithm that expands the cluster based on the location of the of the clusters 952 Layout algorithm that expands the cluster based on the location of the of the clusters
828 """ 953 """
829 def expand_based_on_clusters(self, G, n): 954 def expand_based_on_clusters(self, G, n):
@@ -920,73 +1045,14 @@ class GraphCanvas(scene.SceneCanvas): @@ -920,73 +1045,14 @@ class GraphCanvas(scene.SceneCanvas):
920 self.clusters['a_value'][index:index+4] = np.asarray(v, dtype=np.float32) 1045 self.clusters['a_value'][index:index+4] = np.asarray(v, dtype=np.float32)
921 self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(i)] = self.cluster_pos[i] 1046 self.G_cluster.vertex_properties["pos"][self.G_cluster.vertex(i)] = self.cluster_pos[i]
922 1047
923 -  
924 -  
925 -  
926 """ 1048 """
927 - Function that generates the clusters for an unclustered graph  
928 - These are to be represented by the arcs  
929 - """  
930 - def gen_clusters(self, G, bbl, bbu, n_c = None, edge_metric = 'volume', vertex_metric = 'degree'):  
931 -  
932 - #Generate the clusters  
933 - self.labels = nwt.Network.spectral_clustering(G,'length', n_clusters = n_c)  
934 - bb = nwt.AABB(G)  
935 - #print("FLJKKHDFLKJFDLKJFDLKJ ", m)  
936 - pts = []  
937 - x, y, z = bb.project_grid(3)  
938 - for i in range(3):  
939 - for j in range(3):  
940 - for k in range(3):  
941 - pts.append(np.array([x[i], y[j], z[k]]))  
942 -  
943 - #self.labels = nwt.Network.spectral_clustering(G,'length') 1049 + Function that creates the clusters, assuming that all the data is set already.
944 1050
945 - #Add clusters as a vertex property  
946 - G.vertex_properties["clusters"] = G.new_vertex_property("int", vals=self.labels)  
947 - num_clusters = len(np.unique(self.labels))  
948 - self.n_c = n_c  
949 - new_indices = []  
950 - pos = G.vertex_properties["p"].get_2d_array(range(3)).T  
951 -  
952 - #for each cluster find the average vertex position and match to closest point  
953 - #in the unique grid.  
954 - for i in range(n_c):  
955 - point = np.sum(pos[np.argwhere(self.labels == i)], axis=0)/len(np.argwhere(self.labels == i))  
956 - d = 100000000.0  
957 - idx = -1  
958 - for j in range(len(pts)):  
959 - dist = np.sqrt(np.power(pts[j][0]-point[0,0],2) + np.power(pts[j][1]-point[0,1],2) + np.power(pts[j][2]-point[0,2],2))  
960 - if dist < d:  
961 - d = dist  
962 - idx = j  
963 - new_indices.append(idx)  
964 - pts[idx] = np.array([100000000.0, 1000000000.0, 100000000.0])  
965 - #since there are more points than clusters, we need to make the indices range from  
966 - #[0, n_c)  
967 - j=0  
968 - unique_indices = np.array(new_indices)  
969 - for i in range(n_c):  
970 - idx = np.argmin(new_indices)  
971 - unique_indices[idx] = j  
972 - j += 1  
973 - new_indices[idx] = 100  
974 -  
975 - lbl = np.zeros(self.labels.shape)  
976 - for i in range(n_c):  
977 - idxs = np.argwhere(self.labels == i)  
978 - new_idx = np.argwhere(unique_indices == i)  
979 - lbl[idxs] = unique_indices[i]  
980 -  
981 - self.labels = lbl  
982 - G.vertex_properties["clusters"] = G.new_vertex_property("int", vals=self.labels)  
983 -  
984 -  
985 -  
986 -  
987 -  
988 - #add colormap  
989 - G.vertex_properties["RGBA"] = nwt.Network.map_property_to_color(G, G.vertex_properties["clusters"]) 1051 + """
  1052 + def gen_cluster_vbo(self, G, bbl, bbu, num_clusters, edge_metric = 'volume', vertex_metric = 'degree', update_color = True):
  1053 + #add colormap
  1054 + if(update_color == True):
  1055 + G.vertex_properties["RGBA"] = nwt.Network.map_property_to_color(G, G.vertex_properties["clusters"])
990 1056
991 #generate an empty property set for the clusters. 1057 #generate an empty property set for the clusters.
992 self.clusters = np.zeros(num_clusters*4, dtype=[('a_position', np.float32, 3), 1058 self.clusters = np.zeros(num_clusters*4, dtype=[('a_position', np.float32, 3),
@@ -1105,6 +1171,66 @@ class GraphCanvas(scene.SceneCanvas): @@ -1105,6 +1171,66 @@ class GraphCanvas(scene.SceneCanvas):
1105 # self.edges_s = [] 1171 # self.edges_s = []
1106 #print(self.edges_s) 1172 #print(self.edges_s)
1107 1173
  1174 + """
  1175 + Function that generates the clusters for an unclustered graph
  1176 + These are to be represented by the arcs
  1177 + """
  1178 + def gen_clusters(self, G, bbl, bbu, n_c = None, edge_metric = 'volume', vertex_metric = 'degree'):
  1179 +
  1180 + #Generate the clusters
  1181 + self.labels = nwt.Network.spectral_clustering(G,'length', n_clusters = n_c)
  1182 + bb = nwt.AABB(G)
  1183 + #print("FLJKKHDFLKJFDLKJFDLKJ ", m)
  1184 + pts = []
  1185 + x, y, z = bb.project_grid(3)
  1186 + for i in range(3):
  1187 + for j in range(3):
  1188 + for k in range(3):
  1189 + pts.append(np.array([x[i], y[j], z[k]]))
  1190 +
  1191 +
  1192 + #self.labels = nwt.Network.spectral_clustering(G,'length')
  1193 + #Add clusters as a vertex property
  1194 + G.vertex_properties["clusters"] = G.new_vertex_property("int", vals=self.labels)
  1195 + num_clusters = len(np.unique(self.labels))
  1196 + self.n_c = n_c
  1197 + new_indices = []
  1198 + pos = G.vertex_properties["p"].get_2d_array(range(3)).T
  1199 +
  1200 + #for each cluster find the average vertex position and match to closest point
  1201 + #in the unique grid.
  1202 + for i in range(n_c):
  1203 + point = np.sum(pos[np.argwhere(self.labels == i)], axis=0)/len(np.argwhere(self.labels == i))
  1204 + d = 100000000.0
  1205 + idx = -1
  1206 + for j in range(len(pts)):
  1207 + dist = np.sqrt(np.power(pts[j][0]-point[0,0],2) + np.power(pts[j][1]-point[0,1],2) + np.power(pts[j][2]-point[0,2],2))
  1208 + if dist < d:
  1209 + d = dist
  1210 + idx = j
  1211 + new_indices.append(idx)
  1212 + pts[idx] = np.array([100000000.0, 1000000000.0, 100000000.0])
  1213 + #since there are more points than clusters, we need to make the indices range from
  1214 + #[0, n_c)
  1215 + j=0
  1216 + unique_indices = np.array(new_indices)
  1217 + for i in range(n_c):
  1218 + idx = np.argmin(new_indices)
  1219 + unique_indices[idx] = j
  1220 + j += 1
  1221 + new_indices[idx] = 100
  1222 +
  1223 + lbl = np.zeros(self.labels.shape)
  1224 + for i in range(n_c):
  1225 + idxs = np.argwhere(self.labels == i)
  1226 + new_idx = np.argwhere(unique_indices == i)
  1227 + lbl[idxs] = unique_indices[i]
  1228 +
  1229 + self.labels = lbl
  1230 + G.vertex_properties["clusters"] = G.new_vertex_property("int", vals=self.labels)
  1231 + self.gen_cluster_vbo(self.G, bbl, bbu, num_clusters, edge_metric, vertex_metric)
  1232 +
  1233 +
1108 1234
1109 """ 1235 """
1110 Function that expands that generates the layout and updates the buffer 1236 Function that expands that generates the layout and updates the buffer
@@ -1124,11 +1250,288 @@ class GraphCanvas(scene.SceneCanvas): @@ -1124,11 +1250,288 @@ class GraphCanvas(scene.SceneCanvas):
1124 print(self.view) 1250 print(self.view)
1125 self.refresh() 1251 self.refresh()
1126 1252
  1253 +
  1254 + """
  1255 + Function for generating a distance field based on the clusters in the
  1256 + clustered 3D network.
  1257 + """
  1258 + def distancefield(self, G):
  1259 +
  1260 + import scipy as sp
  1261 + #generate a meshgrid of the appropriate size and resolution to surround the network
  1262 + #get the space occupied by the network
  1263 + lower = self.bbl
  1264 + upper = self.bbu
  1265 + R = np.asarray(np.floor(abs(lower-upper)), dtype=np.int)
  1266 +
  1267 + x = np.linspace(lower[0], upper[0], R[0]) #get the grid points for uniform sampling of this space
  1268 + y = np.linspace(lower[1], upper[1], R[1])
  1269 + z = np.linspace(lower[2], upper[2], R[2])
  1270 + X, Y, Z = np.meshgrid(x, y, z, indexing='ij')
  1271 +
  1272 + Q = np.stack((X, Y, Z), 3)
  1273 + #get a list of all node positions in the network
  1274 + P = []
  1275 + #get a mirrored list of all the point labels
  1276 + L = []
  1277 +
  1278 + for e in G.edges():
  1279 + X_p = G.edge_properties["x"][e]
  1280 + Y_p = G.edge_properties["y"][e]
  1281 + Z_p = G.edge_properties["z"][e]
  1282 + l = list(np.array([X_p,Y_p,Z_p]).T)
  1283 + #generate points list foe each edge
  1284 +
  1285 + P = P + l
  1286 + #generate labels list for each edge
  1287 + if G.vertex_properties["clusters"][e.source()] == G.vertex_properties["clusters"][e.target()]:
  1288 + c = G.vertex_properties["clusters"][e.source()]
  1289 + for i in range(len(l)):
  1290 + L.append(c)
  1291 + #if source and target have the same label, all points have that label
  1292 + else:
  1293 + #if source != target label, then point takes on the closest label
  1294 + source = []
  1295 + source.append(0.0)
  1296 + target = []
  1297 + for i in range(1, len(l)):
  1298 + dist = math.sqrt(pow(l[i][0]-l[i-1][0],2) + pow(l[i][1]-l[i-1][1],2) + pow(l[i][2]-l[i-1][2],2))
  1299 + source.append(dist + source[len(source)-1])
  1300 + target = source[::-1]
  1301 + for i in range(len(l)):
  1302 + if source[i] > target[i]:
  1303 + L.append(G.vertex_properties["clusters"][e.source()])
  1304 + else:
  1305 + L.append(G.vertex_properties["clusters"][e.target()])
  1306 +
  1307 + #turn that list into a Numpy array so that we can create a KD tree
  1308 + P = np.array(P)
  1309 +
  1310 + #generate a KD-Tree out of the network point array
  1311 + tree = sp.spatial.cKDTree(P)
  1312 +
  1313 + D, I = tree.query(Q)
  1314 + C = np.zeros(I.shape, dtype=np.int)
  1315 + for i in range(I.shape[0]):
  1316 + for j in range(I.shape[1]):
  1317 + for k in range(I.shape[2]):
  1318 + C[i,j,k] = L[I[i,j,k]]
  1319 +
  1320 + self.write_VTK_R(G, "./test_field.vtk", Q, C, X, Y, Z)
  1321 + return D, x, y, z, C
  1322 +
  1323 + """
  1324 + Function for saving the distance field based on the clusters in the
  1325 + clustered 3D network.
  1326 + """
  1327 + def write_VTK_R(self, G, filepath, Q, C, X, Y, Z):\
  1328 +
  1329 + from pyevtk.hl import gridToVTK
  1330 + from pyevtk.hl import imageToVTK
  1331 + from pyevtk.vtk import VtkFile, VtkImageData
  1332 + import vtk
  1333 + #T = C.reshape(C.shape[0]*C.shape[1]*C.shape[2])
  1334 + #C = T.reshape((C.shape[0], C.shape[1], C.shape[2]), order = 'C')
  1335 + ColorR = np.zeros((C.shape[0], C.shape[1], C.shape[2]))
  1336 + ColorG = np.zeros((C.shape[0], C.shape[1], C.shape[2]))
  1337 + ColorB = np.zeros((C.shape[0], C.shape[1], C.shape[2]))
  1338 + ColorA = np.zeros((C.shape[0], C.shape[1], C.shape[2]))
  1339 + #ColorR = ColorG = ColorB = ColorA = np.chararray((P.shape[0], P.shape[1], P.shape[2]))
  1340 + G.vertex_properties["RGBA"] = nwt.Network.map_property_to_color(G, G.vertex_properties["clusters"])
  1341 + self.color_edges(G)
  1342 + thisdict = {}
  1343 + otherdict = {}
  1344 + for v in G.vertices():
  1345 + thisdict[G.vertex_properties["clusters"][v]] = G.vertex_properties["RGBA"][v]
  1346 + color = G.vertex_properties["RGBA"][v].get_array()
  1347 + c = '#%02x%02x%02x%02x' % (int(color[0]*255), int(color[1]*255), int(color[2]*255), int(color[3]*255*0.3))
  1348 + otherdict[G.vertex_properties["clusters"][v]] = c
  1349 +
  1350 + print(thisdict, file=open('myfile.txt', 'w'))
  1351 + i = 0
  1352 + for i in range(C.shape[0]):
  1353 + for j in range(C.shape[1]):
  1354 + for k in range(C.shape[2]):
  1355 + c = thisdict[C[i,j,k]]
  1356 + ColorR[i,j,k] = c[0]
  1357 + ColorG[i,j,k] = c[1]
  1358 + ColorB[i,j,k] = c[2]
  1359 + ColorA[i,j,k] = c[3]
  1360 +
  1361 +
  1362 + # fig = plt.figure()
  1363 + # ax = fig.gca(projection='3d')
  1364 + # for e in G.edges():
  1365 + # X = G.edge_properties["x"][e]
  1366 + # Y = G.edge_properties["y"][e]
  1367 + # Z = G.edge_properties["z"][e]
  1368 + # color = G.edge_properties['RGBA'][e].get_array()
  1369 + # c = '#%02x%02x%02x' % (int(color[0]*255), int(color[1]*255), int(color[2]*255))
  1370 + # ax.plot(X,Y,Z, color=c)
  1371 + # print("plotting line")
  1372 + #
  1373 + #
  1374 + # print("generating cells")
  1375 + # x, y, z = np.indices(np.array(C.shape) + 1).astype(float)
  1376 + # filled = np.ones(C.shape)
  1377 + # print("replacing dict")
  1378 + # vox = replace_with_dict(C, otherdict)
  1379 + #
  1380 + # print("plotting voxels")
  1381 + # ax.voxels(x, y, z, filled, facecolors=vox)
  1382 +
  1383 +
  1384 + #ax.imshow(np.stack((ColorR[:,:,0], ColorG[:,:,0], ColorB[:,:,0]), axis = 2))
  1385 +
  1386 + #plt.show()
  1387 +
  1388 +
  1389 +
  1390 +
  1391 +
  1392 + filename = "./image_fixed.vti"
  1393 + imageData = vtk.vtkImageData()
  1394 + imageData.SetDimensions(C.shape[0], C.shape[1], C.shape[2])
  1395 + imageData.SetOrigin(0.0, 0.0, 0.0)
  1396 + imageData.SetSpacing(1.0, 1.0, 1.0)
  1397 + if vtk.VTK_MAJOR_VERSION <= 5:
  1398 + imageData.SetNumberOfScalarComponents(4)
  1399 + imageData.SetScalarTypeToDouble()
  1400 + else:
  1401 + imageData.AllocateScalars(vtk.VTK_DOUBLE, 4)
  1402 +
  1403 + for z in range(C.shape[2]):
  1404 + for y in range(C.shape[1]):
  1405 + for x in range(C.shape[0]):
  1406 + imageData.SetScalarComponentFromDouble(x, y, z, 0, ColorR[x,y,z])
  1407 + imageData.SetScalarComponentFromDouble(x, y, z, 1, ColorG[x,y,z])
  1408 + imageData.SetScalarComponentFromDouble(x, y, z, 2, ColorB[x,y,z])
  1409 + imageData.SetScalarComponentFromDouble(x, y, z, 3, ColorA[x,y,z])
  1410 +
  1411 +
  1412 + writer = vtk.vtkXMLImageDataWriter()
  1413 + writer.SetFileName(filename)
  1414 + if vtk.VTK_MAJOR_VERSION <= 5:
  1415 + writer.SetInputConnection(imageData.GetProducerPort())
  1416 + else:
  1417 + writer.SetInputData(imageData)
  1418 +
  1419 + writer.Write()
  1420 + nwt.Network.write_vtk(G, "./vessels_fixed.vtk", binning = False)
  1421 +
  1422 + def set_graph(self, G, bbl, bbu, subgraph = False):
  1423 + self.G = G
  1424 + self.bbl = bbl
  1425 + self.bbu = bbu
  1426 + clear(color=True, depth=True)
  1427 + self.subgraphs = subgraph
  1428 + self.current_color = "clusters"
  1429 + self.color_edges(G)
  1430 + print(self.G)
  1431 + color = G.vertex_properties["RGBA"].get_2d_array(range(4)).T
  1432 + size = nwt.Network.map_vertices_to_range(G, [30*self.pixel_scale, 8*self.pixel_scale], 'degree').get_array()
  1433 +
  1434 + position = G.vertex_properties["pos"].get_2d_array(range(3)).T
  1435 + #for p in range(position.shape[0]):
  1436 + # position[p][0] = position[p][0] + self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][0]
  1437 + # position[p][1] = position[p][1] + self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][1]
  1438 + # position[p][2] = position[p][2] + self.clusters["a_position"][G.vertex_properties["clusters"][G.vertex(p)]][2]
  1439 + #G.vertex_properties["pos"] = G.new_vertex_property("vector<double>", vals = position)
  1440 + edges = G.get_edges();
  1441 + edges = edges[:, 0:2]
  1442 + #width = nwt.Network.map_edges_to_range(G, [1*self.pixel_scale, 5*self.pixel_scale], 'volume').get_array()
  1443 + #ecolor = G.edge_properties["RGBA"].get_2d_array(range(4)).T
  1444 +
  1445 + self.data = np.zeros(G.num_vertices(), dtype=[('a_position', np.float32, 3),
  1446 + ('a_fg_color', np.float32, 4),
  1447 + ('a_bg_color', np.float32, 4),
  1448 + ('a_size', np.float32, 1),
  1449 + ('a_linewidth', np.float32, 1),
  1450 + ('a_unique_id', np.float32, 4),
  1451 + ('a_selection', np.float32, 1),
  1452 + ])
  1453 +
  1454 + #self.edges = edges.astype(np.uint32)
  1455 + self.data['a_position'] = position
  1456 + #fg color is the color of the ring
  1457 + self.data['a_fg_color'] = 0, 0, 0, 1
  1458 + self.data['a_bg_color'] = color
  1459 + self.data['a_size'] = size
  1460 + self.data['a_linewidth'] = 4.*self.pixel_scale
  1461 + self.data['a_unique_id'] = self.gen_vertex_id(G)
  1462 + self.data['a_selection'] = G.vertex_properties["selection"].get_array()
  1463 + #self.data['a_graph_size'] = [bbu-bbl]
  1464 +
  1465 + #self.program['u_graph_size'] = [bbu-bbl]
  1466 +
  1467 + self.vbo = gloo.VertexBuffer(self.data)
  1468 + self.gen_line_vbo(G)
  1469 + #self.gen_cylinder_vbo(G)
  1470 + if(self.subgraphs):
  1471 + self.labels = self.G.vp["clusters"].get_array()
  1472 + self.gen_cluster_vbo(self.G, bbl, bbu, self.n_c)
  1473 + self.vbo_s = gloo.VertexBuffer(self.clusters)
  1474 + self.index_s = gloo.IndexBuffer(self.edges_s)
  1475 + #self.index = gloo.IndexBuffer(self.edges)
  1476 + self.program_e.bind(self.vbo_line)
  1477 + self.program.bind(self.vbo)
  1478 + if(self.subgraphs):
  1479 + #self.program_e_s.bind(self.vbo_s)
  1480 + self.program_s.bind(self.vbo_s)
  1481 + if DEBUG:
  1482 + print(self.view)
  1483 + self.update_text(self.current_color)
  1484 + self.update_color_bar(self.current_color)
  1485 + self.refresh()
  1486 +
  1487 +
  1488 + def update_text(self, text):
  1489 + self.t1 = Text(text, parent=self.scene, color = 'black', method='gpu', anchor_x = 'right', anchor_y='top')
  1490 + self.t1.font_size = 24
  1491 + #self.t1.anchor_y = 'top'
  1492 + #self.t1.anchor_x = 'right'
  1493 +# print(self.t1.bounds(0), self.t1.bounds(1))
  1494 + self.t1.pos = self.size[0]-10, self.size[1] // 24
  1495 + self.refresh()
  1496 +
  1497 + def update_color_bar(self, color_property):
  1498 + if color_property != "":
  1499 + prop = self.G.vp[color_property].get_array().T
  1500 + mx = max(prop)
  1501 + mn = min(prop)
  1502 + else:
  1503 + mx = 1.0
  1504 + mn = 0.0
  1505 + if(color_property=="clusters"):
  1506 + cm = 'tab20'
  1507 + else:
  1508 + cm = 'plasma'
  1509 + self.c_bar = ColorBar(cmap=cm, orientation = 'bottom',
  1510 + size = (self.size[0] // 3, self.size[1] // 24), clim = (mn, mx),
  1511 + border_width = 10.0,border_color = 'white',
  1512 + parent=self.scene,
  1513 + pos=(self.size[0] // 3 // 2 + 20, self.size[1] // 24),
  1514 + padding = (100, 100)
  1515 + )
  1516 + self.refresh()
  1517 +
1127 """ 1518 """
1128 Loads the data G and generates all the buffers necessary as well as performs 1519 Loads the data G and generates all the buffers necessary as well as performs
1129 spectral clustering on the graph passed if the subgraph is set to true. 1520 spectral clustering on the graph passed if the subgraph is set to true.
1130 """ 1521 """
1131 - def set_data(self, G, bbl, bbu, subgraph=True): 1522 + def set_data(self, G, bbl, bbu, subgraph=True, G_other = None):
  1523 +
  1524 + def in_hull(point, hull, tolerance=1e-6):
  1525 + return all(
  1526 + (np.dot(eq[:-1], point) + eq[-1] <= tolerance)
  1527 + for eq in hull.equations)
  1528 +
  1529 +# def in_hull(p, hull):
  1530 +# if not isinstance(hull,Delaunay):
  1531 +# hull = Delaunay(hull)
  1532 +#
  1533 +# return hull.find_simplex(p)>=0
  1534 +
1132 if DEBUG: 1535 if DEBUG:
1133 print("Setting data") 1536 print("Setting data")
1134 self.G = G 1537 self.G = G
@@ -1137,11 +1540,115 @@ class GraphCanvas(scene.SceneCanvas): @@ -1137,11 +1540,115 @@ class GraphCanvas(scene.SceneCanvas):
1137 clear(color=True, depth=True) 1540 clear(color=True, depth=True)
1138 self.subgraphs = True 1541 self.subgraphs = True
1139 self.current_color = "clusters" 1542 self.current_color = "clusters"
1140 - if(subgraph==True):  
1141 - self.gen_clusters(G, bbl, bbu, n_c=19)  
1142 1543
  1544 + if(subgraph==True and G_other == None):
  1545 + self.gen_clusters(G, bbl, bbu, n_c=19)
  1546 + self.G.vertex_properties["idx"] = self.G.vertex_index
1143 #color based on clusters 1547 #color based on clusters
1144 self.color_edges(G) 1548 self.color_edges(G)
  1549 + else:
  1550 + #polygons = []
  1551 + self.G.vertex_properties["idx"] = self.G.vertex_index
  1552 + self.G.vertex_properties["clusters"] = self.G.new_vertex_property("int", vals=np.full(self.G.num_vertices(), -1, dtype="int"))
  1553 + num_clusters = len(np.unique(G_other.vertex_properties["clusters"].get_array().T))
  1554 + color_lookup = []
  1555 + lbls = G_other.vertex_properties["clusters"].get_array().T
  1556 + for i in range(num_clusters):
  1557 + idx = np.where(lbls == i)[0][0]
  1558 + color_lookup.append(G_other.vertex_properties["RGBA"][G_other.vertex(idx)])
  1559 +
  1560 +
  1561 + self.n_c = num_clusters
  1562 + D, x, y, z, C = self.distancefield(G_other)
  1563 + print(len(x), len(y), len(z))
  1564 + for v in self.G.vertices():
  1565 + p = self.G.vertex_properties["p"][v]
  1566 + x_temp = np.fabs(x - p[0])
  1567 + idx_x = x_temp.argmin()
  1568 + y_temp = np.fabs(y - p[1])
  1569 + idx_y = y_temp.argmin()
  1570 + z_temp = np.fabs(z - p[2])
  1571 + idx_z = z_temp.argmin()
  1572 + cluster = C[idx_x][idx_y][idx_z]
  1573 + self.G.vertex_properties["clusters"][v] = cluster
  1574 + self.G.vertex_properties["RGBA"][v] = color_lookup[cluster]
  1575 +
  1576 +
  1577 +
  1578 + ###############OLD Comparison mechanic########################
  1579 +# polygons = []
  1580 +# for i in range(num_clusters):
  1581 +# #num_v_in_cluster = len(np.argwhere(self.labels == i))
  1582 +# vfilt = np.zeros([G_other.num_vertices(), 1], dtype="bool")
  1583 +# vfilt[np.argwhere(G_other.vertex_properties["clusters"].get_array().T == i)] = 1
  1584 +# vfilt_prop = G_other.new_vertex_property("bool", vals = vfilt)
  1585 +# G_other.set_vertex_filter(vfilt_prop)
  1586 +#
  1587 +# #get the filtered properties
  1588 +# g = nwt.gt.Graph(G_other, prune=True, directed=False)
  1589 +# color = g.vertex_properties["RGBA"][g.vertex(0)]
  1590 +# positions = g.vertex_properties["p"].get_2d_array(range(3)).T
  1591 +# hull = ConvexHull(positions)
  1592 +# #hull = Delaunay(positions)
  1593 +# #hull = multipoint.convex_hull
  1594 +# polygons.append(hull)
  1595 +# G_other.clear_filters()
  1596 +# for v in self.G.vertices():
  1597 +# if in_hull(self.G.vertex_properties["p"][v], hull) and self.G.vertex_properties["clusters"][v] == -1:
  1598 +# self.G.vertex_properties["clusters"][v] = i
  1599 +# self.G.vertex_properties["RGBA"][v] = color
  1600 +## if hull.contains(Point(self.G.vertex_properties["p"][v])):
  1601 +## self.G.vertex_properties["clusters"][v] = i
  1602 +## self.G.vertex_properties["RGBA"][v] = color
  1603 +#
  1604 +# unassigned = np.argwhere(self.G.vertex_properties["clusters"].get_array().T == -1)
  1605 +# while len(unassigned > 0):
  1606 +# for i in range(len(unassigned)):
  1607 +# gen = self.G.vertex(unassigned[i]).all_neighbors()
  1608 +# neighbors = []
  1609 +# neighbors_clusters = []
  1610 +# for j in gen:
  1611 +# neighbors.append(j)
  1612 +# neighbors_clusters.append(self.G.vertex_properties["clusters"][j])
  1613 +# if len(np.unique(neighbors_clusters)) == 1 and np.unique(neighbors_clusters[0]) != -1:
  1614 +# self.G.vertex_properties["clusters"][self.G.vertex(unassigned[i])] = \
  1615 +# self.G.vertex_properties["clusters"][neighbors[0]]
  1616 +# self.G.vertex_properties["RGBA"][self.G.vertex(unassigned[i])] = \
  1617 +# self.G.vertex_properties["RGBA"][neighbors[0]]
  1618 +# else:
  1619 +# c, count = np.unique(neighbors_clusters, return_counts=True)
  1620 +# for k in range(len(c)):
  1621 +# if c[k] == -1:
  1622 +# c = np.delete(c, k)
  1623 +# count = np.delete(count, k)
  1624 +# break
  1625 +# if len(c) > 0:
  1626 +# cluster = np.argwhere(count == max(count))[0]
  1627 +# self.G.vertex_properties["clusters"][self.G.vertex(unassigned[i])] = c[cluster[0]]
  1628 +# for v in range(len(neighbors)):
  1629 +# if self.G.vertex_properties["clusters"][self.G.vertex(unassigned[i])] == c[cluster[0]]:
  1630 +# self.G.vertex_properties["RGBA"][self.G.vertex(unassigned[i])] = \
  1631 +# self.G.vertex_properties["RGBA"][neighbors[v]]
  1632 +# unassigned = np.argwhere(self.G.vertex_properties["clusters"].get_array().T == -1)
  1633 +# #print("stuff")
  1634 +# #for j in range(len(neighbors_clusters)):
  1635 +#
  1636 +# #self.G.vertex_properties["RGBA"] = nwt.Network.map_property_to_color(self.G, self.G.vertex_properties["clusters"])
  1637 + temp = self.G.vertex_properties["clusters"].get_array().T
  1638 + print(np.unique(temp))
  1639 + self.labels = copy.copy(temp)
  1640 +# c = np.unique(temp)
  1641 +# idx = 0
  1642 +# for i in range(len(c)):
  1643 +# self.labels[np.argwhere(temp == c[i])] = idx
  1644 +# idx += 1
  1645 +#
  1646 + ###############/OLD Comparison mechanic########################
  1647 + self.G.vertex_properties["clusters"] = self.G.new_vertex_property("int", vals = self.labels)
  1648 + self.n_c = len(np.unique(self.labels))
  1649 + self.gen_cluster_vbo(self.G, bbl, bbu, self.n_c, update_color = False)
  1650 + self.color_edges(self.G)
  1651 +
1145 1652
1146 color = G.vertex_properties["RGBA"].get_2d_array(range(4)).T 1653 color = G.vertex_properties["RGBA"].get_2d_array(range(4)).T
1147 size = nwt.Network.map_vertices_to_range(G, [30*self.pixel_scale, 8*self.pixel_scale], 'degree').get_array() 1654 size = nwt.Network.map_vertices_to_range(G, [30*self.pixel_scale, 8*self.pixel_scale], 'degree').get_array()
@@ -1193,6 +1700,8 @@ class GraphCanvas(scene.SceneCanvas): @@ -1193,6 +1700,8 @@ class GraphCanvas(scene.SceneCanvas):
1193 self.program_s.bind(self.vbo_s) 1700 self.program_s.bind(self.vbo_s)
1194 if DEBUG: 1701 if DEBUG:
1195 print(self.view) 1702 print(self.view)
  1703 + self.update_text(self.current_color)
  1704 + self.update_color_bar(self.current_color)
1196 self.refresh() 1705 self.refresh()
1197 1706
1198 """ 1707 """
@@ -1201,7 +1710,10 @@ class GraphCanvas(scene.SceneCanvas): @@ -1201,7 +1710,10 @@ class GraphCanvas(scene.SceneCanvas):
1201 def on_resize(self, event): 1710 def on_resize(self, event):
1202 set_viewport(0, 0, *event.physical_size) 1711 set_viewport(0, 0, *event.physical_size)
1203 self.fbo = gloo.FrameBuffer(color=gloo.RenderBuffer(self.size[::-1]), depth=gloo.RenderBuffer(self.size[::-1])) 1712 self.fbo = gloo.FrameBuffer(color=gloo.RenderBuffer(self.size[::-1]), depth=gloo.RenderBuffer(self.size[::-1]))
1204 - 1713 + self.update_text(self.current_color)
  1714 + self.update_color_bar(self.current_color)
  1715 + self.refresh()
  1716 + app.Canvas.update(self)
1205 1717
1206 """ 1718 """
1207 Overloaded function that is called during every self.update() call 1719 Overloaded function that is called during every self.update() call
@@ -1215,8 +1727,10 @@ class GraphCanvas(scene.SceneCanvas): @@ -1215,8 +1727,10 @@ class GraphCanvas(scene.SceneCanvas):
1215 if(self.subgraphs): 1727 if(self.subgraphs):
1216 self.program_e_s.draw('triangles', indices=self.index_clusters_s) 1728 self.program_e_s.draw('triangles', indices=self.index_clusters_s)
1217 self.program_s.draw('triangles', indices=self.index_s) 1729 self.program_s.draw('triangles', indices=self.index_s)
1218 - print("updated ", self.num)  
1219 - self.num += 1 1730 + #print("updated ", self.num)
  1731 + #self.num += 1
  1732 + self.t1.draw()
  1733 + self.c_bar.draw()
1220 #self._u 1734 #self._u
1221 #self._update_pending = True 1735 #self._update_pending = True
1222 #app.Canvas.update(self) 1736 #app.Canvas.update(self)
@@ -1227,6 +1741,7 @@ class GraphCanvas(scene.SceneCanvas): @@ -1227,6 +1741,7 @@ class GraphCanvas(scene.SceneCanvas):
1227 vispy 0.6.3 1741 vispy 0.6.3
1228 """ 1742 """
1229 def refresh(self): 1743 def refresh(self):
  1744 + self.update_view_global()
1230 self.update() 1745 self.update()
1231 app.Canvas.update(self) 1746 app.Canvas.update(self)
1232 1747
@@ -1289,6 +1804,7 @@ class GraphCanvas(scene.SceneCanvas): @@ -1289,6 +1804,7 @@ class GraphCanvas(scene.SceneCanvas):
1289 #imsave("test_ori.png", buff) 1804 #imsave("test_ori.png", buff)
1290 self.fbo.activate() 1805 self.fbo.activate()
1291 if clusters == False: 1806 if clusters == False:
  1807 + self.refresh()
1292 self.program['u_picking'] = True 1808 self.program['u_picking'] = True
1293 clear(color='white', depth=True) 1809 clear(color='white', depth=True)
1294 self.program.draw('points') 1810 self.program.draw('points')
@@ -1336,6 +1852,12 @@ class GraphCanvas(scene.SceneCanvas): @@ -1336,6 +1852,12 @@ class GraphCanvas(scene.SceneCanvas):
1336 else: 1852 else:
1337 return self.cluster_dict[tuple(color)] 1853 return self.cluster_dict[tuple(color)]
1338 1854
  1855 + def update_view_global(self):
  1856 + self.program['u_view'] = self.view
  1857 + self.program_e['u_view'] = self.view
  1858 + self.program_s['u_view'] = self.view
  1859 + self.program_e_s['u_view'] = self.view
  1860 +
1339 1861
1340 """ 1862 """
1341 Top level handle-mouse presee event for either left or right click 1863 Top level handle-mouse presee event for either left or right click
@@ -1361,8 +1883,10 @@ class GraphCanvas(scene.SceneCanvas): @@ -1361,8 +1883,10 @@ class GraphCanvas(scene.SceneCanvas):
1361 # #if menu.exec_(event.globalPos()): 1883 # #if menu.exec_(event.globalPos()):
1362 # # print(item.text()) 1884 # # print(item.text())
1363 if(event.button == 1): 1885 if(event.button == 1):
1364 - if(self.view[0][0] > 0.0010): 1886 + if(self.view[0][0] > 0.0024):
  1887 + self.refresh()
1365 c_id = self.get_clicked_id(event) 1888 c_id = self.get_clicked_id(event)
  1889 + self.refresh()
1366 if(c_id != None): 1890 if(c_id != None):
1367 self.original_point = self.G.vertex_properties["pos"][self.G.vertex(c_id)] 1891 self.original_point = self.G.vertex_properties["pos"][self.G.vertex(c_id)]
1368 self.location = event.pos 1892 self.location = event.pos
@@ -1373,7 +1897,10 @@ class GraphCanvas(scene.SceneCanvas): @@ -1373,7 +1897,10 @@ class GraphCanvas(scene.SceneCanvas):
1373 update_view() 1897 update_view()
1374 #print("Clicked on:", event.pos) 1898 #print("Clicked on:", event.pos)
1375 else: 1899 else:
  1900 +# c_id = None
  1901 + self.refresh()
1376 c_id = self.get_clicked_id(event, True) 1902 c_id = self.get_clicked_id(event, True)
  1903 + self.refresh()
1377 if DEBUG: 1904 if DEBUG:
1378 print(c_id) 1905 print(c_id)
1379 if(c_id != None): 1906 if(c_id != None):
@@ -1390,6 +1917,27 @@ class GraphCanvas(scene.SceneCanvas): @@ -1390,6 +1917,27 @@ class GraphCanvas(scene.SceneCanvas):
1390 Gets the path and formats it in terms of vertex-to-vertex 1917 Gets the path and formats it in terms of vertex-to-vertex
1391 instead of source(obj)-to-source(obj) 1918 instead of source(obj)-to-source(obj)
1392 """ 1919 """
  1920 +
  1921 + def get_cluster(self, cluster_id):
  1922 + p = []
  1923 + num_v_in_cluster = len(np.argwhere(self.labels == cluster_id))
  1924 + vfilt = np.zeros([self.G.num_vertices(), 1], dtype="bool")
  1925 + vfilt[np.argwhere(self.labels == cluster_id)] = 1
  1926 + vfilt_prop = self.G.new_vertex_property("bool", vals = vfilt)
  1927 + self.G.set_vertex_filter(vfilt_prop)
  1928 +
  1929 + #get the filtered properties
  1930 + g = nwt.gt.Graph(self.G, prune=True, directed=False)
  1931 + self.G.clear_filters()
  1932 + for e in g.edges():
  1933 + source = g.vp["idx"][e.source()]
  1934 + target = g.vp["idx"][e.target()]
  1935 + temp = (int(source), int(target))
  1936 + p.append(temp)
  1937 +
  1938 + return p
  1939 +
  1940 +
1393 def get_path(self): 1941 def get_path(self):
1394 p = [] 1942 p = []
1395 for s in self.path: 1943 for s in self.path:
@@ -1422,12 +1970,14 @@ class GraphCanvas(scene.SceneCanvas): @@ -1422,12 +1970,14 @@ class GraphCanvas(scene.SceneCanvas):
1422 self.G.vertex_properties["selection"][vl[v]] = 2.0 1970 self.G.vertex_properties["selection"][vl[v]] = 2.0
1423 update_vertex_alpha(self, self.G.vertex(vl[v]), 1.0) 1971 update_vertex_alpha(self, self.G.vertex(vl[v]), 1.0)
1424 self.data['a_selection'][int(vl[v])] = 2.0 1972 self.data['a_selection'][int(vl[v])] = 2.0
  1973 + self.G.vp["exclude"][self.G.vertex(vl[v])] = True
1425 source.v_path.append(int(vl[v])) 1974 source.v_path.append(int(vl[v]))
1426 for e in el: 1975 for e in el:
1427 source.e_path.append(e) 1976 source.e_path.append(e)
1428 temp = self.G.edge_properties["RGBA"][e] 1977 temp = self.G.edge_properties["RGBA"][e]
1429 temp[3] = 1.0 1978 temp[3] = 1.0
1430 self.G.edge_properties["RGBA"][e] = temp 1979 self.G.edge_properties["RGBA"][e] = temp
  1980 + self.G.edge_properties["exclude"][e] = True
1431 1981
1432 1982
1433 def remove_from_path(self, source): 1983 def remove_from_path(self, source):
@@ -1435,15 +1985,19 @@ class GraphCanvas(scene.SceneCanvas): @@ -1435,15 +1985,19 @@ class GraphCanvas(scene.SceneCanvas):
1435 self.G.vertex_properties["selection"][self.G.vertex(v)] = 0.0 1985 self.G.vertex_properties["selection"][self.G.vertex(v)] = 0.0
1436 update_vertex_alpha(self,self.G.vertex(v), 0.5) 1986 update_vertex_alpha(self,self.G.vertex(v), 0.5)
1437 self.data['a_selection'][v] = 0.0 1987 self.data['a_selection'][v] = 0.0
  1988 + self.G.vertex_properties["exclude"][v] = False
1438 for e in source.e_path: 1989 for e in source.e_path:
1439 temp = self.G.edge_properties["RGBA"][e] 1990 temp = self.G.edge_properties["RGBA"][e]
1440 temp[3] = 0.0 1991 temp[3] = 0.0
1441 self.G.edge_properties["RGBA"][e] = temp 1992 self.G.edge_properties["RGBA"][e] = temp
  1993 + self.G.edge_properties["exclude"][e] = False
1442 source.clear_path() 1994 source.clear_path()
1443 1995
1444 if (event.button == 1): 1996 if (event.button == 1):
1445 - if(self.view[0][0] > 0.0010): 1997 + if(self.view[0][0] > 0.0024):
  1998 + self.refresh()
1446 c_id = self.get_clicked_id(event) 1999 c_id = self.get_clicked_id(event)
  2000 + self.refresh()
1447 if(c_id != None): 2001 if(c_id != None):
1448 #check whether this is the first node to be selected 2002 #check whether this is the first node to be selected
1449 if(self.pathing == False): 2003 if(self.pathing == False):
@@ -1496,6 +2050,7 @@ class GraphCanvas(scene.SceneCanvas): @@ -1496,6 +2050,7 @@ class GraphCanvas(scene.SceneCanvas):
1496 self.pathing = False 2050 self.pathing = False
1497 self.make_all_transparent(1.0) 2051 self.make_all_transparent(1.0)
1498 self.update_color_buffers() 2052 self.update_color_buffers()
  2053 + self.refresh()
1499 2054
1500 2055
1501 2056
@@ -1725,6 +2280,43 @@ class GraphCanvas(scene.SceneCanvas): @@ -1725,6 +2280,43 @@ class GraphCanvas(scene.SceneCanvas):
1725 self.location = event.pos 2280 self.location = event.pos
1726 self.refresh() 2281 self.refresh()
1727 2282
  2283 + def set_view_matrix(self, matrix):
  2284 + self.view = matrix
  2285 + self.program['u_view'] = self.view
  2286 + self.program_e['u_view'] = self.view
  2287 + self.program_s['u_view'] = self.view
  2288 + self.program_e_s['u_view'] = self.view
  2289 + self.refresh()
  2290 +
  2291 +
  2292 + def center_camera_on(self, camera):
  2293 + self.translate[0] += (0.0 - camera[0])/self.view[0][0]
  2294 + self.translate[1] += (0.0 - camera[1])/self.view[1][1]
  2295 + #self.view[3][0] = self.view[3][0]-(self.location[0]-event.pos[0])/10000.0
  2296 + #self.view[3][1] = self.view[3][1]+(self.location[1]-event.pos[1])/10000.0
  2297 +
  2298 + self.view = np.matmul(translate((self.translate[0], self.translate[1], 0)), scale((self.scale[0], self.scale[1], 0)))
  2299 +
  2300 + self.program['u_view'] = self.view
  2301 + self.program_e['u_view'] = self.view
  2302 + self.program_s['u_view'] = self.view
  2303 + self.program_e_s['u_view'] = self.view
  2304 + self.refresh()
  2305 +
  2306 + def zoom_camera_on(self, zoom):
  2307 + self.scale[0] = zoom[0]
  2308 + self.scale[1] = zoom[1]
  2309 +
  2310 + self.view = np.matmul(translate((self.translate[0], self.translate[1], 0)),
  2311 + scale((self.scale[0], self.scale[1], 0)))
  2312 +
  2313 + self.program['u_view'] = self.view
  2314 + self.program_e['u_view'] = self.view
  2315 + self.program_s['u_view'] = self.view
  2316 + self.program_e_s['u_view'] = self.view
  2317 + #print(event.delta[1])
  2318 + self.refresh()
  2319 +
1728 """ 2320 """
1729 Handles the mouse wheel zoom event. 2321 Handles the mouse wheel zoom event.
1730 """ 2322 """
@@ -5,15 +5,79 @@ Created on Mon Aug 5 15:42:19 2019 @@ -5,15 +5,79 @@ Created on Mon Aug 5 15:42:19 2019
5 5
6 @author: pavel 6 @author: pavel
7 """ 7 """
8 -  
9 from GraphCanvas import GraphCanvas 8 from GraphCanvas import GraphCanvas
  9 +from HistogramWidget import HistogramWidget
  10 +#from NodeInformationWidget import NodeInfoWidget
10 from PyQt5 import QtCore, QtGui, QtWidgets 11 from PyQt5 import QtCore, QtGui, QtWidgets
  12 +from PyQt5.Qt import QRect
11 import network_dep as nwt 13 import network_dep as nwt
  14 +from TubeWidget import TubeWidget
  15 +from vispy.scene.visuals import Text
12 16
13 import numpy as np 17 import numpy as np
14 18
15 DEBUG = False 19 DEBUG = False
16 20
  21 +
  22 +
  23 +class NodeInfoWidget(QtWidgets.QWidget):
  24 + def __init__(self, *args, **kwargs):
  25 + QtWidgets.QWidget.__init__(self)
  26 + self.layout = QtWidgets.QGridLayout()
  27 + self.resize(900, 300)
  28 + self.bar = None
  29 + print("stuff 22")
  30 + if 'hist' in kwargs:
  31 + print("stuff")
  32 + self.bar = HistogramWidget()
  33 + self.bar.canvas.create_native()
  34 + self.fibers_mini = TubeWidget()
  35 + self.fibers_mini.canvas.create_native()
  36 +
  37 + self.graph_mini1 = GraphWidget()
  38 + self.graph_mini1.canvas.create_native()
  39 + self.graph_mini2 = GraphWidget()
  40 + self.graph_mini2.canvas.create_native()
  41 + self.graph_mini3 = GraphWidget()
  42 + self.graph_mini3.canvas.create_native()
  43 + self.graph_mini4 = GraphWidget()
  44 + self.graph_mini4.canvas.create_native()
  45 +
  46 +
  47 +
  48 + self.graph_mini1.connect(self.fibers_mini)
  49 + self.fibers_mini.connect(self.graph_mini1)
  50 + self.fibers_mini.connect(self.graph_mini2)
  51 + self.fibers_mini.connect(self.graph_mini3)
  52 + self.fibers_mini.connect(self.graph_mini4)
  53 +
  54 +
  55 + self.layout.addWidget(self.graph_mini1.canvas.native, 0, 0, 1, 1)
  56 + self.layout.addWidget(self.graph_mini2.canvas.native, 0, 1, 1, 1)
  57 + self.layout.addWidget(self.graph_mini3.canvas.native, 1, 0, 1, 1)
  58 + self.layout.addWidget(self.graph_mini4.canvas.native, 1, 1, 1, 1)
  59 + #layout.addItem(vspacer, 0, 2, 2, 1)
  60 + if self.bar == None:
  61 + self.layout.addWidget(self.fibers_mini.canvas.native, 0, 2, 2, 2)
  62 + else:
  63 + self.layout.addWidget(self.fibers_mini.canvas.native, 0, 2, 1, 1)
  64 + self.layout.addWidget(self.bar.canvas.native, 1, 2, 1, 1)
  65 + #layout.setColumnStretch(0, 2)
  66 + #layout.setRowStretch(0, 2)
  67 + #layout.setColumnStretch(2, 1)
  68 + #layout.setRowStretch(0, 1)
  69 +
  70 + self.setLayout(self.layout)
  71 + #print(layout.getContentsMargins())
  72 + #top.show()
  73 +
  74 +
  75 +# def paintEvent(self, e):
  76 +# dc = QPainter(self)
  77 +
  78 + def bye(self):
  79 + self.exit(0)
  80 +
17 """ 81 """
18 Initializes the entire QTlayout and sets the mouse press events. 82 Initializes the entire QTlayout and sets the mouse press events.
19 These are connected to the slots such that each is processes by this class 83 These are connected to the slots such that each is processes by this class
@@ -34,11 +98,13 @@ class GraphWidget(QtWidgets.QWidget): @@ -34,11 +98,13 @@ class GraphWidget(QtWidgets.QWidget):
34 self.color = True 98 self.color = True
35 self.use_3D = False 99 self.use_3D = False
36 self.camera = [0,0,0] 100 self.camera = [0,0,0]
  101 + self.other = None
37 102
38 self.canvas.events.mouse_press.connect(self.on_mouse_press) 103 self.canvas.events.mouse_press.connect(self.on_mouse_press)
39 self.canvas.events.mouse_release.connect(self.on_mouse_release) 104 self.canvas.events.mouse_release.connect(self.on_mouse_release)
40 self.canvas.events.mouse_move.connect(self.on_mouse_move) 105 self.canvas.events.mouse_move.connect(self.on_mouse_move)
41 self.canvas.events.mouse_double_click.connect(self.on_mouse_double_click) 106 self.canvas.events.mouse_double_click.connect(self.on_mouse_double_click)
  107 + self.w = None
42 #self.canvas.events. 108 #self.canvas.events.
43 #self.show() 109 #self.show()
44 #self.repaint() 110 #self.repaint()
@@ -55,18 +121,19 @@ class GraphWidget(QtWidgets.QWidget): @@ -55,18 +121,19 @@ class GraphWidget(QtWidgets.QWidget):
55 self.canvas.set_current(event) 121 self.canvas.set_current(event)
56 if event.button == 2: 122 if event.button == 2:
57 if self.canvas.view[0][0] >= 0.0010: 123 if self.canvas.view[0][0] >= 0.0010:
58 - self.canvas.update() 124 + self.canvas.refresh()
59 c_id = self.canvas.get_clicked_id(event) 125 c_id = self.canvas.get_clicked_id(event)
60 - self.canvas.update() 126 + self.canvas.refresh()
61 else: 127 else:
62 - self.canvas.update() 128 + self.canvas.refresh()
63 c_id = self.canvas.get_clicked_id(event, clusters=True) 129 c_id = self.canvas.get_clicked_id(event, clusters=True)
64 - self.canvas.update() 130 + self.canvas.refresh()
65 #right click 131 #right click
66 if(c_id == None): 132 if(c_id == None):
67 menu = QtWidgets.QMenu(self) 133 menu = QtWidgets.QMenu(self)
68 NS = menu.addAction('Node Size') 134 NS = menu.addAction('Node Size')
69 - 135 + if (self.canvas.path != []):
  136 + FNP = menu.addAction("Filter Network Path")
70 #tmp = menu.addAction('temp') 137 #tmp = menu.addAction('temp')
71 tmp = menu.addMenu('Node Color') 138 tmp = menu.addMenu('Node Color')
72 vertex_props = self.canvas.G.vertex_properties.keys() 139 vertex_props = self.canvas.G.vertex_properties.keys()
@@ -76,12 +143,14 @@ class GraphWidget(QtWidgets.QWidget): @@ -76,12 +143,14 @@ class GraphWidget(QtWidgets.QWidget):
76 vertex_actions.append(tmp.addAction(vertex_props[i])) 143 vertex_actions.append(tmp.addAction(vertex_props[i]))
77 #tmp.addAction("Cluster") 144 #tmp.addAction("Cluster")
78 #NC = menu.addAction('Node Color') 145 #NC = menu.addAction('Node Color')
79 - #EXP = menu.addAction('Export VTK') 146 + EXP = menu.addAction('Export VTK')
80 #EXP_adv = menu.addAction('Export VTK Advanced') 147 #EXP_adv = menu.addAction('Export VTK Advanced')
81 NL = menu.addAction('New Layout') 148 NL = menu.addAction('New Layout')
82 NSL = menu.addAction('New Spring-Onion Layout (sum)') 149 NSL = menu.addAction('New Spring-Onion Layout (sum)')
83 NSLMI = menu.addAction('New Spring-Onion Layout(max)') 150 NSLMI = menu.addAction('New Spring-Onion Layout(max)')
84 EXPAND = menu.addAction('Expand') 151 EXPAND = menu.addAction('Expand')
  152 + CL = menu.addAction('Cluster_Layout')
  153 +
85 action = menu.exec_(event.native.globalPos()) 154 action = menu.exec_(event.native.globalPos())
86 if DEBUG: 155 if DEBUG:
87 print(action) 156 print(action)
@@ -101,11 +170,22 @@ class GraphWidget(QtWidgets.QWidget): @@ -101,11 +170,22 @@ class GraphWidget(QtWidgets.QWidget):
101 self.use_3D = False 170 self.use_3D = False
102 self.canvas.size_vertices(self.canvas.G, 'degree' ) 171 self.canvas.size_vertices(self.canvas.G, 'degree' )
103 self.canvas.color_vertices(self.canvas.G, 'degree') 172 self.canvas.color_vertices(self.canvas.G, 'degree')
  173 + if (self.canvas.path != []):
  174 + if action == FNP:
  175 + net = nwt.Network()
  176 + G1 = net.filterBorder(self.canvas.G)
  177 + BB = nwt.AABB(G1)
  178 + self.canvas.set_graph(G1, BB.A, BB.B, subgraph=True)
  179 + self.test.canvas.set_data(G1, BB.A, BB.B, 16)
  180 + self.canvas.refresh()
  181 + self.test.canvas.refresh()
  182 + #self.canvas.set_data()
  183 +
104 #if action == NC: 184 #if action == NC:
105 # self.canvas.color_vertices(self.canvas.G, not self.color) 185 # self.canvas.color_vertices(self.canvas.G, not self.color)
106 # self.color = not self.color 186 # self.color = not self.color
107 -# if action == EXP:  
108 -# nwt.Network.write_vtk(self.canvas.G, "./nwt.vtk") 187 + if action == EXP:
  188 + nwt.Network.write_vtk(self.canvas.G, "./nwt_small.vtk")
109 # if action == EXP_adv: 189 # if action == EXP_adv:
110 # nwt.Network.write_vtk(self.canvas.G, "./nwt_median_binned.vtk") 190 # nwt.Network.write_vtk(self.canvas.G, "./nwt_median_binned.vtk")
111 # nwt.Network.write_vtk(self.canvas.G, "./nwt_median_non_binned.vtk", binning=False) 191 # nwt.Network.write_vtk(self.canvas.G, "./nwt_median_non_binned.vtk", binning=False)
@@ -158,36 +238,221 @@ class GraphWidget(QtWidgets.QWidget): @@ -158,36 +238,221 @@ class GraphWidget(QtWidgets.QWidget):
158 #self.canvas.expand_clusters(self.canvas.G, self.canvas.n_c) 238 #self.canvas.expand_clusters(self.canvas.G, self.canvas.n_c)
159 239
160 self.canvas.animate(old_pos, new_pos) 240 self.canvas.animate(old_pos, new_pos)
  241 + if action == CL:
  242 + old_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T
  243 + self.canvas.voronoi_layout()
  244 + new_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T
  245 + if self.other != None:
  246 + other_old_pos = self.other.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T
  247 + self.other.canvas.voronoi_layout(G_c = self.canvas.G_cluster)
  248 + other_new_pos = self.other.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T
  249 + self.other.canvas.animate(other_old_pos, other_new_pos)
  250 + self.canvas.animate(old_pos, new_pos)
161 #self.canvas.size_vertices(self.canvas.G, 'degree_volume') 251 #self.canvas.size_vertices(self.canvas.G, 'degree_volume')
162 else: 252 else:
163 if self.canvas.view[0][0] >= 0.0010: 253 if self.canvas.view[0][0] >= 0.0010:
164 menu = QtWidgets.QMenu(self) 254 menu = QtWidgets.QMenu(self)
165 - NS = menu.addAction('Display Node Info') 255 + MnOC = menu.addAction('Minimize Other Clusters')
  256 + RA = menu.addAction('Reset Alpha')
  257 + NI = menu.addAction('Display Node Info')
  258 + CI = menu.addAction('Display Cluster Info')
166 action = menu.exec_(event.native.globalPos()) 259 action = menu.exec_(event.native.globalPos())
167 - if action == NS: 260 + if action == MnOC:
  261 + self.canvas.set_current(event)
  262 + self.canvas.refresh()
  263 + c_id = self.canvas.get_clicked_id(event)
  264 +
  265 + cluster_id = self.canvas.G.vp["clusters"][self.canvas.G.vertex(c_id)]
  266 + self.select.emit(self.canvas.get_cluster(cluster_id))
  267 + if action == RA: