wsba-hockey 1.1.8__py3-none-any.whl → 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. wsba_hockey/__init__.py +22 -1
  2. wsba_hockey/tools/scraping.py +166 -190
  3. wsba_hockey/tools/utils/__init__.py +0 -1
  4. wsba_hockey/tools/utils/shared.py +14 -389
  5. wsba_hockey/tools/xg_model.py +6 -1
  6. wsba_hockey/wsba_main.py +330 -20
  7. {wsba_hockey-1.1.8.dist-info → wsba_hockey-1.2.0.dist-info}/METADATA +16 -15
  8. wsba_hockey-1.2.0.dist-info/RECORD +15 -0
  9. wsba_hockey/api/api/index.py +0 -162
  10. wsba_hockey/data_pipelines.py +0 -247
  11. wsba_hockey/evidence/weakside-breakout/node_modules/duckdb/vendor.py +0 -146
  12. wsba_hockey/evidence/weakside-breakout/node_modules/flatted/python/flatted.py +0 -149
  13. wsba_hockey/evidence/weakside-breakout/node_modules/flatted/python/test.py +0 -63
  14. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/gyp_main.py +0 -45
  15. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py +0 -367
  16. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py +0 -206
  17. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py +0 -1270
  18. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py +0 -1547
  19. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py +0 -59
  20. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py +0 -153
  21. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py +0 -271
  22. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py +0 -574
  23. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/__init__.py +0 -690
  24. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/common.py +0 -661
  25. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/common_test.py +0 -78
  26. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py +0 -165
  27. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py +0 -109
  28. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py +0 -55
  29. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/__init__.py +0 -0
  30. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py +0 -808
  31. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py +0 -1173
  32. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py +0 -1321
  33. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py +0 -120
  34. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py +0 -103
  35. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py +0 -464
  36. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py +0 -89
  37. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py +0 -58
  38. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py +0 -2714
  39. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py +0 -3981
  40. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py +0 -44
  41. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py +0 -2936
  42. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py +0 -55
  43. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py +0 -1394
  44. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py +0 -25
  45. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/input.py +0 -3130
  46. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/input_test.py +0 -98
  47. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py +0 -771
  48. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py +0 -1271
  49. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py +0 -174
  50. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py +0 -61
  51. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py +0 -374
  52. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py +0 -1939
  53. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py +0 -302
  54. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py +0 -3197
  55. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py +0 -65
  56. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/test_gyp.py +0 -261
  57. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/graphviz.py +0 -102
  58. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/pretty_gyp.py +0 -156
  59. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/pretty_sln.py +0 -181
  60. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/pretty_vcproj.py +0 -339
  61. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/test/fixtures/test-charmap.py +0 -31
  62. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/update-gyp.py +0 -64
  63. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/gyp_main.py +0 -45
  64. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py +0 -367
  65. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py +0 -206
  66. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py +0 -1270
  67. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py +0 -1547
  68. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py +0 -59
  69. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py +0 -153
  70. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py +0 -271
  71. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py +0 -574
  72. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/__init__.py +0 -666
  73. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/common.py +0 -654
  74. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/common_test.py +0 -78
  75. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py +0 -165
  76. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py +0 -109
  77. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py +0 -55
  78. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/__init__.py +0 -0
  79. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py +0 -808
  80. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py +0 -1173
  81. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py +0 -1321
  82. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py +0 -120
  83. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py +0 -103
  84. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py +0 -464
  85. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py +0 -89
  86. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py +0 -58
  87. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py +0 -2518
  88. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py +0 -3978
  89. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py +0 -44
  90. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py +0 -2936
  91. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py +0 -55
  92. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py +0 -1394
  93. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py +0 -25
  94. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/input.py +0 -3137
  95. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/input_test.py +0 -98
  96. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py +0 -771
  97. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py +0 -1271
  98. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py +0 -174
  99. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py +0 -61
  100. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py +0 -374
  101. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py +0 -1939
  102. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py +0 -302
  103. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py +0 -3197
  104. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py +0 -65
  105. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/setup.py +0 -42
  106. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/test_gyp.py +0 -260
  107. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/graphviz.py +0 -102
  108. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_gyp.py +0 -156
  109. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_sln.py +0 -181
  110. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_vcproj.py +0 -339
  111. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/test/fixtures/test-charmap.py +0 -31
  112. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/update-gyp.py +0 -46
  113. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/duos/app.py +0 -210
  114. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/duos/calc.py +0 -163
  115. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/game_stats/app.py +0 -401
  116. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/game_stats/name_fix.py +0 -47
  117. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/goalie/app.py +0 -101
  118. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/goalie/plot.py +0 -71
  119. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/goalie/rink_plot.py +0 -245
  120. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/app.py +0 -108
  121. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/plot.py +0 -95
  122. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/rink_plot.py +0 -245
  123. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/line-combos/app.py +0 -245
  124. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/line-combos/plot.py +0 -275
  125. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/line-combos/rink_plot.py +0 -245
  126. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/app.py +0 -145
  127. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/plot.py +0 -79
  128. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/rink_plot.py +0 -245
  129. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/app.py +0 -406
  130. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/plot.py +0 -79
  131. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/rink_plot.py +0 -245
  132. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/app.py +0 -110
  133. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/plot.py +0 -59
  134. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/rink_plot.py +0 -245
  135. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/team_heatmaps/app.py +0 -103
  136. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/team_heatmaps/plot.py +0 -95
  137. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/team_heatmaps/rink_plot.py +0 -245
  138. wsba_hockey/flask/app.py +0 -77
  139. wsba_hockey/tools/utils/config.py +0 -14
  140. wsba_hockey/tools/utils/save_pages.py +0 -133
  141. wsba_hockey/workspace.py +0 -31
  142. wsba_hockey-1.1.8.dist-info/RECORD +0 -148
  143. {wsba_hockey-1.1.8.dist-info → wsba_hockey-1.2.0.dist-info}/WHEEL +0 -0
  144. {wsba_hockey-1.1.8.dist-info → wsba_hockey-1.2.0.dist-info}/licenses/LICENSE +0 -0
  145. {wsba_hockey-1.1.8.dist-info → wsba_hockey-1.2.0.dist-info}/top_level.txt +0 -0
@@ -1,406 +0,0 @@
1
- import pandas as pd
2
- import plotly.express as px
3
- import plot as wsba_plt
4
- import numpy as np
5
- from urllib.parse import *
6
- from shiny import *
7
- from shinywidgets import output_widget, render_widget
8
-
9
- app_ui = ui.page_fluid(
10
- ui.tags.link(
11
- rel='stylesheet',
12
- href='https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap'
13
- ),
14
- ui.tags.style(
15
- """
16
- body {
17
- background-color: #09090b;
18
- color: white;
19
- font-family: 'Bebas Neue', sans-serif;
20
- }
21
-
22
- .custom-input input.form-control,
23
- .custom-input .selectize-control,
24
- .custom-input .selectize-input {
25
- background-color: #09090b !important; /* black background */
26
- color: white !important; /* white font color */
27
- border-radius: 4px;
28
- border: 1px solid #444;
29
- }
30
-
31
- .custom-input .selectize-dropdown,
32
- .custom-input .selectize-dropdown-content {
33
- background-color: #09090b !important;
34
- color: white !important;
35
- }
36
-
37
- .custom-input .selectize-control.multi .item {
38
- background-color: #09090b !important;
39
- color: white !important;
40
- border-radius: 4px;
41
- padding: 2px 6px;
42
- margin: 2px 4px 2px 0;
43
- }
44
-
45
- label.control-label {
46
- color: white !important;
47
- }
48
-
49
- .selectize-control.multi {
50
- width: 300px !important;
51
- }
52
-
53
- .form-row {
54
- display: flex;
55
- gap: 12px;
56
- flex-wrap: wrap;
57
- justify-content: center;
58
- }
59
-
60
- .submit-button {
61
- display: flex;
62
- justify-content: center;
63
- }
64
-
65
- .hide {
66
- display: none;
67
- }
68
-
69
- .table thead tr {
70
- --bs-table-bg: #09090b;
71
- --bs-table-color-state: white;
72
- }
73
-
74
- .table thead tr th {
75
- white-space: nowrap;
76
- text-align: center;
77
- color: white;
78
- background-color: #09090b;
79
- }
80
-
81
- .table tbody tr {
82
- --bs-table-bg: #09090b;
83
- --bs-table-color-state: white;
84
- }
85
-
86
- .table tbody tr td {
87
- white-space: nowrap;
88
- text-align: center;
89
- overflow: hidden;
90
- text-overflow: ellipsis;
91
- color: white;
92
- background-color: #09090b;
93
- }
94
-
95
- .table thead th {
96
- text-align: center !important;
97
- }
98
- """
99
- ),
100
- ui.output_ui('add_filters'),
101
- output_widget("plot_game"),
102
- ui.output_ui('metrics'),
103
- ui.output_ui('timeline_filter'),
104
- ui.output_data_frame("plays"),
105
- output_widget("timelines"),
106
- )
107
-
108
- def server(input, output, session):
109
- query = reactive.Value(None)
110
-
111
- def schedule():
112
- schedule = pd.read_csv('https://weakside-breakout.s3.us-east-2.amazonaws.com/info/schedule.csv')
113
-
114
- return schedule.loc[schedule['gameState'].isin(['OFF','FINAL'])]
115
-
116
- @reactive.Effect
117
- def query_params():
118
- #Retreive query parameters
119
- search = session.input[".clientdata_url_search"]()
120
- q = parse_qs(urlparse(search).query)
121
-
122
- print(q)
123
- #If no input data is provided automatically provide a select game and plot all 5v5 fenwick shots
124
- defaults = {
125
- 'game_id':[str(schedule()['id'].iloc[-1])],
126
- 'event_type':['missed-shot,shot-on-goal,goal'],
127
- 'strength_state':['all'],
128
- 'filters':['false'],
129
- 'table':['false'],
130
- 'title':['true']
131
- }
132
-
133
- for key in defaults.keys():
134
- if key not in q.keys():
135
- q.update({key:defaults[key]})
136
-
137
- query.set(q)
138
-
139
- def active_params():
140
- return query.get() or {}
141
-
142
- @output
143
- @render.ui
144
- def add_filters():
145
- query = active_params()
146
-
147
- games = schedule()
148
-
149
- game_title = games.loc[games['id'].astype(str)==query['game_id'][0],'game_title'].to_list()[0]
150
- date = games.loc[games['id'].astype(str)==query['game_id'][0],'date'].to_list()[0]
151
- all_strengths = ['3v3','3v4','3v5','4v3','4v4','4v5','4v6','5v3','5v4','5v5','5v6','6v4','6v5']
152
- #If filters is true among the url parameters then display the filters with the url params setting the values of the filters
153
- if query['filters'][0] == 'true':
154
- #Iterate through query and parse params with multiple selections
155
- for param in query.keys():
156
- q_string = query[param][0]
157
- query[param] = q_string.split(',')
158
-
159
- return ui.panel_well(
160
- ui.tags.div(
161
- {"class": "form-row custom-input"},
162
- ui.input_date('game_date','Date',value=date),
163
- ui.input_selectize('game_title','Game',{query['game_id'][0]:game_title}),
164
- ui.input_selectize('event_type','Events',['blocked-shot','missed-shot','shot-on-goal','goal','hit','penalty','giveaway','takeaway','faceoff'],selected=query['event_type'],multiple=True),
165
- ui.input_selectize('strength_state','Strengths',all_strengths,selected=(all_strengths if query['strength_state'][0]=='all' else query['strength_state']),multiple=True),
166
- ),
167
- ui.tags.div(
168
- {"class": "submit-button"},
169
- ui.input_action_button('submit','Submit')
170
- )
171
- )
172
- else:
173
- return ui.input_action_button('submit','Submit',class_='hide')
174
-
175
- @reactive.effect
176
- @reactive.event(input.game_date)
177
- def update_games():
178
- query = active_params()
179
- if query['filters'][0] == 'true':
180
- games = schedule()
181
-
182
- date_games = games.loc[games['date']==str(input.game_date())].set_index('id')['game_title'].to_dict()
183
- ui.update_selectize(id='game_title',choices=date_games)
184
-
185
- @reactive.calc
186
- def params():
187
- query = active_params()
188
-
189
- #Set params based on filters
190
- if query['filters'][0] == 'true':
191
- query['game_id'] = [str(input.game_title())]
192
- query['event_type'] = [",".join(input.event_type())]
193
- query['strength_state'] = [",".join(input.strength_state())]
194
-
195
- return query
196
- else:
197
- return query
198
-
199
- submitted = reactive.Value(False)
200
-
201
- @reactive.Effect
202
- def startup():
203
- if not submitted.get():
204
- submitted.set(True)
205
-
206
- game_df = reactive.Value(pd.DataFrame())
207
- show_table = reactive.Value(False)
208
- @reactive.effect
209
- @reactive.event(input.submit, submitted)
210
- def ret_game():
211
- query = params()
212
-
213
- #Iterate through query and parse params with multiple selections
214
- #If it is already parsed skip this
215
- for param in query.keys():
216
- if len(query[param])>1:
217
- ''
218
- else:
219
- q_string = query[param][0]
220
- query[param] = q_string.split(',')
221
-
222
- print(query)
223
- #Determine which season to load based on the input game_id
224
- front_year = int(query['game_id'][0][0:4])
225
- season = f'{front_year}{front_year+1}'
226
- #Load appropriate dataframe
227
- df = pd.read_parquet(f'https://weakside-breakout.s3.us-east-2.amazonaws.com/pbp/{season}.parquet')
228
-
229
- #Prepare dataframe for plotting based on URL parameters
230
- game_data = df.loc[df['game_id'].astype(str).isin(query['game_id'])].replace({np.nan: None})
231
- game_data = wsba_plt.prep(game_data,events=query['event_type'],strengths=query['strength_state'])
232
-
233
- game_df.set(game_data)
234
-
235
- if query['table'][0]=='true':
236
- show_table.set(True)
237
-
238
- @output()
239
- @render_widget
240
- @reactive.event(input.submit, submitted)
241
- def plot_game():
242
- #Retreive game
243
- df = game_df.get().copy()
244
-
245
- #Return empty rink if no data exists else continue
246
- if df.empty:
247
- return wsba_plt.wsba_rink()
248
- else:
249
- game_title = df['game_title'].to_list()[0]
250
- print(game_title)
251
- colors = wsba_plt.colors(df)
252
- rink = wsba_plt.wsba_rink()
253
-
254
- plot = px.scatter(df,
255
- x='x', y='y',
256
- size='size',
257
- color='Team',
258
- color_discrete_map=colors,
259
- hover_name='Description',
260
- hover_data=['Event Num.', 'Period', 'Time (in Period)',
261
- 'Strength',
262
- 'Away Score', 'Home Score', 'x', 'y',
263
- 'Event Distance from Attacking Net',
264
- 'Event Angle to Attacking Net',
265
- 'xG'])
266
-
267
- for trace in plot.data:
268
- rink.add_trace(trace)
269
-
270
- if active_params()['title'][0]=='false':
271
- return rink.update_layout(
272
- legend=dict(
273
- orientation='h',
274
- x=0.49,
275
- y=-0.04,
276
- xanchor='center',
277
- yanchor='bottom',
278
- font=dict(color='white')
279
- ),
280
-
281
- hoverlabel=dict(
282
- font_size=10
283
- )
284
- )
285
- else:
286
- return rink.update_layout(
287
- title=dict(
288
- text=game_title,
289
- x=0.5, y=0.94,
290
- xanchor='center',
291
- yanchor='top',
292
- font=dict(color='white')
293
- ),
294
-
295
- legend=dict(
296
- orientation='h',
297
- x=0.49,
298
- y=-0.04,
299
- xanchor='center',
300
- yanchor='bottom',
301
- font=dict(color='white')
302
- ),
303
-
304
- hoverlabel=dict(
305
- font_size=10
306
- )
307
- )
308
-
309
- @output
310
- @render.ui
311
- def metrics():
312
- query = params()
313
- if query['table'][0]=='true':
314
- return ui.tags.div(
315
- {'class':'custom-input'},
316
- ui.input_selectize('metric_select','Metric',['Plays','Timelines'])
317
- )
318
- else:
319
- return None
320
-
321
- @output
322
- @render.ui
323
- @reactive.event(input.metric_select)
324
- def timeline_filter():
325
- if input.metric_select()=='Timelines':
326
- return ui.tags.div(
327
- {'class':'custom-input'},
328
- ui.input_selectize('timeline_select','Timeline',['xG','Fenwick','Shots','Goals'])
329
- )
330
- else:
331
- return None
332
-
333
- @output()
334
- @render.data_frame
335
- @reactive.event(input.submit,input.metric_select)
336
- def plays():
337
- if not show_table.get():
338
- return None
339
- else:
340
- if input.metric_select()=='Timelines':
341
- return None
342
- else:
343
- df = game_df.get().copy()[['event_num','period','Time (in Period)','strength_state','event_type','Description','event_team_abbr','event_player_1_name','shot_type','zone_code','x','y','away_score','home_score','xG']].rename(columns={
344
- 'event_num':'#',
345
- 'period':'Period',
346
- 'strength_state':'Strength State',
347
- 'event_type':'Event',
348
- 'event_team_abbr':'Team',
349
- 'event_player_1_name':'Player',
350
- 'shot_type':'Shot Type',
351
- 'zone_code':'Zone Code',
352
- 'away_score':'Away Score',
353
- 'home_score':'Home Score'
354
- })
355
-
356
- df['xG'] = df['xG'].round(4)
357
- return render.DataTable(df)
358
-
359
- @output()
360
- @render_widget
361
- @reactive.event(input.submit,input.metric_select,input.timeline_select)
362
- def timelines():
363
- if not show_table.get():
364
- return None
365
- else:
366
- if input.metric_select()=='Plays':
367
- return None
368
- else:
369
- data = wsba_plt.timelines(game_df.get().copy())
370
- colors = wsba_plt.colors(data)
371
- timelines = px.line(data,
372
- x='Time (in Period)',
373
- y=input.timeline_select(),
374
- color='Team',
375
- color_discrete_map=colors,
376
- hover_data=['Away Score','Home Score']
377
- )
378
-
379
- timelines.update_traces(
380
- line=dict(
381
- width=4
382
- ))
383
-
384
- return timelines.update_layout(
385
- paper_bgcolor="rgba(0,0,0,0)",
386
- plot_bgcolor="rgba(0,0,0,0)",
387
- font_color='white',
388
- xaxis=dict(title=dict(text='Time (in Period)'),showgrid=False),
389
- yaxis=dict(title=dict(text=input.timeline_select()),showgrid=False),
390
-
391
- legend=dict(
392
- title='Team',
393
- orientation='h',
394
- x=0.5,
395
- y=1,
396
- xanchor='center',
397
- yanchor='top',
398
- font=dict(color='white')
399
- ),
400
-
401
- hoverlabel=dict(
402
- font_size=10
403
- )
404
- )
405
-
406
- app = App(app_ui, server)
@@ -1,79 +0,0 @@
1
- import pandas as pd
2
- import numpy as np
3
- import matplotlib.pyplot as plt
4
- import plotly.graph_objects as go
5
- import rink_plot
6
-
7
- event_markers = {
8
- 'faceoff':'X',
9
- 'hit':'P',
10
- 'blocked-shot':'v',
11
- 'missed-shot':'o',
12
- 'shot-on-goal':'D',
13
- 'goal':'*',
14
- 'giveaway':'1',
15
- 'takeaway':'2',
16
- 'penalty':''
17
- }
18
-
19
- def wsba_rink():
20
- return rink_plot.rink(setting='full', vertical=False)
21
-
22
- def colors(df):
23
- away_abbr = list(df['away_team_abbr'])[0]
24
- home_abbr = list(df['home_team_abbr'])[0]
25
- season = list(df['season'])[0]
26
- team_data = pd.read_csv('https://weakside-breakout.s3.us-east-2.amazonaws.com/info/nhl_teaminfo.csv')
27
-
28
- team_info ={
29
- away_abbr: list(team_data.loc[team_data['WSBA']==f'{away_abbr}{season}','Primary Color'])[0],
30
- home_abbr: list(team_data.loc[team_data['WSBA']==f'{home_abbr}{season}','Primary Color'])[0],
31
- }
32
-
33
- return team_info
34
-
35
- def convert_time(seconds,period):
36
- period_seconds = seconds - ((period-1)*1200)
37
- minutes = int(period_seconds/60)
38
- seconds = int(((period_seconds/60)-minutes)*60)
39
-
40
- return f'{minutes}:{seconds:02}'
41
-
42
- def prep(df,events,strengths):
43
- df = df.loc[(df['event_type'].isin(events))]
44
-
45
- df['strength_state'] = np.where(df['strength_state'].isin(['5v5','5v4','4v5']),df['strength_state'],'Other')
46
- if 'all' not in strengths:
47
- df = df.loc[((df['strength_state'].isin(strengths)))]
48
-
49
- df = df.fillna(0)
50
- df['size'] = np.where(df['xG']<=0,40,df['xG']*400)
51
-
52
- df['marker'] = df['event_type'].replace(event_markers)
53
-
54
- df['Description'] = df['description']
55
- df['Team'] = df['event_team_abbr']
56
- df['Event Num.'] = df['event_num']
57
- df['Period'] = df['period']
58
- df['Time (in seconds)'] = df['seconds_elapsed']
59
- df['Time (in Period)'] = df.apply(lambda x: convert_time(x['Time (in seconds)'],x['Period']), axis=1)
60
- df['Strength'] = df['strength_state']
61
- df['Away Score'] = df['away_score']
62
- df['Home Score'] = df['home_score']
63
- df['x'] = df['x_adj']
64
- df['y'] = df['y_adj']
65
- df['Event Distance from Attacking Net'] = df['event_distance']
66
- df['Event Angle to Attacking Net'] = df['event_angle']
67
- return df
68
-
69
- def timelines(df):
70
- df['Goals'] = np.where(df['event_type']=='goal',1,0)
71
- df['Shots'] = np.where(df['event_type'].isin(['shot-on-goal','goal']),1,0)
72
- df['Fenwick'] = np.where(df['event_type'].isin(['missed-shot','shot-on-goal','goal']),1,0)
73
-
74
- df['xG'] = df.groupby('event_team_abbr')['xG'].cumsum()
75
- df['Goals'] = df.groupby('event_team_abbr')['Goals'].cumsum()
76
- df['Shots'] = df.groupby('event_team_abbr')['Shots'].cumsum()
77
- df['Fenwick'] = df.groupby('event_team_abbr')['Fenwick'].cumsum()
78
-
79
- return df