def create_graph(messages: list, people: list, reacts: dict, freq: dict, config: dict): directed = config['graph']['directed'] if directed: reacts_g = nx.DiGraph() else: reacts_g = nx.Graph() reacts_g.add_nodes_from(people) threshold = config['graph']['pair_threshold'] for pair in itertools.combinations(people, 2): make_edge(pair[0], pair[1], reacts, directed, threshold, reacts_g) if directed: make_edge(pair[1], pair[0], reacts, directed, threshold, reacts_g) vis = Network(bgcolor='#222222', font_color="white", height="100%", width="100%", directed=directed) vis.from_nx(reacts_g) neighs = vis.get_adj_list() for edge in vis.edges: edge["value"] = get_pair_reacts(edge["from"], edge["to"], reacts, directed) for node in vis.nodes: neighbors = vis.neighbors(node['id']) n_metadata = [] for neighbor in neighbors: pair = (node['id'], neighbor) matching_edge = [ edge for edge in vis.edges if (edge["from"] in pair and edge["to"] in pair) ][0] n_metadata.append(f'{neighbor} ({matching_edge["value"]})') node['title'] = " Reacts:<br>" + "<br>".join(list(n_metadata)) if config['graph']['adjust_node_size']: node['size'] = config['graph']['base_size'] * log10( (freq[node['id']]) / 10) else: node['size'] = config['graph']['base_size'] return (vis)
def make_graph(subjects: list): # read data df = pd.DataFrame() for subject in subjects: courses = pd.read_json(f"courses/{subject}.json") df = pd.concat([df, courses]) edge_list = make_edge_list(df) node_list, title_list = make_node_list(df) # make graph g = Network(directed=True, height="650px", width="100%", bgcolor="#222222", font_color="white") g.barnes_hut() # spring physics on the edges g.inherit_edge_colors(False) g.add_nodes(node_list, title=title_list) for edge in edge_list: g.add_edge(edge[0], edge[1], color="#94c4fc") # add neighbor data to node hover data for node in g.nodes: prereq = df[df["label"] == node["label"]]["prereq"] prereq = [] if prereq.empty else prereq.item() next_courses = g.neighbors(node["label"]) node["title"] += "<br>Prerequisites:<br>" \ + "<br>".join(prereq) \ + "<br>Next courses:<br>" \ + "<br>".join(next_courses) node["value"] = len(next_courses) + len(prereq) # highlight the node if it serves as a prerequisites for more than 5 course node["font"]["size"] = node["value"] * 5 if node["value"] >= 8: node["color"] = "red" return g
jobtype = data['Type'] color = {'PhD' : 'blueviolet' , 'postdoc' : 'magenta' , 'link' : 'turquoise'} all_people = set(list(people)+list(supervisors)) #node_size = Counter(supervisors) for person in all_people: net.add_node(person, title=person,size=5) #,shape='ellipse') for person, supervisor, job in zip(people,supervisors, jobtype): if job != 'link': net.add_edge(supervisor, person, arrow=True,color=color[job]) neighbor_map = net.get_adj_list() # add neighbor data to node hover data for node in net.nodes: supervised = [x for x in net.neighbors(node["id"])] num = len(supervised) if num > 0: node["title"] += " Students:<br>" + "<br>".join(neighbor_map[node["id"]]) node["value"] = num for person, supervisor, job in zip(people,supervisors, jobtype): if job == 'link': net.add_edge(supervisor, person, arrow=False,color=color[job],arrowStrikethrough=True) net.add_edge(person, supervisor, arrow=False,color=color[job],arrowStrikethrough=True) net.show("index.html")
def map_kcs(kc_list, kc_matrix, node_color="#8B008B", edge_color="#03DAC6", node_shape="ellipse", alg="barnes", edge_smooth=None, buttons=False, treshold=0.5): """ Use this on a test that has less than 26 KCs, or else there will be problems with relations between the edges due to name conflict :param threshold: float, :param kc_list: np.array, list of all kcs :param edge_smooth: string, How the user wants the edges to be, default is continuous :param buttons: bool, buttons to edit graph with :param node_shape: string, shape of node :param edge_color: string, shape of edge :param node_color: string, hexvalue of color for node :param kc_matrix: 2D np array, mapping of kcs :param alg: string, algorithm for graph :return: renders a graph in which you can see the relations between nodes and their edges """ g = Network(height="1500px", width="75%", bgcolor="#222222", font_color="white", directed=True) # if buttons: g.width = "75%" # nodes, layout, interaction, selection, renderer, physics g.show_buttons(filter_=["edges", "physics"]) # Create the nodes for kc_node in kc_list: g.add_node(n_id=kc_node, label=kc_node, color=node_color, shape=node_shape) # Creates edges between nodes if they're connected (if the value is true in the database) n = len(kc_matrix) for r in range(n): for c in range(n): if r != c: # Directly logically connnected edge if 0.9 <= kc_matrix[r, c] <= 1.0: g.add_edge(kc_list[r], kc_list[c], color="#42cc14") # green # Necessary edge elif 0.7 <= kc_matrix[r, c] < 0.9: g.add_edge(kc_list[r], kc_list[c], color="#ff8c00") # orange # Important edge elif 0.5 <= kc_matrix[r, c] < 0.7: g.add_edge(kc_list[r], kc_list[c], color="#ffd900") # orange elif kc_matrix[r, c] == -1.0: g.add_edge(kc_list[r], kc_list[c], color="#56f0eb") map_algs(g, alg) if edge_smooth is not None: map_smoothenes(graph=g, smooth=edge_smooth) node_list = g.get_nodes() for node in g.nodes: neighbors = g.neighbors(node_list[node_list.index(node['id'])]) if neighbors is None: title = "Endpoint KC" else: title = "What to learn next:<br>" for neighbor in neighbors: title += f"{neighbor}<br>" node["title"] = title # g.save_graph("../../kc.html") g.show("kc_map.html")