shukdevdatta123 commited on
Commit
2b5132f
·
verified ·
1 Parent(s): c6e0851

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -100
app.py CHANGED
@@ -1,14 +1,13 @@
1
  import streamlit as st
2
- import matplotlib.pyplot as plt
3
  import networkx as nx
4
- import bz2
5
 
6
  # Sidebar for selecting an option
7
  sidebar_option = st.sidebar.radio("Select an option",
8
  ["Select an option", "Basic: Properties",
9
  "Basic: Read and write graphs", "Basic: Simple graph",
10
  "Basic: Simple graph Directed", "Drawing: Custom Node Position",
11
- "Drawing: Chess Masters"])
12
 
13
  # Helper function to draw and display graph
14
  def draw_graph(G, pos=None, title="Graph Visualization", edgewidth=None, nodesize=None):
@@ -50,111 +49,60 @@ def draw_graph(G, pos=None, title="Graph Visualization", edgewidth=None, nodesiz
50
  plt.axis("off")
51
  st.pyplot(plt)
52
 
 
 
 
53
 
54
- def chess_pgn_graph(pgn_file="chess_masters_WCC.pgn.bz2"):
55
- """Read chess games in pgn format in pgn_file.
56
-
57
- Filenames ending in .bz2 will be uncompressed.
58
-
59
- Return the MultiDiGraph of players connected by a chess game.
60
- Edges contain game data in a dict.
61
- """
62
- G = nx.MultiDiGraph()
63
- game = {}
64
- with bz2.BZ2File(pgn_file) as datafile:
65
- lines = [line.decode().rstrip("\r\n") for line in datafile]
66
- for line in lines:
67
- if line.startswith("["):
68
- tag, value = line[1:-1].split(" ", 1)
69
- game[str(tag)] = value.strip('"')
70
- else:
71
- if game:
72
- white = game.pop("White")
73
- black = game.pop("Black")
74
- G.add_edge(white, black, **game)
75
- game = {}
76
- return G
77
 
 
 
78
 
79
- # Draw Chess Masters Graph (the main section)
80
- def display_chess_masters_graph():
81
- st.title("Drawing: Chess Masters")
82
 
83
- option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
 
 
84
 
85
- if option == "Default Example":
86
- G = chess_pgn_graph("chess_masters_WCC.pgn.bz2")
87
-
88
- # identify connected components of the undirected version
89
- H = G.to_undirected()
90
- Gcc = [H.subgraph(c) for c in nx.connected_components(H)]
91
- if len(Gcc) > 1:
92
- st.write(f"Note the disconnected component consisting of:\n{Gcc[1].nodes()}")
93
-
94
- # find all games with B97 opening (as described in ECO)
95
- openings = {game_info["ECO"] for (white, black, game_info) in G.edges(data=True)}
96
- st.write(f"\nFrom a total of {len(openings)} different openings,")
97
- st.write("the following games used the Sicilian opening")
98
- st.write('with the Najdorff 7...Qb6 "Poisoned Pawn" variation.\n')
99
-
100
- for white, black, game_info in G.edges(data=True):
101
- if game_info["ECO"] == "B97":
102
- summary = f"{white} vs {black}\n"
103
- for k, v in game_info.items():
104
- summary += f" {k}: {v}\n"
105
- summary += "\n"
106
- st.write(summary)
107
-
108
- # Create undirected graph H without multi-edges
109
- H = nx.Graph(G)
110
-
111
- # Edge width is proportional to number of games played
112
- edgewidth = [len(G.get_edge_data(u, v)) for u, v in H.edges()]
113
-
114
- # Node size is proportional to number of games won
115
- wins = dict.fromkeys(G.nodes(), 0.0)
116
- for u, v, d in G.edges(data=True):
117
- r = d["Result"].split("-")
118
- if r[0] == "1":
119
- wins[u] += 1.0
120
- elif r[0] == "1/2":
121
- wins[u] += 0.5
122
- wins[v] += 0.5
123
- else:
124
- wins[v] += 1.0
125
- nodesize = [wins[v] * 50 for v in H]
126
-
127
- # Generate layout for visualization
128
- pos = nx.kamada_kawai_layout(H)
129
-
130
- # Manually tweak some positions to avoid label overlap
131
- pos["Reshevsky, Samuel H"] += (0.05, -0.10)
132
- pos["Botvinnik, Mikhail M"] += (0.03, -0.06)
133
- pos["Smyslov, Vassily V"] += (0.05, -0.03)
134
-
135
- # Draw the graph
136
- draw_graph(H, pos, title="World Chess Championship Games: 1886 - 1985", edgewidth=edgewidth, nodesize=nodesize)
137
 
138
  elif option == "Create your own":
139
- uploaded_file = st.file_uploader("Upload your own PGN file", type="pgn")
140
  if uploaded_file is not None:
141
- G_custom = chess_pgn_graph(uploaded_file)
142
- # Identify connected components and draw the graph for the uploaded data
143
- H_custom = G_custom.to_undirected()
144
- edgewidth = [len(G_custom.get_edge_data(u, v)) for u, v in H_custom.edges()]
145
- wins = dict.fromkeys(G_custom.nodes(), 0.0)
146
- for u, v, d in G_custom.edges(data=True):
147
- r = d["Result"].split("-")
148
- if r[0] == "1":
149
- wins[u] += 1.0
150
- elif r[0] == "1/2":
151
- wins[u] += 0.5
152
- wins[v] += 0.5
153
- else:
154
- wins[v] += 1.0
155
- nodesize = [wins[v] * 50 for v in H_custom]
156
- pos_custom = nx.kamada_kawai_layout(H_custom)
157
- draw_graph(H_custom, pos_custom, title="Custom Chess Game Graph", edgewidth=edgewidth, nodesize=nodesize)
 
 
 
 
158
 
159
  # Display other sections
160
  def display_basic_properties():
@@ -260,5 +208,7 @@ elif sidebar_option == "Drawing: Custom Node Position":
260
  display_custom_node_position()
261
  elif sidebar_option == "Drawing: Chess Masters":
262
  display_chess_masters_graph()
 
 
263
  else:
264
  st.write("Please select a valid option from the sidebar.")
 
1
  import streamlit as st
 
2
  import networkx as nx
3
+ import matplotlib.pyplot as plt
4
 
5
  # Sidebar for selecting an option
6
  sidebar_option = st.sidebar.radio("Select an option",
7
  ["Select an option", "Basic: Properties",
8
  "Basic: Read and write graphs", "Basic: Simple graph",
9
  "Basic: Simple graph Directed", "Drawing: Custom Node Position",
10
+ "Drawing: Chess Masters", "Drawing: Cluster Layout"])
11
 
12
  # Helper function to draw and display graph
13
  def draw_graph(G, pos=None, title="Graph Visualization", edgewidth=None, nodesize=None):
 
49
  plt.axis("off")
50
  st.pyplot(plt)
51
 
52
+ # Drawing: Cluster Layout
53
+ def display_cluster_layout():
54
+ st.title("Drawing: Cluster Layout")
55
 
56
+ option = st.radio("Choose a graph type:", ("Default Example", "Create your own"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
+ if option == "Default Example":
59
+ G = nx.davis_southern_women_graph()
60
 
61
+ # Compute communities using greedy modularity community detection
62
+ communities = nx.community.greedy_modularity_communities(G)
 
63
 
64
+ # Compute positions for the node clusters as if they were themselves nodes in a supergraph
65
+ supergraph = nx.cycle_graph(len(communities))
66
+ superpos = nx.spring_layout(G, scale=50, seed=429)
67
 
68
+ # Use the "supernode" positions as the center of each node cluster
69
+ centers = list(superpos.values())
70
+ pos = {}
71
+ for center, comm in zip(centers, communities):
72
+ pos.update(nx.spring_layout(nx.subgraph(G, comm), center=center, seed=1430))
73
+
74
+ # Nodes colored by cluster
75
+ for nodes, clr in zip(communities, ("tab:blue", "tab:orange", "tab:green")):
76
+ nx.draw_networkx_nodes(G, pos=pos, nodelist=nodes, node_color=clr, node_size=100)
77
+ nx.draw_networkx_edges(G, pos=pos)
78
+
79
+ plt.tight_layout()
80
+ st.pyplot(plt)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
  elif option == "Create your own":
83
+ uploaded_file = st.file_uploader("Upload your own graph file (in GML format)", type="gml")
84
  if uploaded_file is not None:
85
+ G_custom = nx.read_gml(uploaded_file)
86
+ # Compute communities using greedy modularity community detection
87
+ communities = nx.community.greedy_modularity_communities(G_custom)
88
+
89
+ # Compute positions for the node clusters as if they were themselves nodes in a supergraph
90
+ supergraph = nx.cycle_graph(len(communities))
91
+ superpos = nx.spring_layout(G_custom, scale=50, seed=429)
92
+
93
+ # Use the "supernode" positions as the center of each node cluster
94
+ centers = list(superpos.values())
95
+ pos = {}
96
+ for center, comm in zip(centers, communities):
97
+ pos.update(nx.spring_layout(nx.subgraph(G_custom, comm), center=center, seed=1430))
98
+
99
+ # Nodes colored by cluster
100
+ for nodes, clr in zip(communities, ("tab:blue", "tab:orange", "tab:green")):
101
+ nx.draw_networkx_nodes(G_custom, pos=pos, nodelist=nodes, node_color=clr, node_size=100)
102
+ nx.draw_networkx_edges(G_custom, pos=pos)
103
+
104
+ plt.tight_layout()
105
+ st.pyplot(plt)
106
 
107
  # Display other sections
108
  def display_basic_properties():
 
208
  display_custom_node_position()
209
  elif sidebar_option == "Drawing: Chess Masters":
210
  display_chess_masters_graph()
211
+ elif sidebar_option == "Drawing: Cluster Layout":
212
+ display_cluster_layout()
213
  else:
214
  st.write("Please select a valid option from the sidebar.")