| import streamlit as st |
| import itertools as it |
| import matplotlib.pyplot as plt |
| import networkx as nx |
| import numpy as np |
| from operator import itemgetter |
|
|
| |
| 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: Cluster Layout", "Drawing: Degree Analysis", |
| "Drawing: Ego Graph", "Drawing: Eigenvalues", "Drawing: Four Grids", |
| "Drawing: House With Colors", "Drawing: Labels And Colors"]) |
|
|
| |
| def draw_graph(G, pos=None, title="Graph Visualization"): |
| 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_labels_and_colors(): |
| st.title("Drawing: Labels And Colors") |
|
|
| option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) |
|
|
| if option == "Default Example": |
| |
| G = nx.cubical_graph() |
| pos = nx.spring_layout(G, seed=3113794652) |
|
|
| |
| options = {"edgecolors": "tab:gray", "node_size": 800, "alpha": 0.9} |
| nx.draw_networkx_nodes(G, pos, nodelist=[0, 1, 2, 3], node_color="tab:red", **options) |
| nx.draw_networkx_nodes(G, pos, nodelist=[4, 5, 6, 7], node_color="tab:blue", **options) |
|
|
| |
| nx.draw_networkx_edges(G, pos, width=1.0, alpha=0.5) |
| nx.draw_networkx_edges( |
| G, |
| pos, |
| edgelist=[(0, 1), (1, 2), (2, 3), (3, 0)], |
| width=8, |
| alpha=0.5, |
| edge_color="tab:red", |
| ) |
| nx.draw_networkx_edges( |
| G, |
| pos, |
| edgelist=[(4, 5), (5, 6), (6, 7), (7, 4)], |
| width=8, |
| alpha=0.5, |
| edge_color="tab:blue", |
| ) |
|
|
| |
| labels = {0: r"$a$", 1: r"$b$", 2: r"$c$", 3: r"$d$", 4: r"$\alpha$", 5: r"$\beta$", 6: r"$\gamma$", 7: r"$\delta$"} |
| nx.draw_networkx_labels(G, pos, labels, font_size=22, font_color="whitesmoke") |
|
|
| plt.tight_layout() |
| plt.axis("off") |
| st.pyplot(plt) |
|
|
| elif option == "Create your own": |
| |
| st.write("Enter the nodes and edges to create your own labeled graph.") |
|
|
| nodes = st.text_area("Enter node labels (comma-separated, e.g., a,b,c,d):", value="a,b,c,d") |
| node_labels = nodes.split(',') |
|
|
| edges = st.text_area("Enter edges (format: node1-node2, comma-separated, e.g., a-b,b-c):", value="a-b,b-c,c-d") |
| edge_list = [tuple(edge.split('-')) for edge in edges.split(',')] |
|
|
| |
| G_custom = nx.Graph() |
| G_custom.add_nodes_from(node_labels) |
| G_custom.add_edges_from(edge_list) |
|
|
| |
| node_color = st.color_picker("Pick a color for nodes:", "#FF6347") |
| edge_color = st.color_picker("Pick a color for edges:", "#4682B4") |
| |
| |
| pos_custom = nx.spring_layout(G_custom) |
|
|
| |
| nx.draw_networkx_nodes(G_custom, pos_custom, node_color=node_color, node_size=800, edgecolors="gray", alpha=0.9) |
| nx.draw_networkx_edges(G_custom, pos_custom, edge_color=edge_color, width=2, alpha=0.7) |
| |
| |
| custom_labels = {node: f"${node}$" for node in node_labels} |
| nx.draw_networkx_labels(G_custom, pos_custom, labels=custom_labels, font_size=22, font_color="whitesmoke") |
|
|
| plt.tight_layout() |
| plt.axis("off") |
| st.pyplot(plt) |
|
|
| |
| if sidebar_option == "Drawing: Labels And Colors": |
| display_labels_and_colors() |
|
|
| |
| def display_house_with_colors(): |
| st.title("Drawing: House With Colors") |
|
|
| option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) |
|
|
| if option == "Default Example": |
| |
| G = nx.house_graph() |
| pos = {0: (0, 0), 1: (1, 0), 2: (0, 1), 3: (1, 1), 4: (0.5, 2.0)} |
|
|
| |
| nx.draw_networkx_nodes(G, pos, node_size=3000, nodelist=[0, 1, 2, 3], node_color="tab:blue") |
| nx.draw_networkx_nodes(G, pos, node_size=2000, nodelist=[4], node_color="tab:orange") |
| nx.draw_networkx_edges(G, pos, alpha=0.5, width=6) |
| |
| |
| ax = plt.gca() |
| ax.margins(0.11) |
| plt.tight_layout() |
| plt.axis("off") |
| st.pyplot(plt) |
|
|
| elif option == "Create your own": |
| |
| st.write("Specify positions for the house graph nodes.") |
|
|
| positions = {} |
| for i in range(5): |
| x = st.number_input(f"X-coordinate for node {i}:", min_value=-10.0, max_value=10.0, value=0.0, step=0.1) |
| y = st.number_input(f"Y-coordinate for node {i}:", min_value=-10.0, max_value=10.0, value=0.0, step=0.1) |
| |
| positions[i] = (x, y) |
|
|
| |
| wall_color = st.color_picker("Wall color:", "#0000FF") |
| roof_color = st.color_picker("Roof color:", "#FFA500") |
|
|
| if st.button("Generate"): |
| |
| G_custom = nx.house_graph() |
|
|
| |
| nx.draw_networkx_nodes(G_custom, positions, node_size=3000, nodelist=[0, 1, 2, 3], node_color=wall_color) |
| nx.draw_networkx_nodes(G_custom, positions, node_size=2000, nodelist=[4], node_color=roof_color) |
| nx.draw_networkx_edges(G_custom, positions, alpha=0.5, width=6) |
|
|
| |
| ax = plt.gca() |
| ax.margins(0.11) |
| plt.tight_layout() |
| plt.axis("off") |
| st.pyplot(plt) |
|
|
| |
| if sidebar_option == "Drawing: House With Colors": |
| display_house_with_colors() |
|
|
| |
| def display_four_grids(): |
| st.title("Drawing: Four Grids") |
|
|
| option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) |
|
|
| if option == "Default Example": |
| |
| G = nx.grid_2d_graph(4, 4) |
| pos = nx.spring_layout(G, iterations=100, seed=39775) |
|
|
| |
| fig, all_axes = plt.subplots(2, 2) |
| ax = all_axes.flat |
|
|
| |
| nx.draw(G, pos, ax=ax[0], font_size=8) |
| nx.draw(G, pos, ax=ax[1], node_size=0, with_labels=False) |
| nx.draw( |
| G, |
| pos, |
| ax=ax[2], |
| node_color="tab:green", |
| edgecolors="tab:gray", |
| edge_color="tab:gray", |
| node_size=250, |
| with_labels=False, |
| width=6, |
| ) |
| H = G.to_directed() |
| nx.draw( |
| H, |
| pos, |
| ax=ax[3], |
| node_color="tab:orange", |
| node_size=20, |
| with_labels=False, |
| arrowsize=10, |
| width=2, |
| ) |
|
|
| |
| for a in ax: |
| a.margins(0.10) |
| fig.tight_layout() |
| st.pyplot(fig) |
|
|
| elif option == "Create your own": |
| |
| rows = st.number_input("Number of rows:", min_value=2, max_value=20, value=4) |
| cols = st.number_input("Number of columns:", min_value=2, max_value=20, value=4) |
|
|
| if st.button("Generate"): |
| |
| G_custom = nx.grid_2d_graph(rows, cols) |
| pos = nx.spring_layout(G_custom, iterations=100, seed=39775) |
|
|
| |
| fig, all_axes = plt.subplots(2, 2) |
| ax = all_axes.flat |
|
|
| |
| nx.draw(G_custom, pos, ax=ax[0], font_size=8) |
| nx.draw(G_custom, pos, ax=ax[1], node_size=0, with_labels=False) |
| nx.draw( |
| G_custom, |
| pos, |
| ax=ax[2], |
| node_color="tab:green", |
| edgecolors="tab:gray", |
| edge_color="tab:gray", |
| node_size=250, |
| with_labels=False, |
| width=6, |
| ) |
| H = G_custom.to_directed() |
| nx.draw( |
| H, |
| pos, |
| ax=ax[3], |
| node_color="tab:orange", |
| node_size=20, |
| with_labels=False, |
| arrowsize=10, |
| width=2, |
| ) |
|
|
| |
| for a in ax: |
| a.margins(0.10) |
| fig.tight_layout() |
| st.pyplot(fig) |
|
|
| |
| if sidebar_option == "Drawing: Four Grids": |
| display_four_grids() |
|
|
| |
| def display_eigenvalue_analysis(): |
| st.title("Drawing: Eigenvalues") |
|
|
| option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) |
|
|
| if option == "Default Example": |
| |
| n = 1000 |
| m = 5000 |
| G = nx.gnm_random_graph(n, m, seed=5040) |
|
|
| |
| L = nx.normalized_laplacian_matrix(G) |
| eigenvalues = np.linalg.eigvals(L.toarray()) |
|
|
| |
| st.write(f"Largest eigenvalue: {max(eigenvalues)}") |
| st.write(f"Smallest eigenvalue: {min(eigenvalues)}") |
|
|
| |
| st.write("### Eigenvalue Histogram") |
| plt.hist(eigenvalues, bins=100) |
| plt.xlim(0, 2) |
| st.pyplot(plt) |
|
|
| elif option == "Create your own": |
| |
| n_nodes = st.number_input("Number of nodes:", min_value=2, max_value=1000, value=100) |
| m_edges = st.number_input("Number of edges:", min_value=1, max_value=n_nodes*(n_nodes-1)//2, value=500) |
|
|
| if st.button("Generate"): |
| |
| G_custom = nx.gnm_random_graph(n_nodes, m_edges, seed=5040) |
|
|
| |
| L = nx.normalized_laplacian_matrix(G_custom) |
| eigenvalues = np.linalg.eigvals(L.toarray()) |
|
|
| |
| st.write(f"Largest eigenvalue: {max(eigenvalues)}") |
| st.write(f"Smallest eigenvalue: {min(eigenvalues)}") |
|
|
| |
| st.write("### Eigenvalue Histogram") |
| plt.hist(eigenvalues, bins=100) |
| plt.xlim(0, 2) |
| st.pyplot(plt) |
|
|
| |
| if sidebar_option == "Drawing: Eigenvalues": |
| display_eigenvalue_analysis() |
|
|
| |
| 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: |
| dist[p] = dist.get(p, 0) + 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) |
| draw_graph(G, pos) |
|
|
| |
| 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) |
| draw_graph(H, pos) |
|
|
| |
| 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") |
| |
| |
| 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]) |
| |
| |
| draw_graph(G, pos) |
|
|
| |
| def display_cluster_layout(): |
| st.title("Drawing: Cluster Layout") |
|
|
| 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) |
|
|
| |
| def display_degree_analysis(): |
| st.title("Drawing: Degree Analysis") |
|
|
| option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) |
|
|
| if option == "Default Example": |
| G = nx.gnp_random_graph(100, 0.02, seed=10374196) |
| |
| degree_sequence = sorted((d for n, d in G.degree()), reverse=True) |
| dmax = max(degree_sequence) |
|
|
| fig = plt.figure("Degree of a random graph", figsize=(8, 8)) |
| |
| axgrid = fig.add_gridspec(5, 4) |
|
|
| ax0 = fig.add_subplot(axgrid[0:3, :]) |
| Gcc = G.subgraph(sorted(nx.connected_components(G), key=len, reverse=True)[0]) |
| pos = nx.spring_layout(Gcc, seed=10396953) |
| nx.draw_networkx_nodes(Gcc, pos, ax=ax0, node_size=20) |
| nx.draw_networkx_edges(Gcc, pos, ax=ax0, alpha=0.4) |
| ax0.set_title("Connected components of G") |
| ax0.set_axis_off() |
|
|
| ax1 = fig.add_subplot(axgrid[3:, :2]) |
| ax1.plot(degree_sequence, "b-", marker="o") |
| ax1.set_title("Degree Rank Plot") |
| ax1.set_ylabel("Degree") |
| ax1.set_xlabel("Rank") |
|
|
| ax2 = fig.add_subplot(axgrid[3:, 2:]) |
| ax2.bar(*np.unique(degree_sequence, return_counts=True)) |
| ax2.set_title("Degree histogram") |
| ax2.set_xlabel("Degree") |
| ax2.set_ylabel("# of Nodes") |
|
|
| fig.tight_layout() |
| st.pyplot(fig) |
|
|
| elif option == "Create your own": |
| n_nodes = st.number_input("Number of nodes:", min_value=2, max_value=500, value=100) |
| p_edge = st.slider("Edge probability:", min_value=0.0, max_value=1.0, value=0.02) |
| |
| if st.button("Generate"): |
| if n_nodes >= 2: |
| G_custom = nx.gnp_random_graph(n_nodes, p_edge, seed=10374196) |
| degree_sequence = sorted((d for n, d in G_custom.degree()), reverse=True) |
| dmax = max(degree_sequence) |
|
|
| fig = plt.figure("Degree of a random graph", figsize=(8, 8)) |
| |
| axgrid = fig.add_gridspec(5, 4) |
|
|
| ax0 = fig.add_subplot(axgrid[0:3, :]) |
| Gcc = G_custom.subgraph(sorted(nx.connected_components(G_custom), key=len, reverse=True)[0]) |
| pos = nx.spring_layout(Gcc, seed=10396953) |
| nx.draw_networkx_nodes(Gcc, pos, ax=ax0, node_size=20) |
| nx.draw_networkx_edges(Gcc, pos, ax=ax0, alpha=0.4) |
| ax0.set_title("Connected components of G") |
| ax0.set_axis_off() |
|
|
| ax1 = fig.add_subplot(axgrid[3:, :2]) |
| ax1.plot(degree_sequence, "b-", marker="o") |
| ax1.set_title("Degree Rank Plot") |
| ax1.set_ylabel("Degree") |
| ax1.set_xlabel("Rank") |
|
|
| ax2 = fig.add_subplot(axgrid[3:, 2:]) |
| ax2.bar(*np.unique(degree_sequence, return_counts=True)) |
| ax2.set_title("Degree histogram") |
| ax2.set_xlabel("Degree") |
| ax2.set_ylabel("# of Nodes") |
|
|
| fig.tight_layout() |
| st.pyplot(fig) |
|
|
| |
| def display_ego_graph(): |
| st.title("Drawing: Ego Graph") |
|
|
| option = st.radio("Choose a graph type:", ("Default Example", "Create your own")) |
|
|
| if option == "Default Example": |
| |
| n = 1000 |
| m = 2 |
| seed = 20532 |
| G = nx.barabasi_albert_graph(n, m, seed=seed) |
|
|
| |
| node_and_degree = G.degree() |
| (largest_hub, degree) = sorted(node_and_degree, key=itemgetter(1))[-1] |
|
|
| |
| hub_ego = nx.ego_graph(G, largest_hub) |
|
|
| |
| pos = nx.spring_layout(hub_ego, seed=seed) |
| nx.draw(hub_ego, pos, node_color="b", node_size=50, with_labels=False) |
|
|
| |
| options = {"node_size": 300, "node_color": "r"} |
| nx.draw_networkx_nodes(hub_ego, pos, nodelist=[largest_hub], **options) |
| plt.tight_layout() |
| st.pyplot(plt) |
|
|
| elif option == "Create your own": |
| n_nodes = st.number_input("Number of nodes:", min_value=2, max_value=1000, value=100) |
| m_edges = st.number_input("Edges per node:", min_value=1, max_value=10, value=2) |
|
|
| if st.button("Generate"): |
| if n_nodes >= 2: |
| G_custom = nx.barabasi_albert_graph(n_nodes, m_edges, seed=20532) |
|
|
| |
| node_and_degree = G_custom.degree() |
| (largest_hub, degree) = sorted(node_and_degree, key=itemgetter(1))[-1] |
|
|
| |
| hub_ego = nx.ego_graph(G_custom, largest_hub) |
|
|
| |
| pos = nx.spring_layout(hub_ego, seed=20532) |
| nx.draw(hub_ego, pos, node_color="b", node_size=50, with_labels=False) |
|
|
| |
| options = {"node_size": 300, "node_color": "r"} |
| nx.draw_networkx_nodes(hub_ego, pos, nodelist=[largest_hub], **options) |
| plt.tight_layout() |
| st.pyplot(plt) |
|
|
| |
| if sidebar_option == "Drawing: Ego Graph": |
| display_ego_graph() |
|
|
| |
| elif 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 = [] |
| 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 = [] |
| 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() |
|
|
| |
| elif sidebar_option == "Drawing: Cluster Layout": |
| display_cluster_layout() |
|
|
| |
| elif sidebar_option == "Drawing: Degree Analysis": |
| display_degree_analysis() |
|
|