siyuansc commited on
Commit
055ca22
1 Parent(s): 3ee5a79

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +270 -39
app.py CHANGED
@@ -15,14 +15,14 @@ pn.extension('vega')
15
  events={}
16
  nations = ['Italy','England','Germany','France','Spain','European_Championship','World_Cup']
17
  for nation in nations:
18
- with open('events/events_%s.json' %nation) as json_data:
19
  events[nation] = json.load(json_data)
20
 
21
  # loading the match data
22
  matches={}
23
  nations = ['Italy','England','Germany','France','Spain','European_Championship','World_Cup']
24
  for nation in nations:
25
- with open('matches/matches_%s.json' %nation) as json_data:
26
  matches[nation] = json.load(json_data)
27
 
28
  # loading the players data
@@ -34,8 +34,7 @@ with open('players.json') as json_data:
34
  competitions={}
35
  with open('competitions.json') as json_data:
36
  competitions = json.load(json_data)
37
-
38
- ev_all_nations = []
39
  for nation in nations:
40
  for i in range(len(events[nation])):
41
  ev_all_nations.append(events[nation][i]['eventName'])
@@ -85,70 +84,302 @@ chart1 = alt.layer(bars, average_rule, average_text).properties(
85
  # Display the combined chart
86
  chart1
87
 
88
- match_ev_count = {}
 
89
  for nation in nations:
90
  for ev in events[nation]:
91
- if ev['matchId'] not in match_ev_count:
92
- match_ev_count[ev['matchId']] = 1
93
- else:
94
- match_ev_count[ev['matchId']] += 1
 
 
 
 
 
95
 
96
- data = pd.DataFrame({
97
- 'Event Count': list(match_ev_count.values())
 
 
 
98
  })
99
 
100
- event_count_values = list(match_ev_count.values())
101
- min_value = min(event_count_values)
102
- max_value = max(event_count_values)
 
 
 
 
 
 
103
 
104
 
105
- ticks = list(range((min_value // 200) * 200, (max_value // 200 + 1) * 200, 200))
 
 
 
 
 
 
 
 
106
 
107
- click = alt.selection_single(encodings=['x'], nearest=True)
108
 
109
- hist = alt.Chart(data).mark_bar().encode(
110
- alt.X('Event Count:Q', bin=alt.Bin(maxbins=20), title='events (n)', axis=alt.Axis(values=ticks)),
111
- alt.Y('count()', title='frequency (n)'),
112
- tooltip=[alt.Tooltip('mean(Event Count):Q', title='Mean', format='.2f')]
113
- ).properties(
114
- width=600,
115
- height=400
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  ).add_selection(
117
- click
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  )
119
 
120
- mean_rule = alt.Chart(data).transform_filter(
121
- click
122
- ).mark_rule(color='firebrick', size=3).encode(
123
- x='mean(Event Count):Q',
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  )
125
 
126
- chart2 = alt.layer(hist, mean_rule).properties(
127
- title='Histogram of Event Counts with Click Interaction and Tooltip'
 
 
128
  )
129
 
130
- chart2
131
 
132
- combined_chart1 = alt.hconcat(
133
- chart1,
134
- chart2,
135
  spacing=10
136
  ).resolve_scale(
137
  color='independent'
138
  )
139
- combined_chart1
140
 
141
 
142
  chart1_panel = pn.pane.Vega(chart1, sizing_mode='stretch_width')
143
- chart2_panel = pn.pane.Vega(chart2, sizing_mode='stretch_width')
144
- combined_chart1_panel = pn.pane.Vega(combined_chart1, sizing_mode='stretch_width')
145
 
146
 
147
  dashboard = pn.Column(
148
  "# My Interactive Dashboard", # 可以添加标题
149
  chart1_panel,
150
- chart2_panel,
151
- combined_chart1_panel
152
  )
153
 
154
  # 设置应用程序为可服务的
 
15
  events={}
16
  nations = ['Italy','England','Germany','France','Spain','European_Championship','World_Cup']
17
  for nation in nations:
18
+ with open('./events_%s.json' %nation) as json_data:
19
  events[nation] = json.load(json_data)
20
 
21
  # loading the match data
22
  matches={}
23
  nations = ['Italy','England','Germany','France','Spain','European_Championship','World_Cup']
24
  for nation in nations:
25
+ with open('./matches_%s.json' %nation) as json_data:
26
  matches[nation] = json.load(json_data)
27
 
28
  # loading the players data
 
34
  competitions={}
35
  with open('competitions.json') as json_data:
36
  competitions = json.load(json_data)
37
+ ev_all_nations = []
 
38
  for nation in nations:
39
  for i in range(len(events[nation])):
40
  ev_all_nations.append(events[nation][i]['eventName'])
 
84
  # Display the combined chart
85
  chart1
86
 
87
+ match_id = 2576335
88
+ a_match = []
89
  for nation in nations:
90
  for ev in events[nation]:
91
+ if ev['matchId'] == match_id:
92
+ a_match.append(ev)
93
+
94
+ for nation in nations:
95
+ for match in matches[nation]:
96
+ if match['wyId'] == match_id:
97
+ match_f = match
98
+
99
+ df_a_match = pd.DataFrame(a_match)
100
 
101
+ background_data = pd.DataFrame({
102
+ 'x': [0],
103
+ 'y': [0],
104
+ 'x2': [100],
105
+ 'y2': [100]
106
  })
107
 
108
+ # Create the background
109
+ background = alt.Chart(background_data).mark_rect(
110
+ color='#195905'
111
+ ).encode(
112
+ x='x:Q',
113
+ y='y:Q',
114
+ x2='x2:Q',
115
+ y2='y2:Q'
116
+ )
117
 
118
 
119
+ #Define the center circle
120
+ center_circle = alt.Chart(pd.DataFrame({'x': [50], 'y': [50]})).mark_point(
121
+ size=12000,
122
+ color='white',
123
+ strokeWidth=3
124
+ ).encode(
125
+ x='x:Q',
126
+ y='y:Q'
127
+ )
128
 
 
129
 
130
+ # Create the border lines
131
+ border_lines_data = pd.DataFrame({
132
+ 'x': [1, 1, 99.5, 99.5, 1],
133
+ 'y': [1, 99.5, 99.5, 1, 1],
134
+ 'x2': [1, 99.5, 99.5, 1, 1],
135
+ 'y2': [99.5, 99.5, 1, 1, 1]
136
+ })
137
+
138
+
139
+ border_lines = alt.Chart(border_lines_data).mark_line(
140
+ color='white',
141
+ strokeWidth=3
142
+ ).encode(
143
+ x=alt.X('x:Q', scale=alt.Scale(domain=[1, 99.5])),
144
+ y=alt.Y('y:Q', scale=alt.Scale(domain=[1, 99.5])),
145
+ x2='x2:Q',
146
+ y2='y2:Q'
147
+ )
148
+
149
+ midline_data = pd.DataFrame({
150
+ 'x': [50, 50,],
151
+ 'y': [1, 99, ]
152
+ })
153
+
154
+ # Create the line using `mark_line`
155
+ midline = alt.Chart(midline_data).mark_line(
156
+ color='white',
157
+ strokeWidth=3
158
+ ).encode(
159
+ x='x:Q',
160
+ y='y:Q'
161
+ )
162
+ lines_data = pd.DataFrame({
163
+ 'x': [1, 17.5, 17.5, 1, 82.5, 82.5, 99,1,6.5,6.5,1, 99,93.5,93.5],
164
+ 'y': [21.3, 21.3, 77.7, 77.7, 21.3, 77.7, 77.7,37.5,37.5,62.5,62.5,37.5,37.5,62.5],
165
+ 'x2': [17.5, 17.5, 1, 17.5, 99, 82.5, 82.5, 6.5,6.5,1,6.5,93.5,93.5,99],
166
+ 'y2': [21.3, 77.7, 77.7, 77.7, 21.3, 21.3,77.7,37.5,62.5,62.5,62.5,37.5,62.5,62.5]
167
+ })
168
+
169
+ lines = alt.Chart(lines_data).mark_line(
170
+ color='white',
171
+ strokeWidth=3
172
+ ).encode(
173
+ x='x:Q',
174
+ y='y:Q',
175
+ x2='x2:Q',
176
+ y2='y2:Q'
177
+ )
178
+
179
+ dot_positions = pd.DataFrame({
180
+ 'x': [12, 87],
181
+ 'y': [50, 50]
182
+ })
183
+
184
+ # Create the white dots
185
+ white_dots = alt.Chart(dot_positions).mark_point(
186
+ size=100,
187
+ color='white',
188
+ filled=True
189
+ ).encode(
190
+ x='x:Q',
191
+ y='y:Q'
192
+ )
193
+
194
+
195
+
196
+ theta = np.linspace(0, np.pi, 100)
197
+ semicircle_x = 12 + 9.5 * np.cos(theta)
198
+ semicircle_y = 50 + 9.5 * np.sin(theta)
199
+
200
+ semicircle_data = pd.DataFrame({
201
+ 'x': semicircle_x,
202
+ 'y': semicircle_y
203
+ })
204
+
205
+ semicircle_data = semicircle_data[semicircle_data['x'] >= 17.5]
206
+
207
+ arc1 = alt.Chart(semicircle_data).mark_line(
208
+ color='white',
209
+ strokeWidth=3
210
+ ).encode(
211
+ x=alt.X('x', scale=alt.Scale(domain=[0, 100])),
212
+ y=alt.Y('y', scale=alt.Scale(domain=[0, 100]))
213
+ )
214
+
215
+
216
+
217
+ theta = np.linspace(0, np.pi, 100)
218
+ semicircle_x2 = 12 + 9.5 * np.cos(theta)
219
+ semicircle_y2 = 50 - 9.5 * np.sin(theta)
220
+
221
+ semicircle_data2 = pd.DataFrame({
222
+ 'x': semicircle_x2,
223
+ 'y': semicircle_y2
224
+ })
225
+
226
+
227
+ semicircle_data2 = semicircle_data2[semicircle_data2['x'] >= 17.5]
228
+
229
+
230
+ arc2 = alt.Chart(semicircle_data2).mark_line(
231
+ color='white',
232
+ strokeWidth=3
233
+ ).encode(
234
+ x=alt.X('x', scale=alt.Scale(domain=[0, 100])),
235
+ y=alt.Y('y', scale=alt.Scale(domain=[0, 100]))
236
+ )
237
+
238
+
239
+ theta = np.linspace(0, np.pi, 100)
240
+ semicircle_x3 = 87 - 9.5 * np.cos(theta)
241
+ semicircle_y3 = 50 + 9.5 * np.sin(theta)
242
+
243
+
244
+ semicircle_data3 = pd.DataFrame({
245
+ 'x': semicircle_x3,
246
+ 'y': semicircle_y3
247
+ })
248
+
249
+
250
+ semicircle_data3 = semicircle_data3[semicircle_data3['x'] <= 82.5]
251
+
252
+
253
+ arc3 = alt.Chart(semicircle_data3).mark_line(
254
+ color='white',
255
+ strokeWidth=3
256
+ ).encode(
257
+ x=alt.X('x', scale=alt.Scale(domain=[0, 100])),
258
+ y=alt.Y('y', scale=alt.Scale(domain=[0, 100]))
259
+ )
260
+
261
+
262
+
263
+ theta = np.linspace(0, np.pi, 100)
264
+ semicircle_x4 = 87 - 9.5 * np.cos(theta)
265
+ semicircle_y4 = 50 - 9.5 * np.sin(theta)
266
+
267
+ semicircle_data4 = pd.DataFrame({
268
+ 'x': semicircle_x4,
269
+ 'y': semicircle_y4
270
+ })
271
+
272
+ semicircle_data4 = semicircle_data4[semicircle_data4['x'] <= 82.5]
273
+
274
+ arc4 = alt.Chart(semicircle_data4).mark_line(
275
+ color='white',
276
+ strokeWidth=3
277
+ ).encode(
278
+ x=alt.X('x', scale=alt.Scale(domain=[0, 100]), title=None ),
279
+ y=alt.Y('y', scale=alt.Scale(domain=[0, 100]), title=None)
280
+ )
281
+
282
+
283
+ df_a_match['x'] = [pos[0]['x'] for pos in df_a_match['positions']]
284
+ df_a_match['y'] = [pos[0]['y'] for pos in df_a_match['positions']]
285
+
286
+
287
+ # brush2 = alt.selection_interval(
288
+ # on="[mousedown[event.shiftKey], mouseup] > mousemove",
289
+ # translate="[mousedown[event.shiftKey], mouseup] > mousemove!",
290
+ # )
291
+
292
+ brush2 = alt.selection(type='interval', encodings=['x', 'y'])
293
+
294
+ team_event = alt.Chart(df_a_match).mark_point(
295
+ size=50,
296
+ opacity=1,
297
+ filled=True
298
+ ).encode(
299
+ x=alt.X('x:Q', axis=alt.Axis(labels=False, ticks=False, grid=False)),
300
+ y=alt.Y('y:Q', axis=alt.Axis(labels=False, ticks=False, grid=False)),
301
+ color=alt.condition(brush2,
302
+ alt.Color('teamId:N', legend=None, scale=alt.Scale(domain=list(df_a_match['teamId'].unique()), range=['black', 'cyan'])),
303
+ alt.value('lightgray')),
304
+ tooltip=['eventName:N', 'teamId:N', 'x:Q', 'y:Q']
305
  ).add_selection(
306
+ brush2
307
+ )
308
+
309
+
310
+ zoom = alt.selection_interval(
311
+ bind='scales',
312
+ on="[mousedown[!event.shiftKey], mouseup] > mousemove",
313
+ translate="[mousedown[!event.shiftKey], mouseup] > mousemove!",
314
+ )
315
+
316
+
317
+
318
+ soccer_pitch = alt.layer(background, border_lines, midline, lines, white_dots, arc1, arc2, arc3, arc4, center_circle, team_event).properties(
319
+ width=700,
320
+ height=440,
321
+ title="Lazio - Internazionale, 2 - 3"
322
+ )
323
+
324
+
325
+ soccer_pitch = soccer_pitch.add_selection(
326
+ zoom,
327
+ )
328
+
329
+
330
+
331
+ bars = alt.Chart(df_a_match).mark_bar().encode(
332
+ y=alt.Y('eventName:N', sort='-x', title=None),
333
+ x=alt.X('count():Q', title='frequency'),
334
+ color=alt.Color('eventName:N',legend=None)
335
+ ).transform_filter(
336
+ brush2
337
  )
338
 
339
+
340
+ annotations_df = pd.DataFrame({
341
+ 'text': ['You can select part of the graph to see distributoon of events'],
342
+ 'x': [0],
343
+ 'y': [0]
344
+ })
345
+
346
+ annotations_chart = alt.Chart(annotations_df).mark_text(
347
+ align='left',
348
+ baseline='middle',
349
+ fontSize=12,
350
+ fontStyle='italic'
351
+ ).encode(
352
+ text='text:N'
353
+ ).properties(
354
+ width=700,
355
+ height=20
356
  )
357
 
358
+ soccer_pitch_with_annotations = alt.vconcat(
359
+ soccer_pitch,
360
+ annotations_chart,
361
+ spacing=5
362
  )
363
 
 
364
 
365
+ combined_chart2 = alt.hconcat(
366
+ soccer_pitch_with_annotations,
367
+ bars,
368
  spacing=10
369
  ).resolve_scale(
370
  color='independent'
371
  )
372
+
373
 
374
 
375
  chart1_panel = pn.pane.Vega(chart1, sizing_mode='stretch_width')
376
+ combined_chart1_panel = pn.pane.Vega(combined_chart2, sizing_mode='stretch_width')
 
377
 
378
 
379
  dashboard = pn.Column(
380
  "# My Interactive Dashboard", # 可以添加标题
381
  chart1_panel,
382
+ combined_chart2_panel
 
383
  )
384
 
385
  # 设置应用程序为可服务的