| import streamlit as st |
| import networkx as nx |
| import matplotlib.pyplot as plt |
|
|
| |
| 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"]) |
|
|
| |
| def draw_graph(G, pos=None, title="Graph Visualization", edgewidth=None, nodesize=None): |
| if edgewidth is None: |
| edgewidth = [1] * len(G.edges()) |
|
|
| if nodesize is None: |
| nodesize = [300] * len(G.nodes()) |
|
|
| 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) |
|
|
| |
| 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, |
| ) |
|
|
| |
| ax.margins(0.1, 0.05) |
| plt.axis("off") |
| st.pyplot(plt) |
|
|
| |
| 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() |
|
|
| |
| communities = nx.community.greedy_modularity_communities(G) |
|
|
| |
| supergraph = nx.cycle_graph(len(communities)) |
| superpos = nx.spring_layout(G, scale=50, seed=429) |
|
|
| |
| 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)) |
|
|
| |
| 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) |
| |
| communities = nx.community.greedy_modularity_communities(G_custom) |
|
|
| |
| supergraph = nx.cycle_graph(len(communities)) |
| superpos = nx.spring_layout(G_custom, scale=50, seed=429) |
|
|
| |
| 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)) |
|
|
| |
| 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) |
|
|
| |
| def display_basic_properties(): |
| st.title("Basic: Properties") |
| option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) |
|
|
| |
| 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) |
|
|
| |
| def display_read_write_graph(): |
| st.title("Basic: Read and write graphs") |
| G = nx.karate_club_graph() |
|
|
| |
| nx.write_gml(G, "karate_club.gml") |
| st.write("Graph written to 'karate_club.gml'.") |
|
|
| |
| 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) |
|
|
|
|
| |
| 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.") |
|
|