gmedin commited on
Commit
209e6b2
·
verified ·
1 Parent(s): 27e4160

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -0
app.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import networkx as nx
3
+ from pyvis.network import Network
4
+ import pickle
5
+ import math
6
+
7
+ # Load the graph from a pickle file
8
+ @st.cache_resource
9
+ def load_graph():
10
+ with open('drumeo_multi_student_graph_labels.pkl', 'rb') as f:
11
+ return pickle.load(f)
12
+
13
+ def dynamic_visualize_graph(graph, start_node, layers=3, top_k=5):
14
+ net = Network(notebook=False, width="100%", height="600px", directed=True)
15
+ net.set_options("""
16
+ var options = {
17
+ "physics": {
18
+ "barnesHut": {
19
+ "gravitationalConstant": -20000,
20
+ "centralGravity": 0.6
21
+ }
22
+ }
23
+ }
24
+ """)
25
+
26
+
27
+
28
+ visited_nodes = set()
29
+ current_nodes = [int(start_node)] # Convert start_node to int
30
+ # Add the starting node, color it red, and include a tooltip
31
+ start_title = graph.nodes[int(start_node)].get('title', 'No title available') # Get the title attribute
32
+ if isinstance(start_title, float) and math.isnan(start_title): # Check if the title is NaN
33
+ start_title = "No title available"
34
+ net.add_node(int(start_node), label=str(start_node), color="red", title=start_title)
35
+ visited_nodes.add(int(start_node))
36
+
37
+ for layer in range(layers):
38
+ next_nodes = []
39
+ for node in current_nodes:
40
+ neighbors = sorted(
41
+ [(int(neighbor), data['weight']) for neighbor, data in graph[node].items()],
42
+ key=lambda x: x[1],
43
+ reverse=True
44
+ )[:top_k] # Get top_k neighbors for this node
45
+
46
+ for neighbor, weight in neighbors:
47
+ if neighbor not in visited_nodes:
48
+ neighbor_title = graph.nodes[neighbor].get('title', 'No title available')
49
+ if isinstance(neighbor_title, float) and math.isnan(neighbor_title): # Check if the title is NaN
50
+ neighbor_title = "No title available"
51
+ if not isinstance(neighbor_title, str):
52
+ neighbor_title = str(neighbor_title) # Ensure it's converted to a string
53
+ net.add_node(neighbor, label=str(neighbor), title=neighbor_title)
54
+
55
+ net.add_edge(node, neighbor, label=f"w:{weight}") # Add the edge regardless of visited status
56
+ visited_nodes.add(neighbor)
57
+ next_nodes.append(neighbor) # Always add to next_nodes for further expansion
58
+
59
+ current_nodes = next_nodes # Move to the next layer
60
+
61
+ # Generate the final visualization
62
+ html_content = net.generate_html()
63
+ st.components.v1.html(html_content, height=600, scrolling=False)
64
+
65
+
66
+ # Streamlit interface
67
+ st.title("Interactive Graph Expansion with Tooltips")
68
+
69
+ # Load the graph
70
+ G = load_graph()
71
+
72
+ import random
73
+ # Randomly sample a starting node
74
+ # Initialize session state for the starting node
75
+ if "start_node" not in st.session_state:
76
+ st.session_state.start_node = random.choice(list(G.nodes)) # Randomly select a node once
77
+
78
+ # Input: Starting node
79
+ start_node = st.number_input(
80
+ "Enter the starting node ID:",
81
+ value=st.session_state.start_node,
82
+ step=1
83
+ )
84
+ layers = st.slider("Depth to explore:", 1, 6, value=3)
85
+ top_k = st.slider("Branching factor (per node):", 1, 6, value=3)
86
+
87
+ # Trigger the visualization
88
+ if st.button("Expand Graph"):
89
+ if start_node in G:
90
+ dynamic_visualize_graph(G, start_node, layers=layers, top_k=top_k)
91
+ else:
92
+ st.error("The starting node is not in the graph!")