shukdevdatta123's picture
Update app.py
6bb529c verified
raw
history blame
30.9 kB
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 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: Cluster Layout", "Drawing: Degree Analysis",
"Drawing: Ego Graph", "Drawing: Eigenvalues", "Drawing: Four Grids",
"Drawing: House With Colors", "Drawing: Labels And Colors",
"Drawing: Multipartite Layout", "Drawing: Node Colormap"])
# Helper function to draw and display graph
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)
# Function to display Drawing: Node Colormap
def display_node_colormap():
st.title("Drawing: Node Colormap")
option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
if option == "Default Example":
G = nx.cycle_graph(24)
pos = nx.circular_layout(G)
nx.draw(G, pos, node_color=range(24), node_size=800, cmap=plt.cm.Blues)
st.pyplot(plt)
elif option == "Create your own":
num_nodes = st.number_input("Number of nodes:", min_value=2, max_value=100, value=24)
color_map = st.selectbox("Select a colormap:", plt.colormaps(), index=plt.colormaps().index('Blues'))
if st.button("Generate Graph"):
# Create cycle graph with custom number of nodes
G_custom = nx.cycle_graph(num_nodes)
pos = nx.circular_layout(G_custom)
nx.draw(G_custom, pos, node_color=range(num_nodes), node_size=800, cmap=plt.get_cmap(color_map))
st.pyplot(plt)
# Display Drawing: Node Colormap if selected
if sidebar_option == "Drawing: Node Colormap":
display_node_colormap()
# Function to create a multipartite graph
def multilayered_graph(*subset_sizes):
G = nx.Graph()
layers = len(subset_sizes)
node_id = 0
# Create nodes for each subset and add edges between nodes in adjacent layers
for i, size in enumerate(subset_sizes):
for j in range(size):
G.add_node(node_id, layer=i) # Assign a layer attribute
node_id += 1
# Add edges between nodes in adjacent layers
node_ids = list(G.nodes())
for i in range(layers - 1):
layer_nodes = [node for node in node_ids if G.nodes[node]["layer"] == i]
next_layer_nodes = [node for node in node_ids if G.nodes[node]["layer"] == i + 1]
for node in layer_nodes:
for next_node in next_layer_nodes:
G.add_edge(node, next_node)
return G
# Function to display Multipartite Layout
def display_multipartite_layout():
st.title("Drawing: Multipartite Layout")
option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
if option == "Default Example":
subset_sizes = [5, 5, 4, 3, 2, 4, 4, 3]
subset_color = [
"gold", "violet", "violet", "violet", "violet",
"limegreen", "limegreen", "darkorange"
]
# Generate and plot multipartite graph
G = multilayered_graph(*subset_sizes)
color = [subset_color[data["layer"]] for v, data in G.nodes(data=True)]
pos = nx.multipartite_layout(G, subset_key="layer")
plt.figure(figsize=(8, 8))
nx.draw(G, pos, node_color=color, with_labels=False)
plt.axis("equal")
st.pyplot(plt)
elif option == "Create your own":
# Let the user input the subset sizes and colors
st.write("Enter the subset sizes and colors to create your own multipartite graph.")
subset_sizes_input = st.text_area("Enter subset sizes (comma-separated, e.g., 5,5,4,3):", value="5,5,4,3,2,4,4,3")
subset_sizes = list(map(int, subset_sizes_input.split(',')))
subset_colors_input = st.text_area("Enter subset colors (comma-separated, e.g., gold,violet,green):", value="gold,violet,violet,violet,violet,limegreen,limegreen,darkorange")
subset_colors = subset_colors_input.split(',')
# Check if the number of colors matches the number of subsets
if len(subset_sizes) != len(subset_colors):
st.error("The number of colors should match the number of subsets.")
else:
# Add a button to generate the graph
if st.button("Generate Graph"):
# Generate and plot multipartite graph
G = multilayered_graph(*subset_sizes)
color = [subset_colors[data["layer"]] for v, data in G.nodes(data=True)]
pos = nx.multipartite_layout(G, subset_key="layer")
plt.figure(figsize=(8, 8))
nx.draw(G, pos, node_color=color, with_labels=False)
plt.axis("equal")
st.pyplot(plt)
# Display Drawing: Multipartite Layout if selected
if sidebar_option == "Drawing: Multipartite Layout":
display_multipartite_layout()
# Function to display Labels and Colors
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":
# Create a cubical graph
G = nx.cubical_graph()
pos = nx.spring_layout(G, seed=3113794652) # positions for all nodes
# Draw nodes with different colors
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)
# Draw edges
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",
)
# Add labels for nodes
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":
# Let the user input the nodes and edges of the graph
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(',')]
# Let user choose colors for nodes and edges
node_color = st.color_picker("Pick a color for nodes:", "#FF6347")
edge_color = st.color_picker("Pick a color for edges:", "#4682B4")
# Add a button to generate the graph
if st.button("Generate Graph"):
# Generate graph based on user input
G_custom = nx.Graph()
G_custom.add_nodes_from(node_labels)
G_custom.add_edges_from(edge_list)
# Generate layout for the nodes
pos_custom = nx.spring_layout(G_custom)
# Draw the graph
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)
# Create custom labels
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)
# Display Drawing: Labels And Colors if selected
if sidebar_option == "Drawing: Labels And Colors":
display_labels_and_colors()
# Function to display Drawing: House With 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":
# Create the house graph and explicitly set positions
G = nx.house_graph()
pos = {0: (0, 0), 1: (1, 0), 2: (0, 1), 3: (1, 1), 4: (0.5, 2.0)}
# Plot nodes with different properties for the "wall" and "roof" nodes
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)
# Customize axes
ax = plt.gca()
ax.margins(0.11)
plt.tight_layout()
plt.axis("off")
st.pyplot(plt)
elif option == "Create your own":
# Allow the user to specify node positions and colors
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)
# Allow the user to specify colors for wall and roof nodes
wall_color = st.color_picker("Wall color:", "#0000FF")
roof_color = st.color_picker("Roof color:", "#FFA500")
if st.button("Generate"):
# Create the house graph with the specified positions
G_custom = nx.house_graph()
# Plot nodes with user-defined properties for wall and roof nodes
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)
# Customize axes
ax = plt.gca()
ax.margins(0.11)
plt.tight_layout()
plt.axis("off")
st.pyplot(plt)
# Display Drawing: House With Colors if selected
if sidebar_option == "Drawing: House With Colors":
display_house_with_colors()
# Function to display Four Grids visualization for Drawing: Four Grids
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":
# Generate a 4x4 grid graph
G = nx.grid_2d_graph(4, 4) # 4x4 grid
pos = nx.spring_layout(G, iterations=100, seed=39775)
# Create a 2x2 subplot
fig, all_axes = plt.subplots(2, 2)
ax = all_axes.flat
# Draw graphs in 4 different styles
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", # Node surface color
edge_color="tab:gray", # Color of graph edges
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,
)
# Set margins for the axes so that nodes aren't clipped
for a in ax:
a.margins(0.10)
fig.tight_layout()
st.pyplot(fig)
elif option == "Create your own":
# Allow the user to customize the grid dimensions
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"):
# Generate a custom grid graph
G_custom = nx.grid_2d_graph(rows, cols) # Create the grid graph
pos = nx.spring_layout(G_custom, iterations=100, seed=39775)
# Create a 2x2 subplot
fig, all_axes = plt.subplots(2, 2)
ax = all_axes.flat
# Draw graphs in 4 different styles
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", # Node surface color
edge_color="tab:gray", # Color of graph edges
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,
)
# Set margins for the axes so that nodes aren't clipped
for a in ax:
a.margins(0.10)
fig.tight_layout()
st.pyplot(fig)
# Display Drawing: Four Grids if selected
if sidebar_option == "Drawing: Four Grids":
display_four_grids()
# Function to display Eigenvalue analysis for Drawing: Eigenvalues
def display_eigenvalue_analysis():
st.title("Drawing: Eigenvalues")
option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
if option == "Default Example":
# Generate random graph with 1000 nodes and 5000 edges
n = 1000
m = 5000
G = nx.gnm_random_graph(n, m, seed=5040) # Seed for reproducibility
# Calculate the normalized Laplacian matrix
L = nx.normalized_laplacian_matrix(G)
eigenvalues = np.linalg.eigvals(L.toarray())
# Print largest and smallest eigenvalues
st.write(f"Largest eigenvalue: {max(eigenvalues)}")
st.write(f"Smallest eigenvalue: {min(eigenvalues)}")
# Display the histogram of eigenvalues
st.write("### Eigenvalue Histogram")
plt.hist(eigenvalues, bins=100)
plt.xlim(0, 2) # Eigenvalues between 0 and 2
st.pyplot(plt)
elif option == "Create your own":
# Allow the user to customize the number of nodes and edges
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"):
# Generate a random graph with the custom number of nodes and edges
G_custom = nx.gnm_random_graph(n_nodes, m_edges, seed=5040) # Seed for reproducibility
# Calculate the normalized Laplacian matrix
L = nx.normalized_laplacian_matrix(G_custom)
eigenvalues = np.linalg.eigvals(L.toarray())
# Print largest and smallest eigenvalues
st.write(f"Largest eigenvalue: {max(eigenvalues)}")
st.write(f"Smallest eigenvalue: {min(eigenvalues)}")
# Display the histogram of eigenvalues
st.write("### Eigenvalue Histogram")
plt.hist(eigenvalues, bins=100)
plt.xlim(0, 2) # Eigenvalues between 0 and 2
st.pyplot(plt)
# Display Drawing: Eigenvalues if selected
if sidebar_option == "Drawing: Eigenvalues":
display_eigenvalue_analysis()
# Function to display properties and graph for Basic: Properties
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)}")
# Visualize the graph
st.write("### Graph Visualization")
pos = nx.spring_layout(G, seed=3068) # Seed layout for reproducibility
draw_graph(G, pos)
# Function to display graph for Basic: Read and write graphs
def display_read_write_graph(G):
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=":") # Save edge list
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
draw_graph(H, pos)
# 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)
# Function to display Simple Directed Graphs for Basic: Simple graph Directed
def display_simple_directed_graph(G, pos=None):
options = {
"node_size": 500,
"node_color": "lightblue",
"arrowsize": 20,
"width": 2,
"edge_color": "gray",
}
# Draw the directed graph with the given positions and options
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)
# Function to display Custom Node Position Graphs for Drawing: Custom Node Position
def display_custom_node_position():
st.title("Drawing: Custom Node Position")
# Default example graph (path graph with custom node position)
G = nx.path_graph(20)
center_node = 5
edge_nodes = set(G) - {center_node}
# Ensure the nodes around the circle are evenly distributed
pos = nx.circular_layout(G.subgraph(edge_nodes))
pos[center_node] = np.array([0, 0]) # Manually specify node position
# Draw the graph
draw_graph(G, pos)
# Function to display Cluster Layout for Drawing: Cluster Layout
def display_cluster_layout():
st.title("Drawing: Cluster Layout")
G = nx.davis_southern_women_graph() # Example graph
communities = nx.community.greedy_modularity_communities(G)
# Compute positions for the node clusters as if they were themselves nodes in a supergraph using a larger scale factor
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)
# Function to display Degree Analysis for Drawing: Degree Analysis
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))
# Create a gridspec for adding subplots of different sizes
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))
# Create a gridspec for adding subplots of different sizes
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)
# Function to display Ego Graph for Drawing: Ego Graph
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":
# Create a BA model graph - use seed for reproducibility
n = 1000
m = 2
seed = 20532
G = nx.barabasi_albert_graph(n, m, seed=seed)
# Find node with largest degree
node_and_degree = G.degree()
(largest_hub, degree) = sorted(node_and_degree, key=itemgetter(1))[-1]
# Create ego graph of main hub
hub_ego = nx.ego_graph(G, largest_hub)
# Draw graph
pos = nx.spring_layout(hub_ego, seed=seed) # Seed layout for reproducibility
nx.draw(hub_ego, pos, node_color="b", node_size=50, with_labels=False)
# Draw ego as large and red
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)
# Find node with largest degree
node_and_degree = G_custom.degree()
(largest_hub, degree) = sorted(node_and_degree, key=itemgetter(1))[-1]
# Create ego graph of main hub
hub_ego = nx.ego_graph(G_custom, largest_hub)
# Draw graph
pos = nx.spring_layout(hub_ego, seed=20532) # Seed layout for reproducibility
nx.draw(hub_ego, pos, node_color="b", node_size=50, with_labels=False)
# Draw ego as large and red
options = {"node_size": 300, "node_color": "r"}
nx.draw_networkx_nodes(hub_ego, pos, nodelist=[largest_hub], **options)
plt.tight_layout()
st.pyplot(plt)
# Display Drawing: Ego Graph if selected
if sidebar_option == "Drawing: Ego Graph":
display_ego_graph()
# Display Basic: Properties if selected
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)
# 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"))
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)
# 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"))
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)
# Display Basic: Simple Directed Graph if selected
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)
# Display Drawing: Custom Node Position if selected
elif sidebar_option == "Drawing: Custom Node Position":
display_custom_node_position()
# Display Drawing: Cluster Layout if selected
elif sidebar_option == "Drawing: Cluster Layout":
display_cluster_layout()
# Display Drawing: Degree Analysis if selected
elif sidebar_option == "Drawing: Degree Analysis":
display_degree_analysis()