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 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
random_weight = random.randint(1, 5) G.add_edge(random_node_from, random_node_to, weight=random_weight) number_of_nodes = st.slider("Number of nodes?", 0, 200, 10) number_of_edges = st.slider("Number of edges?", 1, 400, 20) G = nx.DiGraph() # initilize the graph bidirectional for x in range(number_of_nodes): generate_random_node(G) for x in range(number_of_edges): generate_random_edge(G) render_demo = st.button("Render Sample Node Network") if (render_demo): nt = Network('500px', '500px') nt.from_nx(G) nt.inherit_edge_colors(False) for ix in nt.get_edges(): ix["width"] = ix["weight"] nt.write_html('demo.html') print(nt) # display(HTML('demo.html')) HtmlFile = open("demo.html", 'r', encoding='utf-8') source_code = HtmlFile.read() components.html(source_code, height=700)
def create_and_return_flow_diagram(request_dict, path_to_reactions=path_to_reactions, path_to_template=path_to_template, csv_results_path=csv_results_path_default): global userSelectedMinMax global minAndMaxOfSelectedTimeFrame global previous_vals global csv_results_path_default logging.info("using csv_results_path: " + csv_results_path) csv_results_path_default = csv_results_path if (('maxMolval' in request_dict and 'minMolval' in request_dict) and (request_dict['maxMolval'] != '' and request_dict['minMolval'] != '') and (request_dict['maxMolval'] != 'NULL' and request_dict['minMolval'] != 'NULL')): userSelectedMinMax = [ float(request_dict["minMolval"]), float(request_dict["maxMolval"])] logging.info("new user selected min and max: " + str(userSelectedMinMax)) if 'startStep' not in request_dict: request_dict.update({'startStep': 1}) if 'maxArrowWidth' not in request_dict: request_dict.update({'maxArrowWidth': 10}) minAndMaxOfSelectedTimeFrame = [999999999999, -1] # load csv file csv = pd.read_csv(csv_results_path) start_step = int(request_dict['startStep']) end_step = int(request_dict['endStep']) # scale with correct scaling function scale_type = request_dict['arrowScalingType'] max_width = request_dict['maxArrowWidth'] previousMin = float(request_dict["currentMinValOfGraph"]) previousMax = float(request_dict["currentMaxValOfGraph"]) previous_vals = [previousMin, previousMax] isPhysicsEnabled = request_dict['isPhysicsEnabled'] if isPhysicsEnabled == 'true': max_width = 2 # change for max width with optimized performance # load species json and reactions json with open(path_to_reactions, 'r') as f: reactions_data = json.load(f) # completely new method of creating nodes and filtering elements selected_species = request_dict['includedSpecies'].split(',') blockedSpecies = request_dict['blockedSpecies'].split(',') (network_content, raw_yields, edgeColors, quantities, minVal, maxVal, raw_yield_values, species_colors, species_sizes, total_quantites, reaction_names_on_hover) = new_find_reactions_and_species( selected_species, reactions_data, blockedSpecies, csv, start_step, end_step, max_width, scale_type, csv_results_path) # add edges and nodes # force network to be 100% width and height before it's sent to page net = Network(height='100%', width='100%', directed=True) # make it so we can manually change arrow colors net.inherit_edge_colors(False) shouldMakeSmallNode = False if isPhysicsEnabled == "true": net.toggle_physics(False) net.force_atlas_2based() else: net.force_atlas_2based(gravity=-200, overlap=1) reac_nodes = network_content['reaction_nodes'] hover_names = reaction_names_on_hover names = [getReactName(hover_names, x) for x in reac_nodes] colors = [species_colors[x] for x in network_content['species_nodes']] if shouldMakeSmallNode: net.add_nodes(names, color=["#FF7F7F" for x in reac_nodes], size=[ 10 for x in list(reac_nodes)], title=names) net.add_nodes(network_content['species_nodes'], color=colors, size=[ 10 for x in list(network_content['species_nodes'])]) else: net.add_nodes(names, color=[ "#FF7F7F" for x in reac_nodes], title=names) net.add_nodes(network_content['species_nodes'], color=colors, size=[species_sizes[x] for x in list( network_content['species_nodes'])]) net.set_edge_smooth('dynamic') # add edges individually so we can modify contents i = 0 values = edgeColors for edge in network_content['edges']: unbeu1 = unbeautifyReaction(edge[0]) unbeu2 = unbeautifyReaction(edge[1]) val = unbeu1+"__TO__"+unbeu2 flux = str(raw_yields[unbeu1+"__TO__"+unbeu2]) colorVal = "" try: colorVal = values[val] except KeyError: colorVal = values[val.replace('->', '-')] if colorVal == "#e0e0e0": # don't allow blocked edge to show value on hover if "→" in edge[0]: be1 = beautifyReaction(reaction_names_on_hover[unbeu1]) net.add_edge(be1, edge[1], color=colorVal, width=edge[2]) elif "→" in edge[1]: try: be2 = beautifyReaction(reaction_names_on_hover[unbeu2]) net.add_edge(edge[0], be2, color=colorVal, width=edge[2]) except KeyError: be2 = beautifyReaction(unbeu2) net.add_edge(edge[0], be2, color=colorVal, width=edge[2]) else: net.add_edge(edge[0], edge[1], color=colorVal, width=edge[2]) else: # hover over arrow to show value for arrows within range # check if value is reaction by looking for arrow if "→" in edge[0]: be1 = beautifyReaction(reaction_names_on_hover[unbeu1]) net.add_edge(be1, edge[1], color=colorVal, width=float( edge[2]), title="flux: "+flux) elif "→" in edge[1]: try: be2 = beautifyReaction(reaction_names_on_hover[unbeu2]) net.add_edge(edge[0], be2, color=colorVal, width=float( edge[2]), title="flux: "+flux) except KeyError: be2 = beautifyReaction(unbeu2) net.add_edge(edge[0], be2, color=colorVal, width=float( edge[2]), title="flux: "+flux) else: net.add_edge(edge[0], edge[1], color=colorVal, width=float(edge[2]), title="flux: "+flux) i = i+1 net.show(path_to_template) if minAndMaxOfSelectedTimeFrame[0] == minAndMaxOfSelectedTimeFrame[1]: minAndMaxOfSelectedTimeFrame = [0, maxVal] with open(path_to_template, 'r+') as f: ############################################# # here we are going to replace the contents # ############################################# a = """<script> network.on("stabilizationIterationsDone", function () { network.setOptions( { physics: false } ); }); </script>""" logging.debug("((DEBUG)) [min,max] of selected time frame: " + str(minAndMaxOfSelectedTimeFrame)) logging.debug("((DEBUG)) [min,max] given by user: "******"""<script> parent.document.getElementById("flow-start-range2").value = "NULL"; parent.document.getElementById("flow-end-range2").value = "NULL"; console.log("inputting NULL");""" else: a = '<script>\ parent.document.getElementById("flow-start-range2").value = \ "'+formattedMinOfSelected+'";' a += 'parent.document.getElementById("flow-end-range2").value = \ "'+str( formattedMaxOfSelected)+'";' a += """ currentMinValOfGraph = """+formattedPrevMin+"""; currentMaxValOfGraph = """+formattedPrevMax+"""; """ if (str(formattedPrevMin) != str(formattedMinOfSelected) or str(formattedPrevMax) != str(formattedMaxOfSelected) or previousMax == 1): logging.debug("previousMin:" + str(formattedPrevMin) + "does not equal " + str(formattedMinOfSelected)) logging.debug("previousMax: " + str(formattedPrevMax) + " does not equal " + str(formattedMaxOfSelected)) logging.debug("previousMin: " + str(previousMin) + " equals 0") logging.debug("previousMax: " + str(previousMax) + " equals 1") a += 'parent.document.getElementById("flow-start-range2").value =\ "'+str(formattedMinOfSelected)+'";\ parent.document.getElementById("flow-end-range2").value =\ "'+str(formattedMaxOfSelected)+'";' a += ('parent.reloadSlider("'+str(formattedMinOfSelected)+'","' + str(formattedMaxOfSelected)+'", "'+str( formattedMinOfSelected)+'", "' + str(formattedMaxOfSelected)+'", '+str(get_step_length(csv_results_path))+');</script>') else: logging.debug("looks like min and max are the same") isNotDefaultMin = int(userSelectedMinMax[0]) != 999999999999 isNotDefaultmax = int(userSelectedMinMax[1]) != -1 block1 = 'parent.document.getElementById("flow-start-range2")' rangeId = block1+'.value = ' if isNotDefaultmax or isNotDefaultMin: a += (rangeId+str( formattedUserMin)+'"; \ '+rangeId+'"'+formattedUserMax+'";') block1 = 'parent.reloadSlider("' + formattedUserMin + '", "' fmos = str(formattedMinOfSelected) block2 = formattedUserMax + '", "' + fmos block3 = '", "' + formattedMaxOfSelected + '", '+str(get_step_length(csv_results_path))+');\ </script>' a += block1 + block2 + block3 else: fmos = formattedMinOfSelected block1 = 'parent.reloadSlider("' + fmos + '", "' block2 = formattedMaxOfSelected + '", "' + str(fmos) a += block1 + '", "' + formattedMaxOfSelected + '", '+str(get_step_length(csv_results_path))+');</script>' if isPhysicsEnabled == 'true': # add options to reduce text size a += \ """<script> var container = document.getElementById("mynetwork"); var options = {physics: false, nodes: { shape: "dot", size: 10, font: {size: 5} } }; var network = new vis.Network(container, data, options); </script>""" lines = f.readlines() for i, line in enumerate(lines): # find a pattern so that we can add next to that line if line.startswith('</script>'): lines[i] = lines[i]+a f.truncate() f.seek(0) # rewrite into the file for line in lines: f.write(line) f.close() # read from file and return the contents with open(path_to_template, 'r') as f: return f.read()