shukdevdatta123's picture
Update app.py
2b5132f verified
raw
history blame
7.96 kB
import streamlit as st
import networkx as nx
import matplotlib.pyplot as plt
# 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",
"Basic: Simple graph Directed", "Drawing: Custom Node Position",
"Drawing: Chess Masters", "Drawing: Cluster Layout"])
# Helper function to draw and display graph
def draw_graph(G, pos=None, title="Graph Visualization", edgewidth=None, nodesize=None):
if edgewidth is None:
edgewidth = [1] * len(G.edges()) # Default edge width if not provided
if nodesize is None:
nodesize = [300] * len(G.nodes()) # Default node size if not provided
plt.figure(figsize=(12, 12))
nx.draw_networkx_edges(G, pos, alpha=0.3, width=edgewidth, edge_color="m")
nx.draw_networkx_nodes(G, pos, node_size=nodesize, node_color="#210070", alpha=0.9)
label_options = {"ec": "k", "fc": "white", "alpha": 0.7}
nx.draw_networkx_labels(G, pos, font_size=14, bbox=label_options)
# Title/legend
font = {"fontname": "Helvetica", "color": "k", "fontweight": "bold", "fontsize": 14}
ax = plt.gca()
ax.set_title(title, font)
ax.text(
0.80,
0.10,
"edge width = # games played",
horizontalalignment="center",
transform=ax.transAxes,
fontdict=font,
)
ax.text(
0.80,
0.06,
"node size = # games won",
horizontalalignment="center",
transform=ax.transAxes,
fontdict=font,
)
# Resize figure for label readability
ax.margins(0.1, 0.05)
plt.axis("off")
st.pyplot(plt)
# Drawing: Cluster Layout
def display_cluster_layout():
st.title("Drawing: Cluster Layout")
option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
if option == "Default Example":
G = nx.davis_southern_women_graph()
# Compute communities using greedy modularity community detection
communities = nx.community.greedy_modularity_communities(G)
# Compute positions for the node clusters as if they were themselves nodes in a supergraph
supergraph = nx.cycle_graph(len(communities))
superpos = nx.spring_layout(G, scale=50, seed=429)
# Use the "supernode" positions as the center of each node cluster
centers = list(superpos.values())
pos = {}
for center, comm in zip(centers, communities):
pos.update(nx.spring_layout(nx.subgraph(G, comm), center=center, seed=1430))
# Nodes colored by cluster
for nodes, clr in zip(communities, ("tab:blue", "tab:orange", "tab:green")):
nx.draw_networkx_nodes(G, pos=pos, nodelist=nodes, node_color=clr, node_size=100)
nx.draw_networkx_edges(G, pos=pos)
plt.tight_layout()
st.pyplot(plt)
elif option == "Create your own":
uploaded_file = st.file_uploader("Upload your own graph file (in GML format)", type="gml")
if uploaded_file is not None:
G_custom = nx.read_gml(uploaded_file)
# Compute communities using greedy modularity community detection
communities = nx.community.greedy_modularity_communities(G_custom)
# Compute positions for the node clusters as if they were themselves nodes in a supergraph
supergraph = nx.cycle_graph(len(communities))
superpos = nx.spring_layout(G_custom, scale=50, seed=429)
# Use the "supernode" positions as the center of each node cluster
centers = list(superpos.values())
pos = {}
for center, comm in zip(centers, communities):
pos.update(nx.spring_layout(nx.subgraph(G_custom, comm), center=center, seed=1430))
# Nodes colored by cluster
for nodes, clr in zip(communities, ("tab:blue", "tab:orange", "tab:green")):
nx.draw_networkx_nodes(G_custom, pos=pos, nodelist=nodes, node_color=clr, node_size=100)
nx.draw_networkx_edges(G_custom, pos=pos)
plt.tight_layout()
st.pyplot(plt)
# Display other sections
def display_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)
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)
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)
def display_graph_properties(G):
pathlengths = []
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])
avg_path_length = sum(pathlengths) / len(pathlengths)
st.write(f"### Average shortest path length: {avg_path_length}")
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")
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)}")
st.write("### Graph Visualization")
pos = nx.spring_layout(G, seed=3068)
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)
# Display other sections
def display_read_write_graph():
st.title("Basic: Read and write graphs")
G = nx.karate_club_graph()
# Write the graph
nx.write_gml(G, "karate_club.gml")
st.write("Graph written to 'karate_club.gml'.")
# Read the graph back
G_new = nx.read_gml("karate_club.gml")
st.write("Graph read back from 'karate_club.gml'.")
nx.draw(G_new, with_labels=True)
st.pyplot(plt)
def display_simple_graph():
st.title("Basic: Simple graph")
G = nx.complete_graph(5)
nx.draw(G, with_labels=True)
st.pyplot(plt)
def display_simple_directed_graph():
st.title("Basic: Simple graph Directed")
G = nx.complete_graph(5, nx.DiGraph())
nx.draw(G, with_labels=True)
st.pyplot(plt)
def display_custom_node_position():
st.title("Drawing: Custom Node Position")
pos = {"A": (1, 2), "B": (2, 3), "C": (3, 1)}
G = nx.Graph(pos)
nx.draw(G, pos=pos, with_labels=True)
st.pyplot(plt)
# Call the appropriate function based on sidebar selection
if sidebar_option == "Basic: Properties":
display_basic_properties()
elif sidebar_option == "Basic: Read and write graphs":
display_read_write_graph()
elif sidebar_option == "Basic: Simple graph":
display_simple_graph()
elif sidebar_option == "Basic: Simple graph Directed":
display_simple_directed_graph()
elif sidebar_option == "Drawing: Custom Node Position":
display_custom_node_position()
elif sidebar_option == "Drawing: Chess Masters":
display_chess_masters_graph()
elif sidebar_option == "Drawing: Cluster Layout":
display_cluster_layout()
else:
st.write("Please select a valid option from the sidebar.")