Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -9,12 +9,15 @@ sidebar_option = st.sidebar.radio("Select an option",
|
|
9 |
"Basic: Read and write graphs", "Basic: Simple graph",
|
10 |
"Basic: Simple graph Directed", "Drawing: Custom Node Position"])
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
# Function to display properties and graph for Basic: Properties
|
13 |
def display_graph_properties(G):
|
14 |
-
# Initialize a list for path lengths
|
15 |
pathlengths = []
|
16 |
-
|
17 |
-
# Display the source-target shortest path lengths
|
18 |
st.write("### Source vertex {target:length, }")
|
19 |
for v in G.nodes():
|
20 |
spl = dict(nx.single_source_shortest_path_length(G, v))
|
@@ -22,23 +25,16 @@ def display_graph_properties(G):
|
|
22 |
for p in spl:
|
23 |
pathlengths.append(spl[p])
|
24 |
|
25 |
-
# Calculate and display the average shortest path length
|
26 |
avg_path_length = sum(pathlengths) / len(pathlengths)
|
27 |
st.write(f"### Average shortest path length: {avg_path_length}")
|
28 |
|
29 |
-
# Calculate and display the distribution of path lengths
|
30 |
dist = {}
|
31 |
for p in pathlengths:
|
32 |
-
|
33 |
-
dist[p] += 1
|
34 |
-
else:
|
35 |
-
dist[p] = 1
|
36 |
-
|
37 |
st.write("### Length #paths")
|
38 |
for d in sorted(dist.keys()):
|
39 |
st.write(f"Length {d}: {dist[d]} paths")
|
40 |
|
41 |
-
# Display the graph metrics with a "Properties" heading
|
42 |
st.write("### Properties")
|
43 |
st.write(f"Radius: {nx.radius(G)}")
|
44 |
st.write(f"Diameter: {nx.diameter(G)}")
|
@@ -50,13 +46,10 @@ def display_graph_properties(G):
|
|
50 |
# Visualize the graph
|
51 |
st.write("### Graph Visualization")
|
52 |
pos = nx.spring_layout(G, seed=3068) # Seed layout for reproducibility
|
53 |
-
|
54 |
-
nx.draw(G, pos=pos, with_labels=True, node_color='lightblue', node_size=500, font_size=10, font_weight='bold')
|
55 |
-
st.pyplot(plt)
|
56 |
|
57 |
# Function to display graph for Basic: Read and write graphs
|
58 |
def display_read_write_graph(G):
|
59 |
-
# Print the adjacency list of the graph
|
60 |
st.write("### Adjacency List:")
|
61 |
for line in nx.generate_adjlist(G):
|
62 |
st.write(line)
|
@@ -74,9 +67,7 @@ def display_read_write_graph(G):
|
|
74 |
# Visualize the graph
|
75 |
st.write("### Graph Visualization:")
|
76 |
pos = nx.spring_layout(H, seed=200) # Seed for reproducibility
|
77 |
-
|
78 |
-
nx.draw(H, pos, with_labels=True, node_color='lightblue', node_size=500, font_size=10, font_weight='bold')
|
79 |
-
st.pyplot(plt)
|
80 |
|
81 |
# Function to display Simple Graphs for Basic: Simple graph
|
82 |
def display_simple_graph(G, pos=None):
|
@@ -131,25 +122,21 @@ def display_custom_node_position():
|
|
131 |
pos[center_node] = np.array([0, 0]) # Manually specify node position
|
132 |
|
133 |
# Draw the graph
|
134 |
-
|
135 |
-
st.pyplot(plt)
|
136 |
|
137 |
# Display Basic: Properties if selected
|
138 |
if sidebar_option == "Basic: Properties":
|
139 |
st.title("Basic: Properties")
|
140 |
option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
|
141 |
|
142 |
-
# Default example: 5x5 grid graph
|
143 |
if option == "Default Example":
|
144 |
G = nx.lollipop_graph(4, 6)
|
145 |
display_graph_properties(G)
|
146 |
|
147 |
-
# Create your own graph
|
148 |
elif option == "Create your own":
|
149 |
num_nodes = st.number_input("Number of nodes:", min_value=2, max_value=50, value=5)
|
150 |
num_edges = st.number_input("Number of edges per group (for lollipop graph):", min_value=1, max_value=10, value=3)
|
151 |
|
152 |
-
# Button to generate the graph
|
153 |
if st.button("Generate"):
|
154 |
if num_nodes >= 2 and num_edges >= 1:
|
155 |
G_custom = nx.lollipop_graph(num_nodes, num_edges)
|
@@ -160,17 +147,14 @@ elif sidebar_option == "Basic: Read and write graphs":
|
|
160 |
st.title("Basic: Read and write graphs")
|
161 |
option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
|
162 |
|
163 |
-
# Default example: 5x5 grid graph
|
164 |
if option == "Default Example":
|
165 |
-
G = nx.grid_2d_graph(5, 5)
|
166 |
display_read_write_graph(G)
|
167 |
|
168 |
-
# Create your own graph
|
169 |
elif option == "Create your own":
|
170 |
rows = st.number_input("Number of rows:", min_value=2, max_value=20, value=5)
|
171 |
cols = st.number_input("Number of columns:", min_value=2, max_value=20, value=5)
|
172 |
|
173 |
-
# Button to generate the graph
|
174 |
if st.button("Generate"):
|
175 |
if rows >= 2 and cols >= 2:
|
176 |
G_custom = nx.grid_2d_graph(rows, cols)
|
@@ -181,7 +165,6 @@ elif sidebar_option == "Basic: Simple graph":
|
|
181 |
st.title("Basic: Simple graph")
|
182 |
option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
|
183 |
|
184 |
-
# Default example: simple undirected graph
|
185 |
if option == "Default Example":
|
186 |
G = nx.Graph()
|
187 |
G.add_edge(1, 2)
|
@@ -191,32 +174,21 @@ elif sidebar_option == "Basic: Simple graph":
|
|
191 |
G.add_edge(3, 4)
|
192 |
G.add_edge(4, 5)
|
193 |
|
194 |
-
# explicitly set positions for visualization
|
195 |
pos = {1: (0, 0), 2: (-1, 0.3), 3: (2, 0.17), 4: (4, 0.255), 5: (5, 0.03)}
|
196 |
display_simple_graph(G, pos)
|
197 |
|
198 |
-
# Create your own graph
|
199 |
elif option == "Create your own":
|
200 |
-
# num_nodes = st.number_input("Number of nodes:", min_value=2, max_value=20, value=5)
|
201 |
edges = []
|
202 |
-
|
203 |
-
# Let the user define edges
|
204 |
-
st.write("Enter the edges (as pairs of nodes) separated by commas. For example, 1,2 or 3,4.")
|
205 |
edge_input = st.text_area("Edges:", value="1,2\n1,3\n2,3")
|
206 |
-
|
207 |
-
# Parse the edges
|
208 |
if edge_input:
|
209 |
edge_list = edge_input.split("\n")
|
210 |
for edge in edge_list:
|
211 |
u, v = map(int, edge.split(","))
|
212 |
edges.append((u, v))
|
213 |
|
214 |
-
# Button to generate the graph
|
215 |
if st.button("Generate"):
|
216 |
G_custom = nx.Graph()
|
217 |
G_custom.add_edges_from(edges)
|
218 |
-
|
219 |
-
# Set a basic layout (spring layout as default)
|
220 |
pos = nx.spring_layout(G_custom, seed=42)
|
221 |
display_simple_graph(G_custom, pos)
|
222 |
|
@@ -225,45 +197,31 @@ elif sidebar_option == "Basic: Simple graph Directed":
|
|
225 |
st.title("Basic: Simple graph Directed")
|
226 |
option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
|
227 |
|
228 |
-
# Default example: simple directed graph
|
229 |
if option == "Default Example":
|
230 |
G = nx.DiGraph([(0, 3), (1, 3), (2, 4), (3, 5), (3, 6), (4, 6), (5, 6)])
|
231 |
|
232 |
-
# Group nodes by column
|
233 |
left_nodes = [0, 1, 2]
|
234 |
middle_nodes = [3, 4]
|
235 |
right_nodes = [5, 6]
|
236 |
|
237 |
-
# Set the position according to column (x-coord)
|
238 |
pos = {n: (0, i) for i, n in enumerate(left_nodes)}
|
239 |
pos.update({n: (1, i + 0.5) for i, n in enumerate(middle_nodes)})
|
240 |
pos.update({n: (2, i + 0.5) for i, n in enumerate(right_nodes)})
|
241 |
|
242 |
-
# Draw the directed graph
|
243 |
display_simple_directed_graph(G, pos)
|
244 |
|
245 |
-
# Create your own directed graph
|
246 |
elif option == "Create your own":
|
247 |
-
# num_nodes = st.number_input("Number of nodes:", min_value=2, max_value=20, value=5)
|
248 |
edges = []
|
249 |
-
|
250 |
-
# Let the user define directed edges
|
251 |
-
st.write("Enter the directed edges (as pairs of nodes) separated by commas. For example, 1,2 or 3,4.")
|
252 |
edge_input = st.text_area("Edges:", value="1,2\n1,3\n2,3")
|
253 |
-
|
254 |
-
# Parse the edges
|
255 |
if edge_input:
|
256 |
edge_list = edge_input.split("\n")
|
257 |
for edge in edge_list:
|
258 |
u, v = map(int, edge.split(","))
|
259 |
edges.append((u, v))
|
260 |
|
261 |
-
# Button to generate the directed graph
|
262 |
if st.button("Generate"):
|
263 |
G_custom = nx.DiGraph()
|
264 |
G_custom.add_edges_from(edges)
|
265 |
-
|
266 |
-
# Set a basic layout (spring layout as default)
|
267 |
pos = nx.spring_layout(G_custom, seed=42)
|
268 |
display_simple_directed_graph(G_custom, pos)
|
269 |
|
|
|
9 |
"Basic: Read and write graphs", "Basic: Simple graph",
|
10 |
"Basic: Simple graph Directed", "Drawing: Custom Node Position"])
|
11 |
|
12 |
+
# Helper function to draw and display graph
|
13 |
+
def draw_graph(G, pos=None, title="Graph Visualization"):
|
14 |
+
plt.figure(figsize=(8, 6))
|
15 |
+
nx.draw(G, pos=pos, with_labels=True, node_color='lightblue', node_size=500, font_size=10, font_weight='bold')
|
16 |
+
st.pyplot(plt)
|
17 |
+
|
18 |
# Function to display properties and graph for Basic: Properties
|
19 |
def display_graph_properties(G):
|
|
|
20 |
pathlengths = []
|
|
|
|
|
21 |
st.write("### Source vertex {target:length, }")
|
22 |
for v in G.nodes():
|
23 |
spl = dict(nx.single_source_shortest_path_length(G, v))
|
|
|
25 |
for p in spl:
|
26 |
pathlengths.append(spl[p])
|
27 |
|
|
|
28 |
avg_path_length = sum(pathlengths) / len(pathlengths)
|
29 |
st.write(f"### Average shortest path length: {avg_path_length}")
|
30 |
|
|
|
31 |
dist = {}
|
32 |
for p in pathlengths:
|
33 |
+
dist[p] = dist.get(p, 0) + 1
|
|
|
|
|
|
|
|
|
34 |
st.write("### Length #paths")
|
35 |
for d in sorted(dist.keys()):
|
36 |
st.write(f"Length {d}: {dist[d]} paths")
|
37 |
|
|
|
38 |
st.write("### Properties")
|
39 |
st.write(f"Radius: {nx.radius(G)}")
|
40 |
st.write(f"Diameter: {nx.diameter(G)}")
|
|
|
46 |
# Visualize the graph
|
47 |
st.write("### Graph Visualization")
|
48 |
pos = nx.spring_layout(G, seed=3068) # Seed layout for reproducibility
|
49 |
+
draw_graph(G, pos)
|
|
|
|
|
50 |
|
51 |
# Function to display graph for Basic: Read and write graphs
|
52 |
def display_read_write_graph(G):
|
|
|
53 |
st.write("### Adjacency List:")
|
54 |
for line in nx.generate_adjlist(G):
|
55 |
st.write(line)
|
|
|
67 |
# Visualize the graph
|
68 |
st.write("### Graph Visualization:")
|
69 |
pos = nx.spring_layout(H, seed=200) # Seed for reproducibility
|
70 |
+
draw_graph(H, pos)
|
|
|
|
|
71 |
|
72 |
# Function to display Simple Graphs for Basic: Simple graph
|
73 |
def display_simple_graph(G, pos=None):
|
|
|
122 |
pos[center_node] = np.array([0, 0]) # Manually specify node position
|
123 |
|
124 |
# Draw the graph
|
125 |
+
draw_graph(G, pos)
|
|
|
126 |
|
127 |
# Display Basic: Properties if selected
|
128 |
if sidebar_option == "Basic: Properties":
|
129 |
st.title("Basic: Properties")
|
130 |
option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
|
131 |
|
|
|
132 |
if option == "Default Example":
|
133 |
G = nx.lollipop_graph(4, 6)
|
134 |
display_graph_properties(G)
|
135 |
|
|
|
136 |
elif option == "Create your own":
|
137 |
num_nodes = st.number_input("Number of nodes:", min_value=2, max_value=50, value=5)
|
138 |
num_edges = st.number_input("Number of edges per group (for lollipop graph):", min_value=1, max_value=10, value=3)
|
139 |
|
|
|
140 |
if st.button("Generate"):
|
141 |
if num_nodes >= 2 and num_edges >= 1:
|
142 |
G_custom = nx.lollipop_graph(num_nodes, num_edges)
|
|
|
147 |
st.title("Basic: Read and write graphs")
|
148 |
option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
|
149 |
|
|
|
150 |
if option == "Default Example":
|
151 |
+
G = nx.grid_2d_graph(5, 5)
|
152 |
display_read_write_graph(G)
|
153 |
|
|
|
154 |
elif option == "Create your own":
|
155 |
rows = st.number_input("Number of rows:", min_value=2, max_value=20, value=5)
|
156 |
cols = st.number_input("Number of columns:", min_value=2, max_value=20, value=5)
|
157 |
|
|
|
158 |
if st.button("Generate"):
|
159 |
if rows >= 2 and cols >= 2:
|
160 |
G_custom = nx.grid_2d_graph(rows, cols)
|
|
|
165 |
st.title("Basic: Simple graph")
|
166 |
option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
|
167 |
|
|
|
168 |
if option == "Default Example":
|
169 |
G = nx.Graph()
|
170 |
G.add_edge(1, 2)
|
|
|
174 |
G.add_edge(3, 4)
|
175 |
G.add_edge(4, 5)
|
176 |
|
|
|
177 |
pos = {1: (0, 0), 2: (-1, 0.3), 3: (2, 0.17), 4: (4, 0.255), 5: (5, 0.03)}
|
178 |
display_simple_graph(G, pos)
|
179 |
|
|
|
180 |
elif option == "Create your own":
|
|
|
181 |
edges = []
|
|
|
|
|
|
|
182 |
edge_input = st.text_area("Edges:", value="1,2\n1,3\n2,3")
|
|
|
|
|
183 |
if edge_input:
|
184 |
edge_list = edge_input.split("\n")
|
185 |
for edge in edge_list:
|
186 |
u, v = map(int, edge.split(","))
|
187 |
edges.append((u, v))
|
188 |
|
|
|
189 |
if st.button("Generate"):
|
190 |
G_custom = nx.Graph()
|
191 |
G_custom.add_edges_from(edges)
|
|
|
|
|
192 |
pos = nx.spring_layout(G_custom, seed=42)
|
193 |
display_simple_graph(G_custom, pos)
|
194 |
|
|
|
197 |
st.title("Basic: Simple graph Directed")
|
198 |
option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
|
199 |
|
|
|
200 |
if option == "Default Example":
|
201 |
G = nx.DiGraph([(0, 3), (1, 3), (2, 4), (3, 5), (3, 6), (4, 6), (5, 6)])
|
202 |
|
|
|
203 |
left_nodes = [0, 1, 2]
|
204 |
middle_nodes = [3, 4]
|
205 |
right_nodes = [5, 6]
|
206 |
|
|
|
207 |
pos = {n: (0, i) for i, n in enumerate(left_nodes)}
|
208 |
pos.update({n: (1, i + 0.5) for i, n in enumerate(middle_nodes)})
|
209 |
pos.update({n: (2, i + 0.5) for i, n in enumerate(right_nodes)})
|
210 |
|
|
|
211 |
display_simple_directed_graph(G, pos)
|
212 |
|
|
|
213 |
elif option == "Create your own":
|
|
|
214 |
edges = []
|
|
|
|
|
|
|
215 |
edge_input = st.text_area("Edges:", value="1,2\n1,3\n2,3")
|
|
|
|
|
216 |
if edge_input:
|
217 |
edge_list = edge_input.split("\n")
|
218 |
for edge in edge_list:
|
219 |
u, v = map(int, edge.split(","))
|
220 |
edges.append((u, v))
|
221 |
|
|
|
222 |
if st.button("Generate"):
|
223 |
G_custom = nx.DiGraph()
|
224 |
G_custom.add_edges_from(edges)
|
|
|
|
|
225 |
pos = nx.spring_layout(G_custom, seed=42)
|
226 |
display_simple_directed_graph(G_custom, pos)
|
227 |
|