Spaces:
Sleeping
Sleeping
import streamlit as st | |
import matplotlib.pyplot as plt | |
import networkx as nx | |
# Sidebar for selecting an option | |
sidebar_option = st.sidebar.radio("Select an option", | |
["Select an option", "Basic: Properties", | |
"Basic: Read and write graphs", "Basic: Simple graph"]) | |
# Function to display properties and graph for Basic: Properties | |
def display_graph_properties(G): | |
# Initialize a list for path lengths | |
pathlengths = [] | |
# Display the source-target shortest path lengths | |
st.write("### Source vertex {target:length, }") | |
for v in G.nodes(): | |
spl = dict(nx.single_source_shortest_path_length(G, v)) | |
st.write(f"Vertex {v}: {spl}") | |
for p in spl: | |
pathlengths.append(spl[p]) | |
# Calculate and display the average shortest path length | |
avg_path_length = sum(pathlengths) / len(pathlengths) | |
st.write(f"### Average shortest path length: {avg_path_length}") | |
# Calculate and display the distribution of path lengths | |
dist = {} | |
for p in pathlengths: | |
if p in dist: | |
dist[p] += 1 | |
else: | |
dist[p] = 1 | |
st.write("### Length #paths") | |
for d in sorted(dist.keys()): | |
st.write(f"Length {d}: {dist[d]} paths") | |
# Display the graph metrics with a "Properties" heading | |
st.write("### Properties") | |
st.write(f"Radius: {nx.radius(G)}") | |
st.write(f"Diameter: {nx.diameter(G)}") | |
st.write(f"Eccentricity: {nx.eccentricity(G)}") | |
st.write(f"Center: {nx.center(G)}") | |
st.write(f"Periphery: {nx.periphery(G)}") | |
st.write(f"Density: {nx.density(G)}") | |
# Visualize the graph | |
st.write("### Graph Visualization") | |
pos = nx.spring_layout(G, seed=3068) # Seed layout for reproducibility | |
plt.figure(figsize=(8, 6)) | |
nx.draw(G, pos=pos, with_labels=True, node_color='lightblue', node_size=500, font_size=10, font_weight='bold') | |
st.pyplot(plt) | |
# Function to display graph for Basic: Read and write graphs | |
def display_read_write_graph(G): | |
# Print the adjacency list of the graph | |
st.write("### Adjacency List:") | |
for line in nx.generate_adjlist(G): | |
st.write(line) | |
# Write the graph's edge list to a file | |
st.write("### Writing Edge List to 'grid.edgelist' file:") | |
nx.write_edgelist(G, path="grid.edgelist", delimiter=":") | |
st.write("Edge list written to 'grid.edgelist'") | |
# Read the graph from the edge list | |
st.write("### Reading Edge List from 'grid.edgelist' file:") | |
H = nx.read_edgelist(path="grid.edgelist", delimiter=":") | |
st.write("Edge list read into graph H") | |
# Visualize the graph | |
st.write("### Graph Visualization:") | |
pos = nx.spring_layout(H, seed=200) # Seed for reproducibility | |
plt.figure(figsize=(8, 6)) | |
nx.draw(H, pos, with_labels=True, node_color='lightblue', node_size=500, font_size=10, font_weight='bold') | |
st.pyplot(plt) | |
# Function to display Simple Graphs for Basic: Simple graph | |
def display_simple_graph(G, pos=None): | |
options = { | |
"font_size": 36, | |
"node_size": 3000, | |
"node_color": "white", | |
"edgecolors": "black", | |
"linewidths": 5, | |
"width": 5, | |
} | |
# Draw the network | |
nx.draw_networkx(G, pos, **options) | |
# Set margins for the axes so that nodes aren't clipped | |
ax = plt.gca() | |
ax.margins(0.20) | |
plt.axis("off") | |
st.pyplot(plt) | |
# Display Basic: Properties if selected | |
if sidebar_option == "Basic: Properties": | |
st.title("Basic: Properties") | |
option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) | |
# Default example: 5x5 grid graph | |
if option == "Default Example": | |
G = nx.lollipop_graph(4, 6) | |
display_graph_properties(G) | |
# Create your own graph | |
elif option == "Create your own": | |
num_nodes = st.number_input("Number of nodes:", min_value=2, max_value=50, value=5) | |
num_edges = st.number_input("Number of edges per group (for lollipop graph):", min_value=1, max_value=10, value=3) | |
# Button to generate the graph | |
if st.button("Generate"): | |
if num_nodes >= 2 and num_edges >= 1: | |
G_custom = nx.lollipop_graph(num_nodes, num_edges) | |
display_graph_properties(G_custom) | |
# Display Basic: Read and write graphs if selected | |
elif sidebar_option == "Basic: Read and write graphs": | |
st.title("Basic: Read and write graphs") | |
option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) | |
# Default example: 5x5 grid graph | |
if option == "Default Example": | |
G = nx.grid_2d_graph(5, 5) # 5x5 grid | |
display_read_write_graph(G) | |
# Create your own graph | |
elif option == "Create your own": | |
rows = st.number_input("Number of rows:", min_value=2, max_value=20, value=5) | |
cols = st.number_input("Number of columns:", min_value=2, max_value=20, value=5) | |
# Button to generate the graph | |
if st.button("Generate"): | |
if rows >= 2 and cols >= 2: | |
G_custom = nx.grid_2d_graph(rows, cols) | |
display_read_write_graph(G_custom) | |
# Display Basic: Simple Graph if selected | |
elif sidebar_option == "Basic: Simple graph": | |
st.title("Basic: Simple graph") | |
option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) | |
# Default example: simple undirected graph | |
if option == "Default Example": | |
G = nx.Graph() | |
G.add_edge(1, 2) | |
G.add_edge(1, 3) | |
G.add_edge(1, 5) | |
G.add_edge(2, 3) | |
G.add_edge(3, 4) | |
G.add_edge(4, 5) | |
# explicitly set positions for visualization | |
pos = {1: (0, 0), 2: (-1, 0.3), 3: (2, 0.17), 4: (4, 0.255), 5: (5, 0.03)} | |
display_simple_graph(G, pos) | |
# Create your own graph | |
elif option == "Create your own": | |
num_nodes = st.number_input("Number of nodes:", min_value=2, max_value=20, value=5) | |
edges = [] | |
# Let the user define edges | |
st.write("Enter the edges (as pairs of nodes) separated by commas. For example, 1,2 or 3,4.") | |
edge_input = st.text_area("Edges:", value="1,2\n1,3\n2,3") | |
# Parse the edges | |
if edge_input: | |
edge_list = edge_input.split("\n") | |
for edge in edge_list: | |
u, v = map(int, edge.split(",")) | |
edges.append((u, v)) | |
# Button to generate the graph | |
if st.button("Generate"): | |
G_custom = nx.Graph() | |
G_custom.add_edges_from(edges) | |
# Set a basic layout (spring layout as default) | |
pos = nx.spring_layout(G_custom, seed=42) | |
display_simple_graph(G_custom, pos) | |