def construct_network(df): g = Network("800px", "100%", bgcolor="#3c4647", font_color="white") for artist in df.artist: g.add_node(artist, label=artist, color="#26d18f") for related in df.related: g.add_node(related, label=related, color="#8965c7") g.add_edges(list(zip(df.artist, df.related))) counts = df.related.value_counts() for node in g.nodes: freq = str(counts.get(node['id'], 1)) # nodes with a value will scale their size # nodes with a title will include a hover tooltip on the node node.update({"value": freq, "title": f"Frequency: {freq}"}) g.inherit_edge_colors("to") for e in g.edges: edge_label = f'{e["from"]} ---> {e["to"]}' e.update({"title": edge_label}) g.barnes_hut(gravity=-17950, central_gravity=4.1, spring_length=220, spring_strength=.140, damping=.66, overlap=1) g.show("spotify_example.html")
def show(graph, output_filename): """ Saves an HTML file locally containing a visualization of the graph, and returns a pyvis Network instance of the graph. """ g = Network(directed=graph.is_directed) g.add_nodes(graph.nodes) g.add_edges(graph.edges) g.show(output_filename) return g
class Vis: def __init__(self, artists, adjacency): self.artists = artists self.adjacency = adjacency self.network = Network(height='1500px', width='1500px') def init_network(self): id = list(self.artists.keys()) label = [a['name'] for _, a in self.artists.items()] size = [a['popularity'] / 10 for _, a in self.artists.items()] self.network.add_nodes(id, label=label, size=size) [ self.network.add_edges([(key, v) for v in value]) for key, value in self.adjacency.items() ] def show_network(self): self.network.show('net.html')
def show(graph, output_filename): g = Network(directed=True) g.add_nodes(graph.nodes) g.add_edges(graph.edges) g.show(output_filename) return g
def show3(graph, output_filename): g = Network(directed=False) g.add_nodes(graph.nodes) g.add_edges(graph.edges) g.show(output_filename)
def network_vis(self, use_eqp=False, iter_matrix=False, spec_layout=False, lin=False, lin_dyn=None, title="Network Visualization", save_img=False, filename='network_viz'): """ Creates a visualization of the network G Parameters: G (DirectedGraph): A DirectedGraph object to visualize iter_matrix (ndarray): allows you to explicitly pass in the dynamics matrix of G. If left as False, then we run the dynamics simulation here spec_layout (bool): if False will display with random layout, otherwise it will use the spectral layout option lin (bool): Adds edge labels if the dynamics are linear lin_dyn (ndarray): the linear dynamics array title (str): Title of visualization save_img (bool): if True, saves the visualization with name 'filename' filename (str): filename """ if use_eqp: colors = self.colors group_dict = {} for color in colors.keys(): for node in colors[color]: group_dict[self.labeler[node]] = color else: # find synchronized communities communities = self.detect_sync(iters=80) # create a dictionary mapping each node to its community group_dict = {} for i in range(len(communities)): for node in communities[i][0]: group_dict[node] = i # create (and relabel) a pyvis graph object net = Network(directed=True) net.barnes_hut(gravity=-30000, spring_length=7500) net.show_buttons(filter_=['physics']) nxG = nx.relabel.relabel_nodes(nx.DiGraph(self.A.T), self.labeler) # set community membership as an attribute of nxG nx.set_node_attributes(nxG, group_dict, name='community') # generate random colors c = [ '#' + str(hex(np.random.randint(0, 16777215)))[2:] for i in list(colors) ] # add nodes to the pyvis object and color them according to group_dict for node in group_dict.keys(): net.add_node(node, color=c[group_dict[node]], value=1) # add edges directly from networkx object net.add_edges(nxG.edges()) # show visualization as html net.show('visualize.html')
class MyNetwork: def __init__(self): self.lock = threading.RLock() self.g: ig.Graph = None # 网络对象 self.vg: pyvis.network.Network = None # 动态可视化网络对象 self.vertex_df: pd.DataFrame = None # 节点文件表 # 度、度分布、聚集系数、介数、中心性、度相关性 self.vertex_count = None # 节点数 self.edge_count = None # 边数 self.avg_degree = None # 平均度 self.max_degree = None # 最大度 self.degree_list = None # 节点度列表 self.diameter = None # 网络直径 self.avg_path_len = None # 平均路经长 self.clustering_coefficient = None # 聚集系数 self.density = None # 网络密度 self.betweenness = None # 介数中心性列表 self.closeness = None # 紧密中心性列表 self.clique_number = None # 团数量 self.page_rank = None # pagerank值 self.colors = ['#70f3ff', '#44cef6', '#3eede7', '#1685a9', '#177cb0', '#065279', '#003472', '#4b5cc4', '#a1afc9', '#2e4e7e', '#3b2e7e', '#4a4266', '#426666', '#425066', '#574266', '#8d4bbb', '#815463', '#815476', '#4c221b', '#003371', '#56004f', '#801dae', '#4c8dae', '#b0a4e3', '#cca4e3', '#edd1d8', '#e4c6d0', '#ff461f', '#ff2d51', '#f36838', '#ed5736', '#ff4777', '#f00056', '#ffb3a7', '#f47983', '#db5a6b', '#c93756', '#f9906f', '#f05654', '#ff2121', '#f20c00', '#8c4356', '#c83c23', '#9d2933', '#ff4c00', '#ff4e20', '#f35336', '#dc3023', '#ff3300', '#cb3a56', '#a98175', '#b36d61', '#ef7a82', '#ff0097', '#c32136', '#be002f', '#c91f37', '#bf242a', '#c3272b', '#9d2933', '#60281e', '#622a1d', '#bce672', '#c9dd22', '#bddd22', '#afdd22', '#a3d900', '#9ed900', '#9ed048', '#96ce54', '#00bc12', '#0eb83a', '#0eb83a', '#0aa344', '#16a951', '#21a675', '#057748', '#0c8918', '#00e500', '#40de5a', '#00e079', '#00e09e', '#3de1ad', '#2add9c', '#2edfa3', '#7fecad', '#a4e2c6', '#7bcfa6', '#1bd1a5', '#48c0a3', '#549688', '#789262', '#758a99', '#50616d', '#424c50', '#41555d', '#eaff56', '#fff143', '#faff72', '#ffa631', '#ffa400', '#fa8c35', '#ff8c31', '#ff8936', '#ff7500', '#ffb61e', '#ffc773', '#ffc64b', '#f2be45', '#f0c239', '#e9bb1d', '#d9b611', '#eacd76', '#eedeb0', '#d3b17d', '#e29c45', '#a78e44', '#c89b40', '#ae7000', '#ca6924', '#b25d25', '#b35c44', '#9b4400', '#9c5333', '#a88462', '#896c39', '#827100', '#6e511e', '#7c4b00', '#955539', '#845a33', '#ffffff', '#e9e7ef', '#f0f0f4', '#e9f1f6', '#f0fcff', '#e3f9fd', '#d6ecf0', '#fffbf0', '#f2ecde', '#fcefe8', '#fff2df', '#f3f9f1', '#e0eee8', '#e0f0e9', '#c0ebd7', '#bbcdc5', '#c2ccd0', '#bacac6', '#808080', '#75878a', '#88ada6', '#6b6882', '#725e82', '#3d3b4f', '#392f41', '#75664d', '#5d513c', '#665757', '#493131', '#312520', '#161823'] self.community_detect_algorithm_dict = None def get_network_properties_json(self) -> str: ''' 网络属性组成的json格式数据 :return: ''' directed = "有向图" if self.g.is_directed() else "无向图" data = f'{{' \ f'"IsDirected":\"{directed}\",' \ f'"VertexCount":{self.vertex_count},' \ f'"EdgeCount":{self.edge_count},' \ f'"AvgDegree":{self.avg_degree},' \ f'"MaxDegree":{self.max_degree},' \ f'"Diameter":{self.diameter},' \ f'"AvgPathLen":{self.avg_path_len},' \ f'"ClusteringCoefficient":{self.clustering_coefficient},' \ f'"Density":{self.density},' \ f'"CliqueCount":{self.clique_number},' \ f'}}' # f'"DegreeList":{self.degree_list},' \ # f'"BetweennessList":{self.betweenness},' \ # f'"ClosenessList":{self.closeness}' \ return data def generate_graph_from_dataframe(self, v: pd.DataFrame, e: pd.DataFrame, directed=False) -> None: ''' 从dataframe中初始化网络,并获取网络各类属性值 :param v: 节点表 :param e: 边表 :param directed: 是否是有向图 ''' # 加锁 self.lock.acquire() try: # self.vertex_df = v # 生成网络图对象 self.g = ig.Graph.DataFrame(edges=e, vertices=v, directed=directed) # igraph图对象 self.vg = Network(height='100%', width='100%', directed=directed) # 可视化图对象 self.vg.add_nodes([i for i in range(self.g.vcount())]) self.vg.add_edges(self.g.get_edgelist()) self.vg.show_buttons(filter_=['physics']) # 获取网络属性 self.vertex_count = self.g.vcount() # 节点数 self.edge_count = self.g.ecount() # 边数 self.avg_degree = np.average(self.g.degree()) # 平均度 self.max_degree = self.g.maxdegree() # 最大度 self.degree_list = self.g.degree() # 节点度列表 self.diameter = self.g.diameter() # 网络直径 self.avg_path_len = self.g.average_path_length() # 平均路经长 self.clustering_coefficient = self.g.transitivity_undirected() # 聚集系数 self.density = self.g.density() # 网络密度 self.clique_number = self.g.clique_number() # 团数量 self.g.vs.set_attribute_values(attrname='_度_', values=self.degree_list) # self.betweenness = self.g.betweenness() # 介数列表 self.betweenness = [-1 if np.isnan(v) else v for v in self.g.betweenness()] self.g.vs.set_attribute_values(attrname='_介数_', values=self.betweenness) # self.closeness = self.g.closeness() # 紧密中心性列表 self.closeness = [-1 if np.isnan(v) else v for v in self.g.closeness()] self.g.vs.set_attribute_values(attrname='_紧密中心性_', values=self.closeness) self.page_rank = [-1 if np.isnan(v) else v for v in self.g.pagerank()] self.g.vs.set_attribute_values(attrname='_PageRank_', values=self.page_rank) self.community_detect_algorithm_dict = { 'EdgeBetweenness': self.g.community_edge_betweenness, # 速度慢 'FastGreedy': self.g.community_fastgreedy, # 不能有重复边 'InfoMap': self.g.community_infomap, # 返回VertexClustering 'LabelPropagation': self.g.community_label_propagation, 'LeadingEigenvector': self.g.community_leading_eigenvector, # 速度较慢 # 'LeadingEigenvectorNaive': self.g.community_leading_eigenvector_naive, 'Leiden': self.g.community_leiden, 'MultiLevel': self.g.community_multilevel, 'SpinGlass': self.g.community_spinglass, # 速度慢 'WalkTrap': self.g.community_walktrap } finally: self.lock.release() def export_network(self, path: str, isHtml: int = 1, vertex_size: str = '', vertex_color: str = '', vertex_label: str = '', edge_weight: str = '', layout: str = 'kk' ): ''' 网络可视化 :param path: 保存路径 :param isHtml: 是否生成HTML文件或是svg图片 :param vertex_size: 节点大小 _默认_、_度_、_介数_、_紧密中心性_、其他数值属性 :param vertex_color: 节点颜色 _默认_#789262、_随机_、_度_、_介数_、_紧密中心性_、其他属性 :param vertex_label: 节点标签,默认为节点ID :param edge_weight: 边宽度 _默认_、其他数值属性 :param layout: 静态图布局 :param size: 静态图图像大小 ''' self.lock.acquire() try: if vertex_size != '': if vertex_size == '_默认_': vertex_size = None elif vertex_size == "_度_": vertex_size = [int(30 + d * 40) for d in self.value_map(self.degree_list, 1, 10)] elif vertex_size == "_介数_": vertex_size = [int(30 + d * 40) for d in self.value_map(self.betweenness, 1, 10)] elif vertex_size == "_紧密中心性_": vertex_size = [int(30 + d * 40) for d in self.value_map(self.closeness, 1, 10)] else: if vertex_size in self.g.vs.attribute_names(): try: x = np.array(self.g.vs.get_attribute_values(vertex_size)) vertex_size = [int(30 + d * 40) for d in self.value_map(x, 1, 10)] except Exception as e: vertex_size = None else: vertex_size = None if vertex_color != '': if vertex_color == '_默认_': # vertex_color = [f"#{vertex_color.split('#')[-1]}"] * self.vertex_count vertex_color = None elif vertex_color == "_随机_": colors = random.sample(self.colors, 20) vertex_color = [random.choice(colors) for _ in range(self.vertex_count)] elif vertex_color == "_度_": vertex_color = self.value2color(self.degree_list, 10) elif vertex_color == "_介数_": vertex_color = self.value2color(self.betweenness, 10) elif vertex_color == "_紧密中心性_": vertex_color = self.value2color(self.closeness, 10) else: if vertex_color in self.g.vs.attribute_names(): attr = self.g.vs.get_attribute_values(vertex_color) try: x = np.array(attr) vertex_color = self.value2color(x, 10) except Exception as e: vertex_color = self.category2color(attr) else: vertex_color = None if vertex_label == "_默认_": if 'name' in self.g.vs.attribute_names(): vertex_label = [str(i) for i in self.g.vs.get_attribute_values('name')] else: vertex_label = [str(i) for i in range(self.vertex_count)] else: if vertex_label in self.g.vs.attribute_names(): vertex_label = [str(i) for i in self.g.vs.get_attribute_values(vertex_label)] else: vertex_label = [str(i) for i in range(self.vertex_count)] if edge_weight in self.g.es.attribute_names(): if edge_weight == 'dist': edge_weight = [int(10 + i * 20) for i in 1.0 / np.array(self.value_map(self.g.es.get_attribute_values('dist'), 0.2, 1))] else: edge_weight = None else: edge_weight = None if isHtml == 1: nodes = self.vg.nodes ids = [i for i in range(self.vertex_count)] if vertex_size is not None: for i in ids: nodes[i]['value'] = vertex_size[i] if vertex_color is not None: for i in ids: nodes[i]['color'] = vertex_color[i] if vertex_label is not None: for i in ids: nodes[i]['label'] = vertex_label[i] for i in ids: nodes[i]['title'] = f"<br>ID:{i} 标签:{nodes[i]['label']} 度:{self.degree_list[i]}<br>" \ f"<br>介数:{self.betweenness[i]} 紧密中心度:{self.closeness[i]}<br>" if edge_weight is not None: i = 0 for edge in self.vg.edges: edge['value'] = edge_weight[i] i += 1 # self.vg.force_atlas_2based() self.vg.show_buttons() self.vg.write_html(path) # self.vg.show(path) else: if vertex_size is None: vertex_size = 20 if layout == '': layout = 'circle' ig.plot(self.g, target=path, vertex_size=vertex_size, vertex_color=vertex_color, vertex_label=vertex_label, edge_width=edge_weight, layout=layout) finally: self.lock.release() def community_detect(self, path: str, algorithm: str) -> int: ''' 执行社团发现算法,并生成网络图 :param path: :param algorithm: :return: ''' self.lock.acquire() try: community: [ig.VertexDendrogram, ig.VertexClustering] = self.community_detect_algorithm_dict[algorithm]() # count = community.optimal_count # 社团数量 if type(community) is ig.VertexClustering: vertex_community = community.membership else: vertex_community = community.as_clustering().membership # 节点所在社团 vertex_colors = self.category2color(vertex_community) # print(f'社团数:{max(vertex_community) + 1}') for i in range(self.vertex_count): self.vg.nodes[i]['color'] = vertex_colors[i] self.vg.nodes[i]['title'] = f"<br>ID:{i} 标签:{self.vg.nodes[i]['label']} 度:{self.degree_list[i]}<br>" \ f"<br>介数:{self.betweenness[i]} 紧密中心度:{self.closeness[i]}<br> <br>社团:{vertex_community[i]}<br>" self.vg.write_html(path) self.g.vs.set_attribute_values(attrname='_社团_', values=vertex_community) return max(vertex_community) + 1 finally: self.lock.release() def value_map(self, nums, target_min, target_max): ''' 将数值映射到另一个区间 :param nums: :param target_min: :param target_max: :return: ''' x = nums if type(nums) is not np.ndarray: x = np.array(nums) s_min = np.min(x) s_max = np.max(x) return target_min + (target_max - target_min) / (s_max - s_min) * (x - s_min) def value2color(self, nums, color_num): ''' 连续值映射为颜色 :param nums: 值 :param color_num: 映射的颜色数 :return: ''' x = self.value_map(nums, 1, color_num) colors = random.sample(self.colors, color_num + 1) return [colors[math.ceil(c)] for c in x] def category2color(self, category): ''' 离散值转颜色 :param category: 离散数据 :return: ''' u_c = list(set(category)) random.shuffle(self.colors) color_dict = {} i = 0 color_len = len(self.colors) for c in u_c: color_dict[c] = self.colors[i] i += 1 if i >= color_len: i = color_len - 1 return [color_dict[c] for c in category] def shortest_path_1_to_n(self, start_node_id) -> list: self.g.vs.find() return self.g.get_shortest_paths(v=start_node_id)
def darw_relations_graph(reference_data, ID_COLUMN, notebook=False): """Creates an temporary XML file to visualize relations returns temp filename""" node_data = reference_data.drop_duplicates([ID_COLUMN, "KEY"]).pivot( index=ID_COLUMN, columns="KEY")["VALUE"] columns = node_data.columns if "IdentifiedObject.name" in columns: node_data = node_data[[ "Type", "IdentifiedObject.name" ]].rename(columns={"IdentifiedObject.name": "name"}) elif "Model.profile" in columns: node_data = node_data[["Type", "Model.profile" ]].rename(columns={"Model.profile": "name"}) else: node_data = node_data[["Type"]] node_data["name"] = "" # Visulise with pyvis graph = Network(directed=True, width="100%", height=750, notebook=notebook) # node_name = urlparse(dataframe[dataframe.KEY == "Model.profile"].VALUE.tolist()[0]).path # FullModel does not have IdentifiedObject.name # Add nodes/objects for ID, node in node_data.iterrows(): object_data = reference_data.query("{} == '{}'".format(ID_COLUMN, ID)) node_name = u"{} - {}".format(node["Type"], node["name"]) node_title = object_data[[ ID_COLUMN, "KEY", "VALUE", "INSTANCE_ID" ]].rename(columns={ ID_COLUMN: "ID" }).to_html(index=False) # Add object data table to node hover titel node_level = object_data.level.tolist()[0] graph.add_node(ID, node_name, title=node_title, size=10, level=node_level) # Add connections reference_data_columns = reference_data.columns if "ID_FROM" in reference_data_columns and "ID_TO" in reference_data_columns: connections = list(reference_data[[ "ID_FROM", "ID_TO" ]].dropna().drop_duplicates().to_records(index=False)) graph.add_edges(connections) # Set options graph.set_options(""" var options = { "nodes": { "shape": "dot", "size": 10 }, "edges": { "color": { "inherit": true }, "smooth": false }, "layout": { "hierarchical": { "enabled": true, "direction": "LR", "sortMethod": "directed" } }, "interaction": { "navigationButtons": true }, "physics": { "hierarchicalRepulsion": { "centralGravity": 0, "springLength": 75, "nodeDistance": 145, "damping": 0.2 }, "maxVelocity": 28, "minVelocity": 0.75, "solver": "hierarchicalRepulsion" } }""") # graph.show_buttons() graph.set_options = options if notebook == False: # Change directory to temp os.chdir(tempfile.mkdtemp()) # Create unique filename from_UUID = reference_data[ID_COLUMN].tolist()[0] file_name = r"{}.html".format(from_UUID) # Show graph graph.show(file_name) # Returns file path return os.path.abspath(file_name) return graph
nodes_df['borderWidthSelected'] = list(np.repeat(20.0, nodes_df.shape[0])) ## Visualizing a Network Plotting the network using `pyvis`. Gvis = Network("768px","1600px", notebook=False,heading="Semantic Network") # # Gvis.from_nx(G) edges_in = list(edges_df.to_records(index=False)) #Gvis.add_nodes(list(G.nodes), value=nodes_df['size2'], color=nodes_df['color'], borderWidthSelected = nodes_df['borderWidthSelected']) for i in range(nodes_df.shape[0]): Gvis.add_node(list(G.nodes)[i], value=nodes_df.loc[i,'size2'], group=nodes_df.loc[i,'group'])#, color=nodes_df.loc[i,'color'], borderWidthSelected = nodes_df.loc[i,'borderWidthSelected']) Gvis.add_edges(edges_in) #Gvis.show_buttons() Gvis.set_options(""" var options = { "nodes": { "borderWidth": 0, "color": { "highlight": { "border": "rgba(221,171,197,1)", "background": "rgba(248,178,255,1)" } }, "shadow": { "enabled": true } },
'#e9e7ef', '#f0f0f4', '#e9f1f6', '#f0fcff', '#e3f9fd', '#d6ecf0', '#fffbf0', '#f2ecde', '#fcefe8', '#fff2df', '#f3f9f1', '#e0eee8', '#e0f0e9', '#c0ebd7', '#bbcdc5', '#c2ccd0', '#bacac6', '#808080', '#75878a', '#88ada6', '#6b6882', '#725e82', '#3d3b4f', '#392f41', '#75664d', '#5d513c', '#665757', '#493131', '#312520', '#161823' ] random.shuffle(colors) print(colors[:5]) vg = Network(height='100%', width='100%', heading='交通网络图', directed=True) vg.add_nodes( [i for i in range(g.vcount())], value=[20 + d * 15 for d in g.degree()], # 节点大小 label=g.vs.get_attribute_values('Label'), # 节点标签,显示在点下方,缩小自动隐藏 color=[random.choice(colors[:20]) for i in range(g.vcount())]) vg.add_edges(g.get_edgelist()) # for edge in vg.edges: # # edge['value'] = random.randint(1,20) # edge['color'] = 'red' # # vg.set_edge_smooth(smooth_type='dynamic') for node in vg.nodes: # node['color'] = 'red' # node["title"] = "Neighbors:<br>" + "<br>".join(neighbor_map[node["id"]]) # 节点标题,鼠标移动到点上面时显示 node["title"] = f"<br>ID:{node['id']} Label:{node['label']}<br>" # vg.set_template() # vg.force_atlas_2based() vg.show_buttons(filter_=['physics']) vg.show('a.html')
def network(request, n, f): fileType = f inputFile = n htmlFile = "./NetworkViewer/networks/" + n.split(".")[0] + ".html" # The network parameters to be displayed are initiated. All parameters can not be calculated for all types of networks diameter = 0 clusteringCoeff = 0 cliques = 0 degree = 0 connectedComponents = 0 stronglyConnectedomponents = 0 # Different file types needs to be handeled in different ways ngx = None if fileType == 'geneSpider': # Gene spider matrix is read as a matrix that is then transposed, in order to get the directions right networkDf = pd.read_csv(os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'media/' + inputFile), sep=',', header=None) networkDfTransposed = networkDf.T nxg = nx.from_numpy_matrix(np.array(networkDfTransposed), create_using=nx.MultiDiGraph()) elif fileType == 'adjacencyList': # Adjacency lists/Edge lists are red as undirected pandas edgelists networkDf = pd.read_csv(os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'media/' + inputFile), sep='\s+', header=None) nxg = nx.from_pandas_edgelist(networkDf, source=0, target=1) elif fileType == 'directedAdjacencyList': # Directed edge lists need to be read as directed pandas edgelists networkDf = pd.read_csv(os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'media/' + inputFile), sep='\s+', header=None) nxg = nx.from_pandas_edgelist(networkDf, source=0, target=1, create_using=nx.MultiDiGraph()) elif fileType == 'adjacencyMatrix': # Adjacency matrix need to be read as an undirected matrix networkDf = pd.read_csv(os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'media/' + inputFile), sep=',', header=None) nxg = nx.from_numpy_matrix(np.array(networkDf)) elif fileType == 'directedAdjacencyMatrix': # Directed Adjacency matrix need to be read as a directed matrix networkDf = pd.read_csv(os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'media/' + inputFile), sep=',', header=None) nxg = nx.from_numpy_matrix(np.array(networkDf), create_using=nx.MultiDiGraph()) elif fileType == 'funCoup': # FunCoup-network-files contains several columns defining the evidence types and scores. Here, they are red as edge lists, only taking the genes and their edges into account networkDf = pd.read_csv(os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'media/' + inputFile), sep='\t') networkDfGenes = networkDf[['2:Gene1', '3:Gene2']] nxg = nx.from_pandas_edgelist(networkDfGenes, source='2:Gene1', target='3:Gene2') # The networkx-networks are drawn as png-images, since the pyvis can not handle other formats than html. pos = nx.spring_layout(nxg) nx.draw(nxg, pos, with_labels=True) # nx.draw_networkx_edge_labels(nxg, pos, with_labels = True) plt.savefig("./NetworkViewer/templates/NetworkViewer/networks/" + inputFile.split(".")[0] + ".png", format="PNG") plt.clf() # Initiating pyvis interactive network with customized graphics g = Network() g.barnes_hut(gravity=-2000, central_gravity=0.02, spring_length=1, spring_strength=0.000001, damping=0.09, overlap=0) g.toggle_physics(True) # Calculating network prooperties from the networkx graphs if nx.is_directed(nxg): g.directed = True stronglyConnectedomponents = nx.number_strongly_connected_components( nxg) else: connectedComponents = nx.number_connected_components(nxg) if connectedComponents == 1: diameter = nx.diameter(nxg, e=None) clusteringCoeffs = nx.clustering(nxg) clusteringCoeff = np.mean(list(clusteringCoeffs.values())) allCliques = nx.find_cliques(nxg) cliques = len(list(allCliques)) degrees = nxg.degree() degreesOnly = [] for node, degree in degrees: degreesOnly.append(degree) degree = np.mean(degreesOnly) maxDegree = np.max(degreesOnly) # Filling the pyvis graph with nodes and edges from the networkx graph. allNodes = list(nxg.nodes) allSizes = [] # The nodes gets sizes according to their degree for d in degreesOnly: allSizes.append(40 * (d / maxDegree)) g.add_nodes(allNodes, size=allSizes) # The edges gets width according to their weights allEdges = nxg.edges(data=True) edges = [] for a, b, w in allEdges: edges.append((a, b, w.get('weight'))) g.add_edges(edges) g.height = "100%" g.width = "100%" # The pyvis graph is saved as an html file, that is embedded in the network viewer-vindow g.save_graph("./NetworkViewer/templates/NetworkViewer/networks/" + inputFile.split(".")[0] + ".html") # Exporting network properties to the html-view context = { "diameter": ("%.2f" % diameter), "clustering": ("%.2f" % clusteringCoeff), "cliques": ("%.2f" % cliques), "degree": ("%.2f" % degree), "connectedComponents": connectedComponents, "stronglyConnectedomponents": stronglyConnectedomponents, "inputFile": inputFile, "htmlFile": htmlFile } return render(request, 'NetworkViewer/viewNetwork.html', context)
def plotNetwork( self, source: str, target: str, filename: str = "net.html", size: Tuple[int, int] = (500, 500), ): try: paths = nx.all_shortest_paths(self, source, target) except nx.NetworkXNoPath as e: print("No path") finally: paths = list(paths) nodes = list(set(chain.from_iterable(paths))) edges = [(p[i], p[i + 1]) for p in paths for i in range(0, len(p) - 1)] g = Network(height=size[0], width=size[1], directed=True) g.add_nodes( nodes, color=[ "red" if n == source else "green" if n == target else "blue" for n in nodes ], ) g.add_edges(edges) g.set_options(""" { "nodes": { "font": { "size": 9 }, "scaling": { "max": 36 }, "shadow": { "enabled": true } }, "edges": { "arrows": { "to": { "enabled": true, "scaleFactor": 1.4 } }, "smooth": false }, "layout": { "hierarchical": { "enabled": true, "sortMethod": "directed" } }, "interaction": { "keyboard": { "enabled": true } }, "physics": { "hierarchicalRepulsion": { "centralGravity": 0, "nodeDistance": 225 }, "minVelocity": 0.75, "solver": "hierarchicalRepulsion" } }""") return g
selected_edges = negative_edges[n] #Get list of nodes #Keep only the kinases names (i.e. remove the z-scores) from the list of edges nodes_bf = [(a, b) for a, b, c in selected_edges] #Flatten list of edges tuples to list of nodes nodes = list(itertools.chain(*nodes_bf)) #Remove duplicates from the list nodes_list = list(dict.fromkeys(nodes)) #Add nodes & edges to graph networkgraph.add_nodes(nodes_list, value=[10] * len(nodes_list), title=nodes_list, label=nodes_list) networkgraph.add_edges(selected_edges) #Show to which kinases each kinase is connected #Show to which kinases each kinase is connected kinases_map = networkgraph.get_adj_list() network_map = networkgraph.get_edges() for key, value in kinases_map.items(): kinases_map[key] = ([ functools.reduce(operator.add, ((x, str([(y["width"]) for y in network_map if x in y["from"] and key in y["to"] or x in y["to"] and key in y["from"]])))) for x in value ])