| import streamlit as st |
| import matplotlib.pyplot as plt |
| import networkx as nx |
| import numpy as np |
|
|
| |
| 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"]) |
|
|
| |
| 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(G): |
| |
| st.write("### Adjacency List:") |
| for line in nx.generate_adjlist(G): |
| st.write(line) |
| |
| |
| 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'") |
|
|
| |
| 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") |
|
|
| |
| st.write("### Graph Visualization:") |
| pos = nx.spring_layout(H, seed=200) |
| 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) |
|
|
| |
| def display_simple_graph(G, pos=None): |
| options = { |
| "font_size": 36, |
| "node_size": 3000, |
| "node_color": "white", |
| "edgecolors": "black", |
| "linewidths": 5, |
| "width": 5, |
| } |
| |
| |
| nx.draw_networkx(G, pos, **options) |
|
|
| |
| ax = plt.gca() |
| ax.margins(0.20) |
| plt.axis("off") |
| st.pyplot(plt) |
|
|
| |
| def display_simple_directed_graph(G, pos=None): |
| options = { |
| "node_size": 500, |
| "node_color": "lightblue", |
| "arrowsize": 20, |
| "width": 2, |
| "edge_color": "gray", |
| } |
| |
| |
| nx.draw_networkx(G, pos, **options) |
|
|
| |
| ax = plt.gca() |
| ax.margins(0.20) |
| plt.axis("off") |
| st.pyplot(plt) |
|
|
| |
| def display_custom_node_position(): |
| st.title("Drawing: Custom Node Position") |
| option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) |
|
|
| if option == "Default Example": |
| |
| G = nx.path_graph(20) |
| center_node = 5 |
| edge_nodes = set(G) - {center_node} |
| |
| |
| pos = nx.circular_layout(G.subgraph(edge_nodes)) |
| pos[center_node] = np.array([0, 0]) |
| |
| |
| nx.draw(G, pos, with_labels=True) |
| st.pyplot(plt) |
|
|
| elif option == "Create your own": |
| |
| 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="0,1\n1,2\n2,3") |
| |
| 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)) |
|
|
| |
| if st.button("Generate"): |
| G_custom = nx.Graph() |
| G_custom.add_edges_from(edges) |
|
|
| |
| st.write("Enter custom positions for nodes (format: node: x,y). For example, 0: 0,0 or 1: 1,2.") |
| pos_input = st.text_area("Node positions:", value="0: 0,0\n1: 1,1\n2: 2,0") |
| |
| pos = {} |
| if pos_input: |
| pos_list = pos_input.split("\n") |
| for position in pos_list: |
| node, coordinates = position.split(":") |
| x, y = map(float, coordinates.split(",")) |
| pos[int(node)] = np.array([x, y]) |
|
|
| |
| nx.draw(G_custom, pos, with_labels=True) |
| st.pyplot(plt) |
|
|
| |
| if sidebar_option == "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) |
|
|
| |
| 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")) |
|
|
| |
| if option == "Default Example": |
| G = nx.grid_2d_graph(5, 5) |
| display_read_write_graph(G) |
|
|
| |
| 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) |
|
|
| |
| if st.button("Generate"): |
| if rows >= 2 and cols >= 2: |
| G_custom = nx.grid_2d_graph(rows, cols) |
| display_read_write_graph(G_custom) |
|
|
| |
| elif sidebar_option == "Basic: Simple graph": |
| st.title("Basic: Simple graph") |
| option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) |
|
|
| |
| 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) |
|
|
| |
| 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) |
|
|
| |
| elif option == "Create your own": |
| |
| 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") |
| |
| |
| if edge_input: |
| edge_list = edge_input.split("\n") |
| for edge in edge_list: |
| u, v = map(int, edge.split(",")) |
| edges.append((u, v)) |
|
|
| |
| if st.button("Generate"): |
| G_custom = nx.Graph() |
| G_custom.add_edges_from(edges) |
| |
| |
| pos = nx.spring_layout(G_custom, seed=42) |
| display_simple_graph(G_custom, pos) |
|
|
| |
| elif sidebar_option == "Basic: Simple graph Directed": |
| st.title("Basic: Simple graph Directed") |
| option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) |
|
|
| |
| if option == "Default Example": |
| G = nx.DiGraph([(0, 3), (1, 3), (2, 4), (3, 5), (3, 6), (4, 6), (5, 6)]) |
|
|
| |
| left_nodes = [0, 1, 2] |
| middle_nodes = [3, 4] |
| right_nodes = [5, 6] |
|
|
| |
| pos = {n: (0, i) for i, n in enumerate(left_nodes)} |
| pos.update({n: (1, i + 0.5) for i, n in enumerate(middle_nodes)}) |
| pos.update({n: (2, i + 0.5) for i, n in enumerate(right_nodes)}) |
|
|
| |
| display_simple_directed_graph(G, pos) |
|
|
| |
| elif option == "Create your own": |
| |
| edges = [] |
| |
| |
| st.write("Enter the directed 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") |
| |
| |
| if edge_input: |
| edge_list = edge_input.split("\n") |
| for edge in edge_list: |
| u, v = map(int, edge.split(",")) |
| edges.append((u, v)) |
|
|
| |
| if st.button("Generate"): |
| G_custom = nx.DiGraph() |
| G_custom.add_edges_from(edges) |
| |
| |
| pos = nx.spring_layout(G_custom, seed=42) |
| display_simple_directed_graph(G_custom, pos) |
|
|
| |
| elif sidebar_option == "Drawing: Custom Node Position": |
| display_custom_node_position() |
|
|