├── README.md ├── environment.yml ├── LICENSE ├── .gitignore ├── young_outliers.ipynb ├── 02_data_checks.ipynb ├── 06_xa_map.ipynb ├── 01_statsbomb_json_to_feather.ipynb └── demo_crawley.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # statsbomb-explore 2 | Exploring statsbomb data with mplsoccer 3 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: statsbomb-explore 2 | channels: 3 | - anaconda 4 | dependencies: 5 | - jupyter 6 | - pandas 7 | - scipy 8 | - seaborn 9 | - beautifulsoup4 10 | - pyarrow 11 | - scikit-learn 12 | - pillow 13 | - openpyxl 14 | <<<<<<< HEAD 15 | ======= 16 | - pillow 17 | - requests 18 | >>>>>>> 6d5a52dc8abbb526b8433831ca108d0786cbc715 19 | - pip 20 | - pip: 21 | - mplsoccer 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The data are licensed under StatsBomb Public Data User Agreement: https://github.com/statsbomb/open-data/blob/master/LICENSE.pdf. 2 | The code uses the MIT license. 3 | 4 | Code: 5 | MIT License 6 | 7 | Copyright (c) 2020 Andrew Rowlinson 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | 27 | Data: 28 | Please refer to the StatBomb Public Data User Agreement: https://github.com/statsbomb/open-data/blob/master/LICENSE.pdf. 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | 131 | # data folder 132 | data/ 133 | -------------------------------------------------------------------------------- /young_outliers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas as pd\n", 10 | "import numpy as np\n", 11 | "from sklearn.covariance import EmpiricalCovariance" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "df = pd.read_csv('https://raw.githubusercontent.com/mancunian1792/2019_2020_football_analysis/master/data/big5_full_stats.csv')" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "# string to number\n", 30 | "df['playing_minutes'] = pd.to_numeric(df.playing_minutes.str.replace(',', ''))" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "# drop object columns\n", 40 | "df.drop(['per90_matches', 'xg_team_success_matches'], axis=1, inplace=True)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "# keep young players (aged 23 or under playing 900 or greater minutes)\n", 50 | "df = df[(df.age <= 24) & (df.playing_minutes >= 900) & (df.position != 'GK')].copy()" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "# calculate mahalanobis distance and sort dataframe so largest top\n", 60 | "player_values_array = df[df.columns[7:]].values # subset columns with stats\n", 61 | "cov = EmpiricalCovariance().fit(player_values_array)\n", 62 | "df['dist'] = cov.mahalanobis(player_values_array)\n", 63 | "df.sort_values('dist', ascending=False, inplace=True)\n", 64 | "df.reset_index(drop=True, inplace=True)" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "metadata": {}, 71 | "outputs": [], 72 | "source": [ 73 | "#df.head(40)" 74 | ] 75 | } 76 | ], 77 | "metadata": { 78 | "kernelspec": { 79 | "display_name": "Python 3", 80 | "language": "python", 81 | "name": "python3" 82 | }, 83 | "language_info": { 84 | "codemirror_mode": { 85 | "name": "ipython", 86 | "version": 3 87 | }, 88 | "file_extension": ".py", 89 | "mimetype": "text/x-python", 90 | "name": "python", 91 | "nbconvert_exporter": "python", 92 | "pygments_lexer": "ipython3", 93 | "version": "3.8.3" 94 | } 95 | }, 96 | "nbformat": 4, 97 | "nbformat_minor": 4 98 | } 99 | -------------------------------------------------------------------------------- /02_data_checks.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas as pd\n", 10 | "import numpy as np\n", 11 | "import os" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "# Load dataframes" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "DATA_PATH = os.path.join(os.getcwd(),'data')\n", 28 | "SHOT_PATH = os.path.join(DATA_PATH,'freeze.parquet')\n", 29 | "df_shots = pd.read_parquet(SHOT_PATH)" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 3, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "MATCH_PATH = os.path.join(DATA_PATH,'match.parquet')\n", 39 | "df_match = pd.read_parquet(MATCH_PATH)" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 4, 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "EVENTS_PATH = os.path.join(DATA_PATH,'event.parquet')\n", 49 | "df_events = pd.read_parquet(EVENTS_PATH)" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 5, 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [ 58 | "RELATED_PATH = os.path.join(DATA_PATH,'related.parquet')\n", 59 | "df_related_events = pd.read_parquet(RELATED_PATH)" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 6, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "RELATED_PATH = os.path.join(DATA_PATH,'lineup.parquet')\n", 69 | "df_lineup = pd.read_parquet(RELATED_PATH)" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 7, 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [ 78 | "RELATED_PATH = os.path.join(DATA_PATH,'tactic.parquet')\n", 79 | "df_tactics = pd.read_parquet(RELATED_PATH)" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "# Check that all events have matches and vice versa" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "Some event files don't haev match info" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 8, 99 | "metadata": { 100 | "scrolled": true 101 | }, 102 | "outputs": [ 103 | { 104 | "data": { 105 | "text/plain": [ 106 | "{22536, 265905, 266234, 266466, 266574, 266933, 267161, 267405, 267609, 267679}" 107 | ] 108 | }, 109 | "execution_count": 8, 110 | "metadata": {}, 111 | "output_type": "execute_result" 112 | } 113 | ], 114 | "source": [ 115 | "set(df_events.match_id.unique()).symmetric_difference(set(df_match.match_id.unique()))" 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": {}, 121 | "source": [ 122 | "# Check all shots have freeze frames" 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "metadata": {}, 128 | "source": [ 129 | "All non-penalties have freeze frames. Some penalties have the goal keeper location." 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 9, 135 | "metadata": {}, 136 | "outputs": [], 137 | "source": [ 138 | "set_shots = set(df_events.loc[df_events.type_name=='Shot','id'].unique())\n", 139 | "set_freeze = set(df_shots.id.unique())" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 10, 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "data": { 149 | "text/plain": [ 150 | "set()" 151 | ] 152 | }, 153 | "execution_count": 10, 154 | "metadata": {}, 155 | "output_type": "execute_result" 156 | } 157 | ], 158 | "source": [ 159 | "# all freeze frames have shots\n", 160 | "set_freeze - set_shots" 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": 11, 166 | "metadata": {}, 167 | "outputs": [ 168 | { 169 | "name": "stdout", 170 | "output_type": "stream", 171 | "text": [ 172 | <<<<<<< HEAD 173 | "Number of shots without freeze frame: 259\n" 174 | ======= 175 | "Number of shots without freeze frame: 254\n" 176 | >>>>>>> 6d5a52dc8abbb526b8433831ca108d0786cbc715 177 | ] 178 | }, 179 | { 180 | "data": { 181 | "text/plain": [ 182 | <<<<<<< HEAD 183 | "Penalty 259\n", 184 | ======= 185 | "Penalty 254\n", 186 | >>>>>>> 6d5a52dc8abbb526b8433831ca108d0786cbc715 187 | "Name: shot_type_name, dtype: int64" 188 | ] 189 | }, 190 | "execution_count": 11, 191 | "metadata": {}, 192 | "output_type": "execute_result" 193 | } 194 | ], 195 | "source": [ 196 | "# the shots without freeze frames are penalties\n", 197 | "print('Number of shots without freeze frame:',len(set_shots)-len(set_freeze))\n", 198 | "df_events[df_events.id.isin(set_shots - set_freeze)].shot_type_name.value_counts()" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 12, 204 | "metadata": {}, 205 | "outputs": [ 206 | { 207 | "data": { 208 | "text/plain": [ 209 | "Goalkeeper 36\n", 210 | "Left Midfield 1\n", 211 | "Name: player_position_name, dtype: int64" 212 | ] 213 | }, 214 | "execution_count": 12, 215 | "metadata": {}, 216 | "output_type": "execute_result" 217 | } 218 | ], 219 | "source": [ 220 | "# some penalties have the location of the goalkeeper, one has the location of the left midfield\n", 221 | "penalty_ids = df_events[df_events.shot_type_name=='Penalty'].id\n", 222 | "df_shots[df_shots.id.isin(penalty_ids)].player_position_name.value_counts()" 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": {}, 228 | "source": [ 229 | "# Check related events" 230 | ] 231 | }, 232 | { 233 | "cell_type": "markdown", 234 | "metadata": {}, 235 | "source": [ 236 | "Note I made a change to the preprocessing to link all events both ways.\n", 237 | "\n", 238 | "In the docs it said that related_event was a comma separated list of the Ids of related events. For example, a shot might be related to the Goalkeeper event, and a Block Event. The corresponding events will have the Id of the shot in their related_events column.\n", 239 | "\n", 240 | "When I explored the data, often carries didn't have the corresponding event.\n", 241 | "\n", 242 | "Now this is fixed." 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": 13, 248 | "metadata": {}, 249 | "outputs": [ 250 | { 251 | "data": { 252 | "text/plain": [ 253 | "set()" 254 | ] 255 | }, 256 | "execution_count": 13, 257 | "metadata": {}, 258 | "output_type": "execute_result" 259 | } 260 | ], 261 | "source": [ 262 | "set1 = set(df_related_events.id.unique())\n", 263 | "set2 = set(df_related_events.id_related.unique())\n", 264 | "set(set1).symmetric_difference(set2)" 265 | ] 266 | }, 267 | { 268 | "cell_type": "markdown", 269 | "metadata": {}, 270 | "source": [ 271 | "# Are team names consistent between events and match" 272 | ] 273 | }, 274 | { 275 | "cell_type": "markdown", 276 | "metadata": {}, 277 | "source": [ 278 | "Yes!" 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": 14, 284 | "metadata": {}, 285 | "outputs": [ 286 | { 287 | "name": "stdout", 288 | "output_type": "stream", 289 | "text": [ 290 | "True\n" 291 | ] 292 | } 293 | ], 294 | "source": [ 295 | "away_teams = (df_match[['away_team_id', 'away_team_name']]\n", 296 | " .drop_duplicates()\n", 297 | " .rename({'away_team_id':'team_id','away_team_name':'team_name'},axis=1))\n", 298 | "home_teams = (df_match[['home_team_id', 'home_team_name']]\n", 299 | " .drop_duplicates()\n", 300 | " .rename({'home_team_id':'team_id','home_team_name':'team_name'},axis=1))\n", 301 | "teams = pd.concat([away_teams,home_teams]).drop_duplicates()\n", 302 | "print(teams.team_id.nunique()==len(teams))" 303 | ] 304 | }, 305 | { 306 | "cell_type": "code", 307 | "execution_count": 15, 308 | "metadata": {}, 309 | "outputs": [ 310 | { 311 | "name": "stdout", 312 | "output_type": "stream", 313 | "text": [ 314 | "Number of differences: 0\n" 315 | ] 316 | } 317 | ], 318 | "source": [ 319 | "teams_from_events = df_events[['team_id','team_name']].drop_duplicates()\n", 320 | "teams_from_events = teams_from_events.merge(teams,on='team_id',how='outer')\n", 321 | "print('Number of differences:',(teams_from_events.team_name_x != teams_from_events.team_name_y).sum())" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 16, 327 | "metadata": {}, 328 | "outputs": [ 329 | { 330 | "data": { 331 | "text/html": [ 332 | "
\n", 333 | "\n", 346 | "\n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | "
team_idteam_name_xteam_name_y
\n", 358 | "
" 359 | ], 360 | "text/plain": [ 361 | "Empty DataFrame\n", 362 | "Columns: [team_id, team_name_x, team_name_y]\n", 363 | "Index: []" 364 | ] 365 | }, 366 | "execution_count": 16, 367 | "metadata": {}, 368 | "output_type": "execute_result" 369 | } 370 | ], 371 | "source": [ 372 | "teams_from_events[(teams_from_events.team_name_x != teams_from_events.team_name_y)]" 373 | ] 374 | }, 375 | { 376 | "cell_type": "markdown", 377 | "metadata": {}, 378 | "source": [ 379 | "# Are player names consistent?" 380 | ] 381 | }, 382 | { 383 | "cell_type": "markdown", 384 | "metadata": {}, 385 | "source": [ 386 | "Yes!" 387 | ] 388 | }, 389 | { 390 | "cell_type": "code", 391 | "execution_count": 17, 392 | "metadata": {}, 393 | "outputs": [], 394 | "source": [ 395 | "player1 = df_shots.loc[df_shots.player_id.notnull(),['player_id','player_name']].drop_duplicates()\n", 396 | "player2 = df_lineup.loc[df_lineup.player_id.notnull(),['player_id','player_name']].drop_duplicates()\n", 397 | "player3 = df_tactics.loc[df_tactics.player_id.notnull(),['player_id','player_name']].drop_duplicates()\n", 398 | "player4 = df_events.loc[df_events.player_id.notnull(),['player_id','player_name']].drop_duplicates()" 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": 18, 404 | "metadata": {}, 405 | "outputs": [], 406 | "source": [ 407 | "players = (player1.merge(player2,how='outer',on='player_id',suffixes=['_shot','_lineup'])\n", 408 | " .merge(player3,how='outer',on='player_id')\n", 409 | " .merge(player4,how='outer',on='player_id',suffixes=['_tactics','_events']))" 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": 19, 415 | "metadata": {}, 416 | "outputs": [ 417 | { 418 | "data": { 419 | "text/plain": [ 420 | "0" 421 | ] 422 | }, 423 | "execution_count": 19, 424 | "metadata": {}, 425 | "output_type": "execute_result" 426 | } 427 | ], 428 | "source": [ 429 | "# check player names in shots matches events\n", 430 | "len(players[((players.player_name_events != players.player_name_shot) &\n", 431 | " (players.player_name_shot.notnull())&\n", 432 | " (players.player_name_events.notnull()))])" 433 | ] 434 | }, 435 | { 436 | "cell_type": "code", 437 | "execution_count": 20, 438 | "metadata": {}, 439 | "outputs": [ 440 | { 441 | "data": { 442 | "text/plain": [ 443 | "0" 444 | ] 445 | }, 446 | "execution_count": 20, 447 | "metadata": {}, 448 | "output_type": "execute_result" 449 | } 450 | ], 451 | "source": [ 452 | "# check player names in lineups matches events\n", 453 | "len(players[((players.player_name_events != players.player_name_lineup) &\n", 454 | " (players.player_name_lineup.notnull())&\n", 455 | " (players.player_name_events.notnull()))])" 456 | ] 457 | }, 458 | { 459 | "cell_type": "code", 460 | "execution_count": 21, 461 | "metadata": {}, 462 | "outputs": [ 463 | { 464 | "data": { 465 | "text/html": [ 466 | "
\n", 467 | "\n", 480 | "\n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | " \n", 492 | " \n", 493 | "
player_idplayer_name_shotplayer_name_lineupplayer_name_tacticsplayer_name_events
\n", 494 | "
" 495 | ], 496 | "text/plain": [ 497 | "Empty DataFrame\n", 498 | "Columns: [player_id, player_name_shot, player_name_lineup, player_name_tactics, player_name_events]\n", 499 | "Index: []" 500 | ] 501 | }, 502 | "execution_count": 21, 503 | "metadata": {}, 504 | "output_type": "execute_result" 505 | } 506 | ], 507 | "source": [ 508 | "players[((players.player_name_events != players.player_name_lineup) &\n", 509 | " (players.player_name_lineup.notnull())&\n", 510 | " (players.player_name_events.notnull()))]" 511 | ] 512 | }, 513 | { 514 | "cell_type": "code", 515 | "execution_count": 22, 516 | "metadata": {}, 517 | "outputs": [ 518 | { 519 | "data": { 520 | "text/plain": [ 521 | "0" 522 | ] 523 | }, 524 | "execution_count": 22, 525 | "metadata": {}, 526 | "output_type": "execute_result" 527 | } 528 | ], 529 | "source": [ 530 | "# check player names in tactics matches events\n", 531 | "len(players[((players.player_name_events != players.player_name_tactics) &\n", 532 | " (players.player_name_tactics.notnull())&\n", 533 | " (players.player_name_events.notnull()))])" 534 | ] 535 | }, 536 | { 537 | "cell_type": "markdown", 538 | "metadata": {}, 539 | "source": [ 540 | "# Are scorelines correct (exclude shoot outs)" 541 | ] 542 | }, 543 | { 544 | "cell_type": "markdown", 545 | "metadata": {}, 546 | "source": [ 547 | "Yes!" 548 | ] 549 | }, 550 | { 551 | "cell_type": "code", 552 | "execution_count": 23, 553 | "metadata": {}, 554 | "outputs": [], 555 | "source": [ 556 | "team_goals_from_events = df_events[((df_events.outcome_name=='Goal')|\n", 557 | " (df_events.type_name=='Own Goal For'))&(df_events.period!=5)]\n", 558 | "team_goals_from_events = pd.DataFrame(team_goals_from_events.groupby(['match_id','team_name'])\n", 559 | " .id.nunique()).reset_index()\n", 560 | "team_goals_from_events.rename({'id':'number_goals_events'},axis=1,inplace=True)\n", 561 | "teams_home_away = df_match[['match_id','away_team_name','home_team_name']]\n", 562 | "team_goals_from_events = team_goals_from_events.merge(teams_home_away,on='match_id',validate='m:1')\n", 563 | "mask_home = team_goals_from_events.team_name == team_goals_from_events.home_team_name\n", 564 | "team_goals_from_events.loc[mask_home,'team_status'] = 'home_score_events' \n", 565 | "team_goals_from_events.loc[~mask_home,'team_status'] = 'away_score_events'\n", 566 | "team_goals_from_events = team_goals_from_events[['match_id','team_status','number_goals_events']]\n", 567 | "team_goals_from_events = (team_goals_from_events.pivot(index='match_id',\n", 568 | " columns='team_status',\n", 569 | " values='number_goals_events')\n", 570 | " .reset_index())\n", 571 | "team_goals_from_events.replace({np.nan:0},inplace=True)\n", 572 | "df_match = df_match.merge(team_goals_from_events,on='match_id',how='outer')\n", 573 | "df_match.away_score_events.replace({np.nan:0},inplace=True)\n", 574 | "df_match.home_score_events.replace({np.nan:0},inplace=True)" 575 | ] 576 | }, 577 | { 578 | "cell_type": "code", 579 | "execution_count": 24, 580 | "metadata": {}, 581 | "outputs": [ 582 | { 583 | "data": { 584 | "text/html": [ 585 | "
\n", 586 | "\n", 599 | "\n", 600 | " \n", 601 | " \n", 602 | " \n", 603 | " \n", 604 | " \n", 605 | " \n", 606 | " \n", 607 | " \n", 608 | " \n", 609 | " \n", 610 | " \n", 611 | " \n", 612 | " \n", 613 | " \n", 614 | " \n", 615 | " \n", 616 | " \n", 617 | " \n", 618 | " \n", 619 | " \n", 620 | " \n", 621 | " \n", 622 | " \n", 623 | " \n", 624 | " \n", 625 | " \n", 626 | " \n", 627 | " \n", 628 | "
match_idmatch_datekick_offhome_scoreaway_scorelast_updatedmatch_weekcompetition_idcompetition_country_namecompetition_name...home_team_managers_country_nameaway_team_managers_idaway_team_managers_nameaway_team_managers_nicknameaway_team_managers_dobaway_team_managers_country_idaway_team_managers_country_namemetadata_xy_fidelity_versionaway_score_eventshome_score_events
\n", 629 | "

0 rows × 50 columns

\n", 630 | "
" 631 | ], 632 | "text/plain": [ 633 | "Empty DataFrame\n", 634 | "Columns: [match_id, match_date, kick_off, home_score, away_score, last_updated, match_week, competition_id, competition_country_name, competition_name, season_id, season_name, home_team_id, home_team_name, competition_gender, home_team_group, home_team_country_id, home_team_country_name, away_team_id, away_team_name, away_team_group, away_team_country_id, away_team_country_name, metadata_data_version, metadata_shot_fidelity_version, competition_stage_id, competition_stage_name, stadium_id, stadium_name, stadium_country_id, stadium_country_name, referee_id, referee_name, referee_country_id, referee_country_name, home_team_managers_id, home_team_managers_name, home_team_managers_nickname, home_team_managers_dob, home_team_managers_country_id, home_team_managers_country_name, away_team_managers_id, away_team_managers_name, away_team_managers_nickname, away_team_managers_dob, away_team_managers_country_id, away_team_managers_country_name, metadata_xy_fidelity_version, away_score_events, home_score_events]\n", 635 | "Index: []\n", 636 | "\n", 637 | "[0 rows x 50 columns]" 638 | ] 639 | }, 640 | "execution_count": 24, 641 | "metadata": {}, 642 | "output_type": "execute_result" 643 | } 644 | ], 645 | "source": [ 646 | "df_match[df_match.home_score != df_match.home_score_events]" 647 | ] 648 | }, 649 | { 650 | "cell_type": "code", 651 | "execution_count": 25, 652 | "metadata": {}, 653 | "outputs": [ 654 | { 655 | "data": { 656 | "text/html": [ 657 | "
\n", 658 | "\n", 671 | "\n", 672 | " \n", 673 | " \n", 674 | " \n", 675 | " \n", 676 | " \n", 677 | " \n", 678 | " \n", 679 | " \n", 680 | " \n", 681 | " \n", 682 | " \n", 683 | " \n", 684 | " \n", 685 | " \n", 686 | " \n", 687 | " \n", 688 | " \n", 689 | " \n", 690 | " \n", 691 | " \n", 692 | " \n", 693 | " \n", 694 | " \n", 695 | " \n", 696 | " \n", 697 | " \n", 698 | " \n", 699 | " \n", 700 | "
match_idmatch_datekick_offhome_scoreaway_scorelast_updatedmatch_weekcompetition_idcompetition_country_namecompetition_name...home_team_managers_country_nameaway_team_managers_idaway_team_managers_nameaway_team_managers_nicknameaway_team_managers_dobaway_team_managers_country_idaway_team_managers_country_namemetadata_xy_fidelity_versionaway_score_eventshome_score_events
\n", 701 | "

0 rows × 50 columns

\n", 702 | "
" 703 | ], 704 | "text/plain": [ 705 | "Empty DataFrame\n", 706 | "Columns: [match_id, match_date, kick_off, home_score, away_score, last_updated, match_week, competition_id, competition_country_name, competition_name, season_id, season_name, home_team_id, home_team_name, competition_gender, home_team_group, home_team_country_id, home_team_country_name, away_team_id, away_team_name, away_team_group, away_team_country_id, away_team_country_name, metadata_data_version, metadata_shot_fidelity_version, competition_stage_id, competition_stage_name, stadium_id, stadium_name, stadium_country_id, stadium_country_name, referee_id, referee_name, referee_country_id, referee_country_name, home_team_managers_id, home_team_managers_name, home_team_managers_nickname, home_team_managers_dob, home_team_managers_country_id, home_team_managers_country_name, away_team_managers_id, away_team_managers_name, away_team_managers_nickname, away_team_managers_dob, away_team_managers_country_id, away_team_managers_country_name, metadata_xy_fidelity_version, away_score_events, home_score_events]\n", 707 | "Index: []\n", 708 | "\n", 709 | "[0 rows x 50 columns]" 710 | ] 711 | }, 712 | "execution_count": 25, 713 | "metadata": {}, 714 | "output_type": "execute_result" 715 | } 716 | ], 717 | "source": [ 718 | "df_match[df_match.away_score != df_match.away_score_events]" 719 | ] 720 | }, 721 | { 722 | "cell_type": "markdown", 723 | "metadata": {}, 724 | "source": [ 725 | "# Number of events in each file" 726 | ] 727 | }, 728 | { 729 | "cell_type": "code", 730 | "execution_count": 26, 731 | "metadata": {}, 732 | "outputs": [ 733 | { 734 | "data": { 735 | "text/plain": [ 736 | <<<<<<< HEAD 737 | "count 808.000000\n", 738 | "mean 3585.856436\n", 739 | "std 400.381267\n", 740 | "min 2173.000000\n", 741 | "25% 3330.000000\n", 742 | "50% 3588.000000\n", 743 | "75% 3855.500000\n", 744 | ======= 745 | "count 778.000000\n", 746 | "mean 3595.831620\n", 747 | "std 399.092479\n", 748 | "min 2173.000000\n", 749 | "25% 3337.250000\n", 750 | "50% 3603.000000\n", 751 | "75% 3866.500000\n", 752 | >>>>>>> 6d5a52dc8abbb526b8433831ca108d0786cbc715 753 | "max 5026.000000\n", 754 | "Name: id, dtype: float64" 755 | ] 756 | }, 757 | "execution_count": 26, 758 | "metadata": {}, 759 | "output_type": "execute_result" 760 | } 761 | ], 762 | "source": [ 763 | "df_events.groupby('match_id')['id'].nunique().describe()" 764 | ] 765 | } 766 | ], 767 | "metadata": { 768 | "kernelspec": { 769 | "display_name": "Python 3", 770 | "language": "python", 771 | "name": "python3" 772 | }, 773 | "language_info": { 774 | "codemirror_mode": { 775 | "name": "ipython", 776 | "version": 3 777 | }, 778 | "file_extension": ".py", 779 | "mimetype": "text/x-python", 780 | "name": "python", 781 | "nbconvert_exporter": "python", 782 | "pygments_lexer": "ipython3", 783 | "version": "3.8.3" 784 | } 785 | }, 786 | "nbformat": 4, 787 | "nbformat_minor": 2 788 | } 789 | -------------------------------------------------------------------------------- /06_xa_map.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas as pd\n", 10 | "import numpy as np\n", 11 | "from mplsoccer.pitch import Pitch\n", 12 | "import matplotlib.pyplot as plt\n", 13 | "import os\n", 14 | "import matplotlib.gridspec as gridspec" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "# Load datasets" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "#DATA_PATH = os.path.join(os.getcwd(),'data')\n", 31 | "#EVENTS_PATH = os.path.join(DATA_PATH,'events')\n", 32 | "#df_events = pd.read_feather(EVENTS_PATH)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "metadata": {}, 38 | "source": [ 39 | "# Get all passes for Samuel Eto" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 3, 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "#df_pass = df_events[df_events.type_name=='Pass'].copy()\n", 49 | "#df_pass = df_pass[['id','player_id','player_name','pass_assisted_shot_id',\n", 50 | "# 'x', 'y', 'pass_end_x', 'pass_end_y']].copy()\n", 51 | "#df_pass = df_pass[df_pass.player_id==19298].copy()" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "# Get all shots and merge onto shots onto passes for outcomes" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 4, 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "#df_shot = df_events[df_events.type_name=='Shot'].dropna(axis=1,how='all').copy()\n", 68 | "#df_shot = df_shot[['id','shot_statsbomb_xg','shot_outcome_name']].copy()\n", 69 | "#df_shot = df_shot.rename({'id':'pass_assisted_shot_id'},axis=1)" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 5, 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [ 78 | "#df_pass = df_pass.merge(df_shot,on='pass_assisted_shot_id',how='left')\n", 79 | "# add assist column and drop shot outcome\n", 80 | "#df_pass['assist'] = df_pass['shot_outcome_name'] == 'Goal'\n", 81 | "#df_pass.drop('shot_outcome_name',axis=1,inplace=True)" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": 7, 87 | "metadata": {}, 88 | "outputs": [], 89 | "source": [ 90 | "df_pass = pd.read_csv('LubalaAssists.csv')" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 8, 96 | "metadata": {}, 97 | "outputs": [ 98 | { 99 | "data": { 100 | "text/html": [ 101 | "
\n", 102 | "\n", 115 | "\n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | "
x_pass_starty_pass_startx_pass_endy_pass_endxgassist
093.047.590.147.10.00True
183.139.385.353.10.19False
253.250.940.254.00.00False
346.252.440.543.90.22True
484.137.999.019.30.00False
\n", 175 | "
" 176 | ], 177 | "text/plain": [ 178 | " x_pass_start y_pass_start x_pass_end y_pass_end xg assist\n", 179 | "0 93.0 47.5 90.1 47.1 0.00 True\n", 180 | "1 83.1 39.3 85.3 53.1 0.19 False\n", 181 | "2 53.2 50.9 40.2 54.0 0.00 False\n", 182 | "3 46.2 52.4 40.5 43.9 0.22 True\n", 183 | "4 84.1 37.9 99.0 19.3 0.00 False" 184 | ] 185 | }, 186 | "execution_count": 8, 187 | "metadata": {}, 188 | "output_type": "execute_result" 189 | } 190 | ], 191 | "source": [ 192 | "df_pass.head()" 193 | ] 194 | }, 195 | { 196 | "cell_type": "markdown", 197 | "metadata": {}, 198 | "source": [ 199 | "# Subset the data for the lines and shots (assist/ or other)" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 10, 205 | "metadata": {}, 206 | "outputs": [], 207 | "source": [ 208 | "#boolean mask for assists or high xg. Use this to subset data\n", 209 | "mask_line = (df_pass.assist==True)|(df_pass.xg>=0.1)\n", 210 | "df_line = df_pass[mask_line].copy()\n", 211 | "# boolean mask for assists. Use this to subset data\n", 212 | "mask_assist = (mask_line) & (df_pass.assist==True)\n", 213 | "df_assist = df_pass[mask_assist].copy()\n", 214 | "# booelan mask for other passes (no assist/goal). Use this to subset data\n", 215 | "mask_other = (mask_line) & (df_pass.assist==False)\n", 216 | "df_other = df_pass[mask_other].copy()" 217 | ] 218 | }, 219 | { 220 | "cell_type": "markdown", 221 | "metadata": {}, 222 | "source": [ 223 | "# Plot the data" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": 16, 229 | "metadata": {}, 230 | "outputs": [ 231 | { 232 | "data": { 233 | "image/png": "iVBORw0KGgoAAAANSUhEUgAABLQAAAKjCAYAAAAEWFa6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOzd2W+deZ7f989zzuG+iRS1L6W99q6lq6trusvT45mxYcADuJFGkBtfxIkTIHAucpWbAIH/BF8kjpEM4ARwLnzRdsdwNjvj7umpXmem9lUq7bsokaK4L+c8uTiUVNVdi6pa5OFDvV4Ylkrkofilamaq8Nb393uK517+QRkAAAAAqIhapwcAAAAAgK9C0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUhqdHgAAAADYmr7zylMb+vV+/sv3N/Tr0Tk2tAAAAACoFBtaAAAAwLpa782pjd4Eo/NsaAEAAABQKYIWAAAAAJUiaAEAAABQKYIWAAAAAJVSPPfyD8pODwEAAABf5gfff7XTIwAP0Q9/9NrX/lwbWgAAAABUSqPTAwAAAMBX8btsdWwWd7fNNuP3spln2wib9fvfrHN9HQ9j29KGFgAAAACVImgBAAAAUCmCFgAAAACVImgBAAAAUCmCFgAAAACVImgBAAAAUCmCFgAAAACVImgBAAAAUCmCFgAAAACVImgBAAAAUCmCFgAAAACVImgBAAAAUCmCFgAAAACVImgBAAAAUCmCFgAAAACVImgBAAAAUCmNTg8AwMP3nVee6vQIW8rPf/l+p0cAAAA+wYYWAAAAAJViQwtgC7NZ9Lux6QYAPMp+8P1XOz0CfC4bWgAAAABUig0tAAAA4J4f/ui1To8AX8qGFgAAAACVImgBAAAAUCmCFgAAAFABRacHYBMRtAAAAIDNb/vupKu/01OwSQhaAAAAwOZW7056B5LxXZ2ehE1C0AIAAAA2t6HhpLcv6R9KBrZ1eho2AUELAAAA2Ny27Ui6e5PuvmTPoU5PwyYgaAEAAACbWC0Z2p50dyc9PcngcDI03umh6DBBCwAAANi8to23Y1ajJ2k0kkZvcuBEp6eiwxqdHgAAAADgc23fk3T1JkWSlEmtSLpHk5HxZPpmp6ejQwQtAAAAYPPavivp7kqKRortu1L09adcXEi5spj85Z91ejo6RNACAAAANqfewWRwJMXASOpPvJAURVKrJ61mcuSpNG9PpTz1eqenpAPcoQUAAABsTnsOJ13dqT/xQopGV4p6I0VRtH9sdKX+9/6zpG5X51EkaAEAAACb0449Kbbvbm9mfY7i8Rc3cCA2C0ELAAAA2Jw++KsUl08ntc/JF/VGim3jGzsTm4KgBQAAAGxOM5MpJ64ky8uf/fGVpZS3PenwUSRoAQAAAJtW+dHr7UvgP0ur1f44jxw3pwEAAAAdNzjQm2+99Hi2jQxkfn4pf/3Gqdy8dSdprqb5L/9J6v/Jf9M+etjVk6wsJa1Wmv/ynyTN1U6PTgdsyqD1g++/2ukRALYE///04fD7CPC7++GPXuv0CMAmVqsV+e53ns7gQF+SZHCwL9955an8+//wehYWllNePZ/V/+G/TXHihRTbxlPevtnezBKzHlmbMmgBAAAAj46Bgb57Meuurq5GxkaHc3lh7Y6s1ZWU7/86ZQfmY/PZ1EHLn+LQCXc3Mfzv39bjny18Mf83snX5Z0sn2XIFHsTqanvTqizLFEVx78e774ff5FJ4AAAAoKMWFpZz+syVFEWRJCmKItdvTOXGxO0OT8Zmtak3tAAAAIBHw5tvn8mtyZl7l8KfOXctpfOFfA5BCwAAANgULl6ayMVLE50egwpw5BAAAACAShG0AAAAAKgUQQsAAACAShG0AAAAgI335LeT/qFOT0FFuRQeAAAA2BiNrhQnXkix+7EUB46lfPy5lLeupbx4Krl4Mmk2Oz0hFSFoAQAAAOuu2PNY6j/4RyknLqW8ej5ZWU7tyNNpdfel2DaePPlSWtcvJOdPJreudnpcNjlBCwAAAFhfja7Uf/CP0vx///eUp9669+7i+HOp/8k/SOv0u0mtntqeQ8nOgynnZ1NeO5dcOJksznVsbDYvQQsAAABYV8WJF9qbWZ+IWUlSnnor5fWLKYZGU96eSMoyZVGm6OtP8diTycETad2eSC6fTa6dT8pWh74DNhtBCwAAAFhXxeiO9jHDz1BePp3iyDNrP0mK8v7flGVSDG9PhrYlR59OOXE9uXYmmb61YbOzOQlaAAAAwLoqpyZSe/aVz/xYse9osryUlOXai+/+bdnuWmklZZGy3kixc28yvivlwkwycSW5filZXtiw74PNo9bpAQAAAICtrfzo9RQ79qc4/tyn3l8cfy7FrgMp725clWXKJEXKFK32j2VZS3kvdrV/LHoGUuw9kjz33eTxbybb9yaFxPEosaEFAAAArK/mapo//B/bTzn81h+3jxnuO5pi14G0Lp9uh6wyKdKOWLnbr4okabU/0Fo7j9gq729zpUyGRpKBoWTf4WTqRvsJifOzHfk22TiCFgAAALDuyqvns/rP/rsUL/1xiu270rp5JeWpt1J09yY9fSm6upOiaL82ZZK78ar9nnwidKXI2tZWLSlX2++r1ZJtO5LhsWRpoR23bt9Kmisb/r2y/gQtAAAAYGOsrqT85f99r0sl9xtVmSTd/cngcNI/mPT2Jd19SXdvip6+pNHV3tAqW0lZpijLlGWz/Ymttfh191dr9CQ79iWjO5P5mWR6Kpmb/sRXo+oELQAAAGBzWJ5PJueTyU+/+16GanQnvYNJX3/S1ZP09ib1rnbsanTdj1tFmTRbSYr267t7k9HxZO5OMjOdrC5t7PfFQydoAQAAQIf84PuvdnqELWUltazUetMqurJa1NMq6mnV6mkWRYoUKcoiRZpptFYysDqfrrvHFakcQQsAAADYErrSSlerleSz781aTZFWamkWtdTK1sYOx0MlaAEAAMAG++GPXuv0CF/Z0FB//ubvfyNdXY2cPnMlb759ptMjfWVHDu/JC88dTdlazc9/+X6uXZ/q9Eh8TbVODwAAAABsfjMz8/nlrz9Ms9nK0SN788JzRzs90ldy7Oj9md98+7SYVXGCFgAAAPBAbkzczi9+9X6azWaOHN6Tb75wPEVRdHqsL/X48f157tkjSZI33vo4Z85e6/BE/K4ELQAAAOCBXb9xOz//5ftZXW3m0GO78r1Xn01vb3enx/pM9XotL7/0eJ55+lCS5PU3TolZW4SgBQAAAHwlNyam89PX3sn8/FK2bx/OH/3B89kxPtLpsT5laLAvf/i953Jg/46srKzmF7/6IGfPX+/0WDwkghYAAADwlU3dns2f/eSN3Ji4nd7e7vz+q8/mxReOpburs8+fq9VqeerJg/njP3whw8MDuXNnPj/+87dy5eqtjs7Fw+UphwAAAMDXsry8mtd+/m6eOHEgj584kMOP7c7e3dvz7vvncv7CjZRluaHz7Nk9lm88cziDg31JkrPnruXtd89mdbW5oXOw/gQtAAAA4Gsry+SDjy7m4uWbeeG5o9m5Y1u++cLxPHHiQE6eupRzF26k1Wqt29cvimTvnu15/MSBjG4bTJJM35nLG2+ezq3JO+v2deksQQsAAAD4nc3OLuQvfvZu9u8bz1NPHMzQUH9eeP5YnnrqsVy+fDOXLt/MxM3ph/b1to0MZP/+HTmwbzz9/b1JksXF5Xx06lJOn7m64dthbCxBCwAAAHhoLq3Fq317x3Pi+L6MjQ7lyOE9OXJ4TxYWlnJjYjq3Ju9kcnIm03fmHvjXHRzozdjYcLaPDWXHjm0ZWjtWmLRj2qnTl3P+wo00m+u3DcbmIWgBAAAAD93lKzdz+crNDA/158D+Hdm/fzyDA3157ODOPHZwZ5Kk2WxlcXE58wtLWVhYyupqM62yTK0oUq/X0tfbk76+7vT19aTRqH/q119cXM6lKzdz6dJEbk3OdOJbpIMELQAAAGDd3JmZz3sfnM97H5zPyMhAtq9tWW0fG87AQO+9ty+zuLicW5MzmZy8097wmpqJU4WPLkELAAAA2BDT03OZnp7LmbNXk6S9hdXXk77eu1tYtRRFkbJMWq1WFhaWsrDQ3uDypEI+SdACAAAAOqLZbGV2diGzswudHoWKqXV6AAAAAAD4KgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUgQtAAAAACpF0AIAAACgUhqdHgBgo/3g+692egQAAAB+Bza0AAAAAKgUG1rAI+OHP3qt0yMAAADwENjQAgAAAKBSBC0AAAAAKkXQAgAAAKBSBC0AAAAAKkXQAgAAAKBSBC0AAAAAKkXQAgAAAKBSGp0eAAC+rkaSodQylnoaKbKaMpNpZiatrHZ6OAAAYN0IWgBUUm+KHEhXiiTLKbOcMvUkO9LIeJKLWcliyg5PCQAArAdHDgGonEaSA+nKasospExz7f3NJAsps5oyB9LlT20AAGCLErQAqJyh1FIkn3uscDVJsfY6AABg6/Ff+gBUzljqWf7N44S1T/8rbTllxlLfwKkAAICNImgBUDmNFPeOGSZJ6vVkcNunXtNcex0AALD1CFoAVM7q2gXw9xVJoysp7v9rrb72OgAAYOsRtAConMk00/3J7ataLamtRa013Sky+ek9LgAAYIsQtAConJm0UiafeIphkdTqSXdPsvb+cu11AADA1iNoAVA5q0kuZiWNFOlLkXqtlqRIvas7fSnSSJGLWfncpyACAADV1vjylwDA5rOYMmeznKHUMlarpaeoZbWrNxNZzUxaYhYAAGxhghYAlbWaZCqtTHXVksGBpEgy1UhWlzs9GgAAsI4cOQSg+mq1pF60n3LYN9DpaQAAgHUmaAFQfUU9qXUl9UYyMNjpaQAAgHXmyCEA1Vert7ezUia9w52eBgAAWGeCFgDV12i0jx0WRdLvyCEAAGx1jhwCUH21elKvt3/s6k56RS0AANjKBC0Aqq/e1Y5Zd48eDm3r9EQAAMA6ErQAqL560T5yWCuSRj0ZHOn0RAAAwDpyhxYA1Vfrah85LNd+LmgBAMCWJmgBUH31taOGRdH+ee9gUjSScrWzcwEAAOvCkUMAqq/RlaJWS1EUSa1I0agnQ7a0AABgqxK0AKi+Wm3tUvhailqtva01PNrpqQAAgHXiyCEA1dfoWjtymCSloAUAAFucoAVA9dUb7Yh1V5EUQ6P37ogHAAC2FkcOAai+teOGqRVJvdb++56+pNHb6ckAAIB1IGgBUH31Rjti3X3SYVFvv29sR6cnAwAA1oGgBUDlFfVGUqvf+7G9pVVPhrd3ejQAAGAduEMLgOprNNrHDVOkSO7fnbVN0AIAgK1I0AKg+uqN9jHDlO2aVSRJkdrQaFqdnQwAAFgHjhwCUH31evvurFq9ffSwVrTv1OruSQaGOz0dAADwkAlaAFRe8clL4WtFUjTWAlctGdvT6fEAAICHTNACoPrqjRR3n3BYa29rtX9e86RDAADYgtyhBUDF1dr3Z/UPptixN8XwaDtkla2Ud6ZSpEz51mudHhIAAHiIBC0Aqq2rK8XB4ymGx5La2mZW0o5cI2OpP/N7KRvdaf7bf560mp2dFQCAe4oiGRrsz7Ztgxka7Eu9UUu9VkutVktZlmk2W2k2W5mbX8zt27OZvjOXVqv88l+YR4KgBUCl1f/uf5piZCxFrf5bHyuKWlJPcuL51P/kH6T5b/504wcEACBJ0tfXk507RrJt22BGRwYzMjKQRuO3/xvu87Rardy5M5+p27OZuj2bm7fuZGZmfh0nZjMTtACorGLv4RTHnvnMmPWp13V1J8efS7HnUMqr5zZkNgAA2nbtHM3RI3uye9doiqL41Mfm5hYzdXs2d+7MZWW1mVazlWarTK1WpF6vpV6vZWioP6Mjgxka6su2bYPZtm0wh9c+/+at6Zw5ey2Xr9y0vfWIEbQAqKzay38rqXc92IsbXam9/LfS/D/+l/UdCgCAdHc3cujgrhw+vDuDA31JkmazlWvXJzM5NZPbt2dz+/ZslldWH/jXrNdr2TYymNFtgxkdHcye3WMZ3z6S8e0jWVw6nHPnrufsuWuZX1har2+LTUTQAqCyimPPpqg92AN7i1otOfaNdZ4IAODRVq/X8sxTh3L40O7U6+3/TpubX8yZs1dz7vz1LC8/eMD6Tc1mK7cm7+TW5J17X+vA/h05emRPto0M5onHD+TxE/tz6fLNvPXOmSwtrTyU74nNSdACoLoa3V/t9V0PuM0FAMBXNr59OC+9eCIDA70pyzJXr03mzNmruXZ9al2+XrPZyrnz13Pu/PWMjQ3l6OE92bd3PAf278jOndvy1ttncvHSxLp8bTpP0AKgulaXk66eB3/9ij+lAwB42Or1Wp55+lCOHdmbJLk9PZu/ev1UpqfnNmyGycmZTE7O5N33z+fF549l967RvPzS49m3dzxvvPWxba0tSNACoLLKj99JHn/xgY4dlq1Wyo/f3oCpAAAeHePbh/PNF49ncKAvrVYrH350MR+evJSy7MwF7QsLS/nZL97Locd25RvPHM6+vdszPj5sW2sLErQAqKzWr/996kefTbofYEtrdSWtX//79R8KAOAR8djBnfnmC8dTFEVHtrK+yLnz13P9xlRefP74vW2tkeH+vPv++U6PxkPyYDfpAsAmVF45m/LUWylXvvhJNuXKUvt1V89tyFwAAFvdsaN789KLJ1IURT46eTH/4SdvbZqYddfCwnJ+9ov38vqbH6fVauXxEwfywnNHOz0WD4mgBUClNf/tP0958q2Uy0spW61PfaxstdrvP/lWmv/2n3doQgCAreXE8X157tkjSZK33j6Td98/37Ejhg/i7Llr+cWvPkiz2cyRw3vy0ovHOz0SD4EjhwBUW6uZ5r/50xR7DqX27b+dHH22/TTDlZWUH7+d1q//XcqrVssBAB6Gw4d259mnD6csy/z1G6dy/sKNTo/0QK5dn8prP38v3/29p/PYwV1ZWWnmrXfOdHosfgeCFgBbQnn1XJo/+p87PQYAwJa1b+/2e0f23njrdGVi1l03b93JL371fr7zytM5dnRvlpZX8uFHFzs9Fl+TI4cAAADAF+rr6753Afw7753L2XPXOj3S13JjYjq//quPUpZlnnriYLaPDXV6JL4mQQsAAAD4Qi8+fzxdXY1cuXorJ09d6vQ4v5MrV2/lo5OXUhRFvvniidTr0kgV+acGAAAAfK7HDu7K7l2jWV5eyRtvftzpcR6KDz66kDt35jI02Jennnys0+PwNQhaAHREUcSfhgEAbHJ9fd157tnDSZI33z6TxaWVDk/0cLRaZf7q9VNptcocP7rX0cMKcik8ABumVqvlwP7xHDm8J2Oj7f9oWF1t5uKliZw+ezXT03MdnhAAgE/65FHDi5cmOj3OQzV1ezYnT13KE48fyDdfPJE/+/EbaTZbnR6LByRoAbAh+vt78t3fezrDQ/1JkrIsUxRFGo16Dh/ancOHdueDjy7k/Q8udHhSAACSZPeu0S131PA3ffDRhezZM5aR4YEcPbInJ09d7vRIPCBnPQBYd93djfyN7zxzL2YlSVEUn3pNWZZ58vGDeeLEgY0eDwCAz3D08J4kyUcnL22Zo4a/qdUq8+5755IkRw7t6ewwfCWCFgDr7vjRfRkc7PvC1xRF0Y5aTxxIT0/XBk0GAMBnGejvza5do2k2Wzl34Xqnx1lX165PZW5uMQMDvdm9a7TT4/CABC0A1lWtVuTQoV0P9NqiKFKr1XL4sd3rPBUAAF/k8OHdKYoily5PZHl5tdPjrLszZ68mSY4ctqVVFYIWAOtqdHQovT3dX+lz9uwZW6dpAAD4MrVaLYcea/+B5Om10LPVnbtwPc1mK7t3jWagv6fT4/AABC0A1lVXo74hnwMAwMOxf994erq7MnV7NlNTs50eZ0MsL6/m0uWbKYoih92lVQmCFgDranW1+ZU/Z+VrfA4AAA/Hgf3jSe4fw3tU3P1+D+zf0eFJeBCCFgDranJqNkvLX+2pONevT63TNAAAfJnRbUNJkhs3bnd4ko01OTWTlZXV9Pf3eEhRBQhaAKyrVquV8+cf7Mk4ZVmm1Spz9ty1dZ4KAIDP0t/XjjlLSyuZX1jq9Dgb7vb0XJJkdNtghyfhywhaAKy7kx9fzvz84he+pizLFEWRk6cuZWFxeYMmAwDgk7athZzbtx+Nu7N+093ve5ugtekJWgCsu6WllfzFz9/L3NxvR62yLJMkRVHk1OnLee+D8xs9HgAAa+5uJk09okHr7vdtQ2vza3R6AAAeDbOzC/n/fvxGHju4M0cO78nwUH+SdtC6dPlmTp+9mlu37nR4SgCAR9s2QStJsm1E0NrsBC0ANszqajOnz1zN6TNX09VVT61Wy8rKalqtstOjAQCQZNvIQJLk9vSjGbRmZxfuXQzf3d3I8vJqp0ficwhaAHTEykozSbPTYwAA8And3e1MsLCw8Xea1uu1PP3kYxkZGcj8/FLee/9cFpe+2tOyH4alpZV0dTXS3SVobWaCFgAAAJCiSGq1WsqyvHfP6Ub6vW8/mV07R+/9fHz7cP7sJ29mdXVj/xC02WwlSer1+oZ+Xb4aQQsAAIBK+cH3X+30CFtaURSb4vd4cLAvf+9Pfq9jX/+P//CFjn1tvpynHAIAAABQKTa0AAAAqIQf/ui1To8AbBI2tAAAAACoFEELAAAAgEoRtAAAAACoFEELAAAAgEoRtAAAAACoFEELAAAAgEoRtAAAAACoFEELAAAAgEoRtAAAAACoFEELAAAAgEoRtAAAAACoFEELAAAAgEoRtAAAAACoFEELAAAAgEoRtAAAAACoFEELAAAAgEoRtAAAAACoFEELAAAAgEoRtAAAAAColEanBwBg8yn2Hk7txe+lOPZc0tOXLC2kPPVWWq//JOXVc50eDwAAeMQJWgDcV6un/nf+forHHk/r9Z+k+ZN/nczNJANDqT397dS//1+mPP9Rmv/Pv0hazU5PCwAAPKIcOQTgnvrf+fvJ0EhW//Qfp/Wrf5fMTidlK5mdTutX/y6rf/qPk+HR9usAAAA6RNACIEn7mGHx2ONp/qt/lqwsf/aLVpbT/OE/TXH06dT+5D9P8eRLycC2jR0UAAB45DlyCECSpPbC99J6/SefH7PuWllO6y//Q4rnXk3R358883sp5+4k1y+mdfVscu2C44gAAMC6ErQASJIUx59L88//9QO9tvXuL9P47t9N6+aVFEmK/sHkyFOpH34y5cpKMnktrWsXkytnkrnp9R0cAAB45AhaALT19LUvgH8Q8zNJoytJmbIsk7JIkSRFUjQayc79qe/Ym/LpbyVzd1LevJLy2vnk2qWktL0FAAD8bgQtANqWFpKBofZF8F+mfyhZXUlSS4pWUpYpy6T9l6RI0Y5b9XoyOJIMDKU4cCJZXUk5dSPlxOXkyrlk/s56fkcAAMAWJWgBkCQpT72V2tPfbj/d8EvUnnkl5ex0inotaRUp00pStoNWmfbPy7S3tlKkKGpJLSkbSbFjT4rte5Invply/k5y82rKaxeSiSvtJyoCAAB8CUELgCRJ640/T/3v/RdffjF8V09q3/qjtCavp2i22ptYRS0p1mJWqx2z7m1tFWWK9uJWilqRlLWUtTJplSn6hpIDgyn2H0+aqylvT6ScuNK+WN72FgAA8DkELQCSJOWVsynPf5T6f/Rfpfmv/qfPjlpdPan/x/91yuWlZHFu7Zhh7t2flRQpavWkbKVslUnWjiO217ba8StFiqJIavWUZWttq6uV1OrJ2K7UxnYljz+fzM+ldfNKcuNSe3sr5cb9ZgAAAJuaoAXAPc3/51+k/nf+fhr/8B+n9fqfp/Xer9oXwPcPpfb0t1N76Q9Tzk6nvPhx0jeQpH1EsB2miiSttfuzihT1ot2z7m5srR1JLMtW1m7ZSlEU7U+r1ZJWK8XaHVxlWSa9/akdOJYcaG9vZWoirYlLyfWLyeJ8J357AACATULQAuC+VjPN/+t/S7HnUGov/kEa//C/bz/9cGkh5am30vxX/zTl1fPt13b1JON7UoztTjE6ngyNJj1997ax7l0MX6u1Q9anwlYrZYqkbKUo0v77Wi1JsRa2akla7bCVsn2kcWxXatt3J4+/mMzdSevWteTG5WTqhru3AADgESNoAfBbyqvn0vw//9cvftHKUnL1XMqr5+4fBuzuS3bsTTG6I+XIeIrh0RTdve2NrVotaZUpiyJpNdeOGq7ds5X21lZbLam1krKWomy1P+duJGu12nd19Q+m1n882X8sWVlOOXUz5eTV9tHEJdtbAACw1QlaADw8ywvJ5dMpL59OsraQ1T+UbN+TYnRHipHxZHg0Rb3RPnrYWrtDK+1jhsWn7skqkqIdt4rW2ms+8STFoli7lKvRnWJ8d4rxncmxb6Scu5NyaiK5dSW5ffPerw8AAGwdghYA62t+JpmfSXnx5P1cNbQt2b47xcj2FCPbk76htcvky7t3x+f+JfDtC+TTWruf627carXufnTtr7WkVqYYGE4xMJTsPZRydTWZvply8kYyeS1ZWtiwb3uzaCQZSi1jqaeRIqspM5lmZtLKaqeHAwCAr0nQAmDjzdxOZm5n7SGJSYpkeCwZ25lieHvKodFkYLB9VPGTC1a1WvvHci1ulWX7aYpFe3Or/aDFov2L1mopGl3J9l3J6M7kyNPJwmzK2zeTW9eS6VvJFn9yYm+KHEhXiiTLKbOcMvUkO9LIeJKLWcniFv89AABgaxK0ANgEyuTOreTOrft5pagl23ak3LY9xfBYMjSSorcduVLU2p+TVopa+whiO46VSau8v+FVFEmrltD6VpIAACAASURBVKJotT/aN5iitz/ZfTBprqa8M5lMTSST15PlxY585+ulkeRAurKa8lObWM0kCynvffxslm1qAQBQOYIWAJtT2UqmridT1+9FrrLeSEbGk23bUwyNpRjalnT3pv0kxLQvkF87tth+dmLZPo1YFu1tr5RJWbTDV63evtNrZDw59OT97a3bE2vbW9U2lFqK5HNj1WqSrrXXTcVTIgEAqBZBC4DqaK6278KavHb/uGJXT7JtPBkaTTG0LcXAcNLoWrs7vrx3KXzRPo+49j93k9cn/tLbn2L3wWT3gWS12d7euj3R3uBaXe7AN/u7GUs9y19ynHA5ZcZSF7QAAKgcQQuAaltZSiYuJxOX70eunr72nVxDoymGRpL+oZS1RtpbW2sXyBdlinLtKOLdM4t3A1CtlmLb2ibYY0+knJ9JOb0WuObupAp3bzVSfGnQaibpWTugCQAAVSJoAbD1LC18KnIlSfoGkuGxlINrW1x9Qylqd48iFklRri1z3d/quvvUxfQNpugbSHbtT1ZWUs5OJXcm20cTV1c68R1+qdW1C+CbX/Ca+trrAACgagQtAB4NC3Ptt+sX79/J1T+cDG1LBoZTDI60L4xP+8qtdtS6H7baiqSrq3331vBYsvdIysW5ZGYquTOVzM9s8Df1+SbTzI40svAFwao7RSZcCQ8AQAUJWgA8uubvtN+y9pTEopYMDif9Q8nASIr+wbVL59O+pL59w/z9zy9q7QjW05+M7025uprMTScz0+3I1ezc9tZMWhlP+1/0n5Ws2gcw268DAICqEbQA4K6ylczcbr9lbZOrqLcj18DQ/aOHXT33t7aKtcjVSop6LRkaTTm4Ldl1oH30cW46mZ1OFmY39FtZTXIxKzmQrnSlfQF8M+1jht1r1+JfzIr9LAAAKknQAoAvUjbb21YzU+2fJkmt0Y5cfQPtba7e/hT1Rj61wVUrkt6+pKc3GdvVfkLj3Ew7cM1NJ80vut3q4VhMmbNZzlBqGUs9PSmymjITWc1MWmIWAACVJWgBwFfVWm1fCn9n8t67ykZXO271DSa9/e2QVdTXPlgmtVoyONIOYeWBZGn+fuBaWli3UVeTTKWVKUcLAQDYQgQtAHgYVld+K3KlqyfpHVh76026++4fUezuTbp6k23b29ta8zPJ/Gz7x/LL41Mjubd51VjbvJpM0+YVAACPBEELANbLylL7beaTkas36etvx62evqSru729NTDcfitbyeJCsjSXzM22P/839KbIgXSlSPturOWUqSfZkUbG074ba/ELnm4IAABVJ2gBwEZaWWy/fVJ3T/tJiT19SXd3+7hid08yNJasrraPJy7MJYvzaZStHEhXVlN+ahOrmWQhZRpJDqQrZ7NsUwsAgC1L0AKATltear+tXTyf1JKenrVjiT3tuNXbn5RlhuYXUiwtZXVl8TMvll9N0pX2cUT3ZgEAsFUJWgCw6bTaF8V/8rL4opZ092Ss6Mlyo5H0bGtfTr8w197i+oTllBlLXdACAGDLErTgc/zg+692egSA3zJw+U6a3bWkKFKmSJIUv3lfVlmmvtzK8/uGOzAhAACsv1qnBwAAHlxZL5JWO2C1k9ZnXP7eKtuvAwCALcqGFvyGH/7otU6PQIX09/fkD7/3fHp6uvLxmSt56+0znR6JLay/ryd/+5tPZniplUs3JnPq9JXPfF1fikxk1ZFDAAC2LBtaAL+D+fml/OJX76fZbOXYkb05enhPp0dii2o06vnOK0+lMdqfqTtzOXfms2NWI0mZZEbMAgBgCxO0AH5HtyZn8tdvnEqSPPeNI9m9a7TDE7HVFEWRl196PCMjA5meX8yPT59PvSzSlyL1tdfU097MaqTIxaxk9Yt+QQAAqDhBC+AhuHhpIh98eCFFUeSVl58UtXhoiqLIt7/1ePbsHsvS0kp+/ov3M7u6mrNZzkRWU0/Svxa2JtJ+/+Jn3asFAABbiKAF8JC8/+GFnD5zJfV6La+8/GT27B7r9EhUXK1W5JWXn8i+veNZXl7Ja794L3Pzi0mS1SRTaeV0VvJRlnM6K5lKy2YWAACPBEEL4CF68+0zOXX68lrUeiJ792zv9EhUVDtmPZm9e7ZnaXklP/3Zu7l9e7bTYwEAwKYgaAE8ZG+/czYnT11KrVbLt7/1ePbtFbX4amq1Wr7z7afuHTP8i9fezfT0XKfHAgCATUPQAlgH77x3Lh+dvJharZaXX3oi+/eNd3okKqJer+W7rzyVXbtGs7i4nJ++9k6m74hZAADwSY1ODwCwVb37/vm0yjJPPn4wL7/0eIqiyMVLE50ei02sXq/lO688lZ07tmVhcTl/8do7mZld6PRYAACw6QhaAOvo/Q8upGyVeerJx/Ktb55IURS5cPFGp8diE2o06vnuK09lfHwkCwtL+enP3s2smAUAAJ9J0AJYZx98dDGtsswzTx3KSy8eT6NRy5mz1zo9FptId3cj3/n2U9m+fTjz80v56c/eydzcYqfHAgCATUvQAtgAH528lLIs8+zTh/PCc8eybWQwb759Oq1W2enR6LDRbYN55eUn0t/fm7n5xfzFa+9kbn6p02MBAMCmJmgBbJCTpy5ncXElLz5/NIcP7c7IyEB++esPs7AgXjyqDj22K89/42jq9VpuTd7JL3/9YRYXlzs9FgAAbHqecgiwgS5cvJEf//TtzM0tZmx0KH/0B89n546RTo/FBqvVirz4/LF884XjqddrOX3mSv78L94RswAA4AEJWgAbbHp6Ln/2kzdz7fpkenq68up3nsmJ4/s7PRYbpK+vJ9/7G9/I4UO702w285d/fTJvvn0mZen4KQAAPChBC6ADVlZW87NfvJ8PPryQoijy7NOH8srLT6TRqHd6NNbRjvGR/NEfPJ+x0aHMzS3mxz9921MvAQDga3CHFkAHvf/hhUzdns1L3zyRfXvHMzzUn1/86oPMzC50ejQeshPH9+WZpw6lKIpcuz6ZX//VyaysrHZ6LAAAqCQbWgAddvXaZH78kzczPT2XoaH+/M3vPZfHDu7s9Fg8JD09XXnl5Sfz7NOHUxRFPvjwQn72i/fFLAAA+B3Y0ALYBGbnFvPjn76VF58/loMHdualF0/k4IGdefOt07a1Kuzwod155ulD6e5qZGVlNX/51ydz9dpkp8cCAIDKE7QANolms5W//OuTuX7jdr7xzOHs3LEtf/Q3X8jJU5fy4cmLabVcGl4VI8MDeeH5o9k+NpwkuXZtMm+8fTrz80sdngwAALYGQQtgk7lw8UauXZvMM08fyuFDu/PkEwdzYP+OvPHW6dyYuN3p8fgC9XotTz1xMMeO7kutVmRhYSlvvXMml6/c6vRoAACwpQhaAJvQ8spqXn/z45y/cCMvPH80I8MD+RvffSYXLt7I2++ezdLSSqdH5Dfs2T2W579xJP39vSnLMh+fvpL3Pjif1dVmp0cDAIAtR9AC2MRuTd7Jn/34zRw/ti9PPn4gBw/szO7dY3n3vXM5e+5ap8cjSV9fT57/xpHs3bM9STJ1ezavv/lxbt+e7fBkAACwdQlaAJtcWZY5eepSLl2eyAvfOJrdu8fy4vPH8tjBnXnv/fOZuDnd6REfSY1GPUeP7MkTJw6k0ahnZWU1731wPqfPXO30aAAAsOUJWgAVMT+/lJ/98v3s27s9zz17JNvHhvP7rz6biZvT+eDDC8LWBrkbsk4c25fu7q4kyaXLN/PWO2eyuLjc4ekAAODRIGgBVMzlK7dy/cbtHDuyN8eP7c2O8ZHsePXZ3Lw5nfeFrXXTaNTv/Z7fDVl+zwEAoDMELYAKWl1t5sOTF/PxmSv3toXGx0fy+68+m8mpmZz6+HIuX7mZsuz0pNXX19edY0f25vCh3enqav9r01YcAAB0lqAFUGGrq818dPJSTp+5mqNH9uT40X0ZGx3Kt7/1RObmF/Pxx1dy7sJ1T9r7GkZGBnL82L4c2DeeWq2WRMgCAIDNQtAC2ALuhq2PT1/JwQM7c+LYvgwO9uW5bxzJk08czKXLE7l4aSI3b93p9KibWndXI/v2bs+BAzuzY3wkSftS/ouXJnLq48uZ8uRCAADYFAQtgC2k2Wzl7LlrOXvuWvbuGcvxY/syvn0kRw7vyZHDezK/sJRLl2/m4qWJ3BZnkrTvxtqzeywH9u/Irp3b7m1jra42c/b8tXx8+krm55c6PCUAAPBJghbAFnXl6mSuXJ3MyMhADuwbz/79OzLQ35sTx/blxLF9mZ1dyMXLE7l46WZmZuY7Pe6GqtVq2b17NAf27cie3aOp1+tJklarzPXrU7l4eSKXr9xyVBMAADYpQQtgi5uensv09Fzeff98xkaHcmD/juzfN57Bwb48+fjBPPn4wUxPz+Xi5Ylcunwzc3OLnR55XdRqRXaMb8uB/Tuyd8/YvQvek/bdWJcuT+Ty5VtZWl7p4JQAAMCDELQAHiGTUzOZnJrJW++cyY7xkRzYvyP79m7PyMhARkYG8sxTh7KwsJRbkzOZnLyTW5MzuT09m1areo9L7O3pytjYcLaPDWX72HC2bRtMvV679/GpqZlcvHwzly5PZGFhuYOTAgAAX5WgBfCImrg5nYmb03njrdPZtbO9ubR712j6+nqyf19P9u8bT9K+l2vq9uy9wHVr8k6WljbXFlNRJCPDA58KWAMDvb/1utvTc7l85WYuXZrI7BbdRAMAgEeBoAXwiCvLMteuT+Xa9akkydBg3yfC0FCGhwcyvn0449uH733O3NxiJqdmMj+/mPmF5SwsLK29La/bkb1arUhfb3f6+nruvfX3dWdoqD9jo0NpNOqfev3Kymomp2bubZtNTs1kZcWdWAAAsBUIWgB8yszsQmZmF3L+wvUkSVdXPWOj9zefRkcHMzDQ+5kbUEl7o2thYSkLi8uZXwtdiwvLWW22UpattFplWmWZslWmLMvUarUURZFarbj3Y3d3I/2fCFd9vd3p7e3+wrlnZxfubZBNTs5k+s7cQ/+9AQAANgdBC4AvtLLSzPUbU7l+o73BVRTJ8PBARoYH1qJT99q2VPvvu7u7MjjYl8HBvoc6R6tVZmGxvQX2yY2wufnFTE7OuMwdAAAeIYIWAF9JWd5/cuJnqddr944DfnLDqlarfWoLqyjab2VZtre2Wq3235dlVlaaWVhYurfhtbCwnMVFF7cDAABtghYAD1Wz2crs7EJmZxc6PQoAALBF1b78JQAAAACweQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAAFSKoAUAAABApQhaAAAAwP/f3n01x3me+b7+dyMnIjAAYA4KFEVFW5bGo/Ga8VqrdtU+mip/zqma89mTPZYVrcgo5gCCAQCJDHTYBwChYEkUKYBvv8R1VbFkAE30DVMSwZ/u52koFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAoFUELAAAAgFIRtAAAAAAolfaiBwAAAACeTb9958RTfb4//fnUU30+imNDCwAAAIBSsaEFAAAAbKmt3px62ptgFM+GFgAAAAClImgBAAAAUCqCFgAAAAClImgBAAAAUCouhQcAAKAU/vCP7xY9Ak/oaf3a+XukXP7pn//4xD/XhhYAAAAApWJDCwAAgFL5JVsdreLhJlErfi2tPNvT0Kpff6vO9SQ2Y5POhhYAAAAApSJoAQAAAFAqghYAAAAApSJoAQAAAFAqghYAAAAApSJoAQAAAFAqghYAAAAApSJoAQAAAFAqghYAAAAApSJoAQAAAFAqghYAAAAApSJoAQAAAFAqghYAAAAApSJoAQAAAFAqghYAAAAApSJoAQAAAFAqghYAAAAApSJoAQAAAFAqghYAAAAApdJe9AAAAABA6/nDP75b9AhrGs1UavW0rTaSZjOpVFLvqKbZ3pZUK0VPR0EELQAAAKA11RtpX1pNmpU0q0naqkmjmbaVRrJaT627Y+19bDuCFgAAALDhn/75j0WPkCSpJNmRahpJGj/w8er6jwdppPlUJ6MVyJgAAABAy+lIJZX8cMzK+vsr649j+xG0AAAAgJbTnaT2iMfU1h/H9iNoAQAAAC2nmsojjxI21x/H9iNoAQAAAC2nkeYjU1Vl/XFsP4IWAAAA0HKW8uhXsmtffxzbj6AFAAAAtJzVNNePFP6wataOHK7a0NqWBC0AAACg5TSTzKWRapKOZOP4YWX97er6x+Ws7elR23sAAAAAhagneZBGOlJJd9YugG+kmYV8s8HF9iRoAQAAAC2rmWQlzaxsvAWOHAIAAABQMoIWAAAAAKUiaAEAAABQKoIWAAAAAKUiaAEAAABQKoIWAAAAAKUiaAEAAABQKu1FDwAAAABQrVby4vP7MzjYl4WF5Zw+ey2rq7Wix6JFCVoAAABA4d5+63j2ju/ceHvP7qH8+399lnq9UeBUtCpHDgEAAIBC9fV2Ze/4zjSbzY33DQ72Zc/uoQKnopUJWgAAAEChKtW1PFGpVL73/soPPRwELQAAAKBY8/OLmZqe/c77FheXc/fu/YImotW5QwsAAAAoVLOZ/M97X+X1V49tXAr/2RcXs7LiUnh+mKAFAAAAFG5lpZYPPjpb9BiUhCOHAAAAAJSKoAUAAABAqQhaAAAAAJSKoAUAAABAqQhaAAAAAJSKoAUAAABAqQhaAAAAAJSKoAUAAABAqbQXPQAAAABAESpJOlJJd5JqKmmkmaUkq2mmWfBs/DRBCwAAANh22pL0p5pKklqSepJKKulN0kwlc2mkXuiE/BRHDgEAAIBtpZK1mNVIsppsbGM1199u5JvYRWuyoQUAAABsG5UkfalmR5L6+jHD5Xw3bDWytsHVkUpWHD5sSTa0AAAAgG2hLcmOVDOUSlZSWd/GqqQnlQykkrZvPbaWpLuYMfkZBC0AAADgmfftY4YPfyTfPWbYl8rGMcNm4tBhC3PkEIAt197els7O9lQrlVSqlVQqlVQrlaRSSbPZTLPRTLPZTKPZTL3eyPLyappNq90AAGyejvVY9TBmVZLvHCb85phhsrL+8Ybjhi1L0ALgiVWr1fT1daenuyPd3V3p7u5Id3dnero7093Vme6etb+2t7c9+pN9z/LyahaXVrL0vR8P37e4uJzFpZUt+KoAAHgWdWftGGGSLCfpydpm1rfVknRlLWi1J1l4atPxuAQtAH6WarWawcHeDA/1Z2ioP8ND/dkx0Jdq9dFr2LVaPcsrq2k21rawHv41SdYWtSob21vtbW3p6urY+JHBvh/9vMvLq5mZmcv0zFym789lZmYuCwvLm/Y1AwBstT/847tFj7BttM8tp9m+fvNSo5m2xdW1b0a/8/1sM5V6M7WejlSazdR6Or/3cVqFoAXAX6lUKhka7Mvw8E/Hq2azmdm5xSwuLn+zRbW8+p1NqqWlldRq9ceeobtrbdvr2z96vvW/+3q709XVkdHR4YyODm/8vO9HrumpWZtcAACsxatGcy1QVSup93SkbXE1lXozzYff5zabSb25FrO6O8SsFiZoAZBk7Z6rsdHhjI+NZGx0JJ2d3/0totls5v6D+Y1YNDMzl5n786nXGz/yGX+ZpeXVLC2vJvfnf/QxPT1dGV4Pbg/D2w9Frpn7c5mYmMrNW1OZmZnbknkBAB7HP/3zH4se4YmcOH4wLx0/mEajkfc/PJubE/eKHuln2z3Ql79784W093RmYmIqn3x2IZWshZHuVFLN2ivnzaSZebdntTxBC2Ab6+3tyvjYSPaO7cyuXTtSrX7z4rezswuZmp59KvHqSS0uLmdxcfk730h9P3LtHBnI0GB/hgb789Lxg1lcXM7EralM3JrK7Tv302i01tcEANDKTp25mmpbNS8+vz9vv3U8H3x0Njdu3i16rEcaHu7PO++8nI5aI5MTU/nL5xeSfPMKh6tpbgQtMascBC2AbWZoqD/7xndmfGwkg9+6n6rRaObO3fuZmLiXiVtTmZtfKnDKJ/f9yFWtVrJ712DGx0YyPrYzvb1dOXpkPEePjKdWq+f2nZncnJjKzYl7WV2tPeKzAwDw5VeX02w0c/zFA3n7rRdz+mxvTp+5WvRYP+rggT158/VjaWtry5Xbd3Lm8wtpb65dAN9MNra0mknmxKzSELQAtoG2tmoO7N+do0fGMzzUv/H+1dVabk1OZ+LWVG5NTj+TQafRaGby9kwmb8/k088vZnCwL3vHRjI+vjPDQ/3ZO74ze8d3pl4/mmvX7+bCpQnHEgEAHuGr01eyWqvl5InDOXH8YIaH+vPhx2ezuvr4d6dulUqlktdeOZJjR/cmSS5dvpW/fHYhaTbTkUq6k1RTSSPNLGRtS0vMKg9BC+AZ1t/fk6OHx3Lo0Gg6O9b+lb+8vJrrN+7k5sRU7ty9n2Zze/22ff/+fO7fn8/ps9fS092ZsbGR7N+7K3v2DOXwodEcPjSaqenZXLw0kWvX7zqSCADwI86dv5GZmfn85q0XMz42kv/z+zfz2ecXW+JerZHhgbzx+nMZGuxLvd7Ip59fyOUrkxsfX0kzay8btL2+F36WCFoAz5hKJRkf25mjR8Yyuuebi9HvTT3IxUsTuX7jbhoNv3EnyeLSSi5dvpVLl2+lv687R46M5/DBPRkZHsjI8EBePXkkl69M5uLlW5kv6RFMAICtdPvOTP7tPz7Nb379YnaO7MjfvP1SJm5N5dPPL2RhYfmpz9PR0Z6TJw7l6JHxJMn8/FLe//BMpm3gP3MELYBnREdHW44d3Zsjh8fS29OVJKnV6rl2/U4uXprIzE+8WiDJ3PxSvvjyUk6dvpL9+3bl2JHxDA8P5IXn9+eF5/fn1uR0vr5wI5O3Z4oeFQCgpSwsLOc//uvzHD0ynpMnDmV8bCSje4Zy+cpkzp6//lTCVmdne44d3Zvnj+1NR0d7Go1Gzp2/kTPnrrXcCxuxOQQtgJJra6vm2NHxvPj8gXR2rv1rfXZ2IRcv3cqVa5MtdY9BGdTrjVy5ejtXrt7O8FB/jh4Zz4H9uzI2Opyx0eHcuXs/X566nKmp2aJHBQBoKRcvTeTmxL288vLhjftbjxwey42b93L12u1M3p7e9JMCu3buyMEDe3Jg/+60t7clSW7fnsmnX1zM7OzCpj4XrUXQAiipSiU5fHA0Lx0/mJ71jazbd2Zy9ty13L5zv+Dpng3TM3P5+C/n88WXl3L48GheeH5/du8azD/87rXcnLiXL09d8Y0SAMC3LC2t5MOPz+XMuWt58fkDObB/V/bvW/uxslLLzYl7mbw9nXtTD7K4uPLYn7+zsz07R3Zk9+7B7N+7a+P74CS5dWsqZ85fz717DzbzS6JFCVoAJbRv7868/NKhDAz0JlkLL19+dTm37zgOtxVWVms5d/5GLl66sd7kzAAAFw5JREFUlRee35fnj+3L3vGdGR8byZWrt3P6zNUsLD79OyIAAFrV7OxiPvrkXL48dXl9g2pXhgb7N16EJ1k7qjhzfy4LC8tZXFzOwuJyarV6ms1mKpVK2tqq6enpSk9PV3p7OjO4o2/j+9+H5ueXcu36nVy9djuzc4tFfKkURNACKJHduwZz8uXDGRkeSJLMzS3mq9NXcv3G3YIn2x5qtXpOnb6aCxcn8tKLB3Lk8FgOHxrNgf27c/HSRM6cu5aVlVrRYwIAtIylpZWcO389585fz8BAT/aN78rOnQMZGdmR3t6u9PZ2PfqTfEutVs/0zFzuTT3IxMRUpqZdA7FdCVoAJdDX2503XjuW0dG1Vy1cXFrJmTNXc+nKZJpNr1j4tC0vr+bTzy/m/Nc3c+Klgzl4YE+ef25fDh8azemz13L+6xtFjwgA0HJmZxdzZvbaxtsDA73ZMdCb3p7OjU2strZqqpVKms1m6o1GFpdWsri4nMXFlczOLeb+/Xnf/5JE0AJoeceOjufkicNpb2/L6motZ89fz9cXbnq1lhYwv7CUDz8+l3Nf38jJE4cyNjqSV08eyb69O/PxJ+etvQMA/ITZ2QX3kfLEBC2AFtXX25VfvflCdu8aTJJcu34nn35+wZG2FnT//nz+571TGRsdzhuvP5edIzvyv//hjZw6fSXnbGsBAMCmE7QAWtCxI+M5+fLaVtbS0kr+8tmF3Jy4V/RYPMKtyen8f//2SV49eTSHD43mlZNHste2FgAAbDpBC6CF2Moqv9XVej7+y/ncuHk3b35rW+ur01fcrQUAAJtE0AJoEbayni23JqfzL9/a1nK3FgAAbB5BC6Bg7e1teetXL2Tv+M4ktrKeJT+0rfX7v389H31yLjduipUAAPCkqkUPALCd9fV25+9/92r2ju/Myspq3nv/dD746KyY9Yx5uK119drttLe35Z3fvJQTxw8WPRYAAJSWDS2AguzeNZi3f3M8XZ0defBgIX96/1Tm55eKHostsrpaz4cfn8v0zFxePXkkLx0/mB07+vLRJ+dSq9WLHg8AAEpF0AIowLEj43n1laOpViuZuDWVDz46K2psE19fuJkHDxby9lvHs2/vzvT3vZo/vX8qCwvLRY8GAACl4cghwFNUqVTy5uvP5fXXjqVareTMuWv5059PiVnbzO07M/n3//w0s7MLGRzsy+//1+sbr2wJAAA8mqAF8JR0dXbkd397MkcOj6Ver+f9D8/kq1NXih6LgszNL+Xf/vOzTNyaSldXR9797ckcPTJW9FgAAFAKghbAUzDQ35N/+PvXsmvXYBYWl/Mf//1Frt+4W/RYFKxWq+dPfz6Vs+eup1qt5I3Xnsvrrx4teiwAAGh57tAC2GI7dvTm7/72ZLq7OnNv6kH+/P7pLC2vFj0WLeTLU5dz/8F8fvXG8zl2dG/a2tvy8Sfnix4LAABalqAFsIWGBvvy7t+eTFdnR25NTue990+n0WgUPRYt6Nr1O1laWslv3zmRwwdH01at5sOPz6XZbBY9GgAAtBxHDgG2yMjwQH737ivp6uzIzYl7ee/9U2IWP+nO3fv545++zOpqLQf2787bbx1PtVopeiwAAGg5ghbAFhge7s+7v305HR3tuX7jbv78wZk0GjZteLR7U7P57//5MisrtezbuzNvv3U8lYqoBQAA3yZoAWyyocG+vPvbk+noaM+163fywUdnHBvjsUzPzOW//ueLrKysZu/4zvzm1y9E0wIAgG8IWgCbaMdAb9797cl0drTnxs27+fDjs9GyeBL378/nv//0VVZXa9m/b3d+9cYLRY8EAAAtQ9AC2CT9fd35u789ma6ujkzcmsr7H4pZ/DIzM3P543tfpVar59DBPXnz9eeKHgkAAFqCoAWwCTo62vLbd06ku7szk7en8+cPTjtmyKaYmprN/6xHrSOHx/LCc/uKHgkAAAonaAFsgt/8+ngGBnozc38+771/2gXwbKq79x7kw4/PJUlOvnw4Y6PDBU8EAADFErQAfqFX1gPD8vJq3nv/VOr1RtEj8Qy6OXEvX52+kkqlkt/8+sUM9PcUPRIAABRG0AL4BQ4e2JMXnt+fRqORP39wOgsLy0WPxDPszNlruX7jbjo62vM375xIR0db0SMBAEAhBC2AJzQyPLBxSfenn1/M3XsPCp6I7eCjT85l5v5cBvp78vZbx1OpFD0RAAA8fYIWwBPo7u7MO2+/lLa2ai5cvJlLl28VPRLbRL3eyHt/Pp2l5ZWM7hnOKy8fKXokAAB46gQtgMdUrVbzN2+/lJ7uzty+M5PPvrhU9EhsMwuLy/nzB2fSaDTy/HP7cujgnqJHAgCAp0rQAnhMb75+LCPDA5mfX8r7H55Js+kVDXn67t17kL98diFJ8sZrz2V4qL/giQAA4OkRtAAew97xnTl0cDS1Wj1/ev9UVlZqRY/ENnb5ymQuXLyZtrZq3vrVC6lW/bYOAMD24DtfgJ+ps7M9b7x2LEnyxVeX8+DBQsETQfL5l5fyYHYhAwO9OfHSwaLHAQCAp0LQAviZXn/1WLrX7826eGmi6HEgSdJoNPPxJ+fTbDbzwnP7MjI8UPRIAACw5QQtgJ9h7/jOHNi/O7VaPZ/85XzR48B3TE3P5tzXN1KpVPLrN5939BAAgGee73gBHuH7Rw3nF5YLngj+2qnTVxw9BABg2xC0AB7BUUPKoNFo5qNPzjl6CADAtiBoAfyEbx81/NhRQ1rc9PRczp139BAAgGef73QBfsR3jxpeyoKjhpTAqTOOHgIA8OwTtAB+xInjh7511PBW0ePAz/Lto4fPH9uX/v6eokcCAIBNJ2gB/IC+vu4cOTyaZrOZTz+/UPQ48Fimp+dy+cpkqtVKXn7pUNHjAADAphO0AH7Ayy8dSrVazeWrk5mdXSx6HHhsp85cTb1ez/59uzI81F/0OAAAsKkELYDvGRrsy4H9u1OvN3L6zNWix4EnsrS0kq8v3EySnHz5cLHDAADAJhO0AL7n5ROHkyQXLt7M4uJKscPAL3D2/PWsrNSyZ/dQ9uweKnocAADYNIIWwLfs3jWYsdHhrK7Wcvbc9aLHgV9kdbWes+evJbGlBQDAs0XQAviWk+vbWWfPX8/Kaq3YYWATXLg4kcXF5QwP9Wf/vl1FjwMAAJtC0AJYt3d8Z0ZGBrL4rbuHoOy+fRfcyy8dSqVSKXgiAAD45QQtgCSVSnLyxKEkyZkzV1OvNwqeCDbP2qt1LqS/vyeHD40WPQ4AAPxighZAkvGxkQwM9GZufjGXrkwWPQ5sqmYz+er02pbWC8/tK3gaAAD45dqLHgCgFRw9Mp5k7b6hZrNZ8DTl155kINWMpC3tqaSWZqZSz2wacTNZMW7cvJv5haX09/dkdM9QJm/PFD0SAAA8MRtawLbX39ed0T3DqdXquXLVdtYv1Z1KjqQzu9OeepKFNFNPsjvtOZLOdMcdTkW5dOlWkm8CLgAAlJWgBWx7D/9wf+36nayu1gueptzakxxIR2ppZnE9ZCVJPclimqmlmQPpsB5ckMtXJtNoNDI+NpLenq6ixwEAgCcmaAHbWltbNYfWL8m+eGmi4GnKbyDVVJIfPVZYS1JZfxxP3/LKaq7fuJtKpZIjh8eKHgcAAJ6YP1EA29qB/bvT2dGee1MPMnN/vuhxSm8kbVnJT99BtpJmRtL2lCbi+x6G28OHRlOtOv4JAEA5CVrAtvbwuKHtrM3RnkoedWizvv44inFvajYz9+fT3d2ZveM7ix4HAACeiKAFbFvDw/0ZHurP8vLaMSx+uVqaj9y9alt/HMV5GHCPuRweAICSErSAbevhH+bXLsoWWDbDVOrpfMT2VWcqmXrkHhdb6eq121ldrWXXrsHs2NFb9DgAAPDYBC1gW2prq2b/vl1JkkuXHTfcLLNppJn86KsYtidprj+O4tTrjVy9djtJcvjgaMHTAADA4xO0gG1pdM9Q2tracm/qQeYXlose55lRS3Itq2lPJT2pbBw/bEvSk0raU8m1rP7oqyDy9Fy7vnbMdnxspOBJAADg8QlawLY0PrZ2GfbEramCJ3n2LKWZS1nJndTSlqR3PWzdSS2XspIl92e1hHtTD7K8vJr+/p4MDPQUPQ4AADwWQQvYlsbGhpMkExOC1laoJZlOIxeymrNZyYWsZjoNm1ktZmJy7e9/W1oAAJSNoAVsOyPDA+nu6sz8/FIezC4UPQ4U5mHQfbixCAAAZSFoAdvO+PjaNorjhmx3k7enU683snNkIF2dHUWPAwAAP5ugBWw7e9ePV92cuFfwJFCser2RO3dnUqlUNo7hAgBAGQhawLbS19udHTv6srJay917D4oeBwr3zbFD92gBAFAeghawrTw8bjg5OZ1m06vtwcOjt6N7hlOtVgqeBgAAfh5BC9hWxh03hO9YXFrJ9Mxc2tvbsmf3UNHjAADAzyJoAdtGpbL2CodJcvv2TMHTQOuYnJxOkuwc2VHwJAAA8PMIWsC2MTDQm/b2tszPL2VltVb0ONAypmfmkiTDQ/0FTwIAAD+PoAVsGw//sD49M1vwJNBaHgatIUELAICSELSAbeOboDVX8CTQWhYXl7O8vJquro709nYVPQ4AADySoAVsGw+3T2YELfgrtrQAACgTQQvYFiqVZHBHX5Jkema+4Gmg9TwMvcODghYAAK1P0AK2hW9fCL/qQnj4Ky6GBwCgTAQtYFtwITz8NEcOAQAoE0EL2BZcCA8/zcXwAACUiaAFbAtDgy6Eh0fZ2NJyjxYAAC1O0AK2hYcbJ7NziwVPAq1rbv2fjz4bWgAAtDhBC9gWurs7kyRLS6sFTwKta3FpOck3/7wAAECrErSAZ153V0cqlUqWllfSbDaLHgda1sPgK2gBANDq2oseAGCr2c6Cn2dpaSWJoAUAPF2dne0Z6O9JW1s1bW1tqVYraTSaqdcbqTcaWVhYyuLiStFj0mIELeCZ903QWi54Emhti+tBq0fQAgC2SGdne4aH+jM01L/x177e7kf+vKXllcxMz2X6/lxmZuYyPT238b0L25OgBTzzbGjBz2NDCwDYCm1t1Rw8sCdHj4z94Ksp12r1PJhdSK1WT73eSKPRSLVaTbVaSXtbWwYGetLd1ZmxsZGMjY1s/Lz5+aVcvHwrV65MZnnF9/rbjaAFPPN6NoKW/4IDP2V1tZZ6vZGOjva0tVVTrzeKHgkAKLGBgZ4cPTKeQwf2pKNjLT/UavXM3J/LzMx8pmfmMj0zm9nZR78SeV9v13e2uoaH+tPX151XXj6cE8cP5sbNu7lwaSJTU7Nb/WXRIgQt4Jn3cNvESjI82tLSSvr6utPd3Zn5+aWixwEASmjP7qG8+ML+7Nk9tPG+u3fv58KlidycuJdG4/FfqGl+YTnzC8u5cfPexvtG9wzl6JHxjI+N5OCBPTl4YE9m7s/n/NfXc/XanU35WmhdghbwzOu2odVSKpVK9u3dmZGRgbRVq1laXs3163cyO/fo/zLH1nsYtHoELQDgMbW3t+XVV47kyKGxJGvbWFev3c6FSxN58GBh059v8vZMJm/PpLe3K0cOjeXw4dEMDfblrV+9mAP79+STT8+7TP4ZJmgBzzxBq3UcOzKeF1888FeXjp84fjC378zkk0+/FlEKtrTsHi0A4PGN7hnKm68/n97ertTrjZw+ezUXLk6kVqtv+XMvLCznq9NXcvrs1RzYvyevnDycsdHh/N/fv5nPv7yUy1cmt3wGnj5BC3jmtbe1JUlWa7WCJ9neXj5xKMdfOPCDH2s2m9mzeyj/8LvX8p///bltrQKtrq5909m2/s8NAMBP+f5W1tTUbD765Fwh3881Gs1cuTqZW5NTefP157J3fGd+9cbz2b93Vz7+9OssLnrV82dJtegBALZapVpJkjSf4Kw+m2Pv+EiOv3AgzeYP/xpUKmu/Rl1dHfmbd048zdH4noe/RtX1f24AAH7MQH9P/s/v38iRQ2Op1xv54stL+Y///qzw/zi5vLya994/nQ8+OpvlldWMjg7n//7+jezZPVjoXGwuQQt45lXXY8mPxRS23nPH9iX5Jlz9lIH+noyNDm/1SPyIh5e0/pxfKwBg+xoa7Mv/+rtX09fbnanp2fzrv/8l576+kVb6lvva9Tv5l3/9JDcn7qWjoz2/fefl7B3fWfRYbBJBC3jmPfyDuQWtYvT3dWf3rsHHCopHDo9t4UT8lI0NLUELAPgRIyMD+d27r6SrqyMTt6byX3/8ovCtrB/zcFvr6ws309ZWzTu/OZ4D+3cXPRaboKXv0PrDP75b9AjAM+T//X/eKnqEbe1xNn72ju/0e0DBXnv1aF579WjRYwAALWZwsC9/+zcvp6OjPdeu38mHH58rxUmIz764mNXVWl46fjC/fvOF1Gr1TNyaKnosfgEbWgAAAMAj9fd1593fvpzOjvZcv3E3H3x0thQx66FTZ67m9NmrqVYrefut49m9y51aZdaSG1r/9M9/LHoEAAAAYF21Wsk7b7+U7q7OTE5O58OPzxY90hM5dfpqOjvac+zo3rz9m+P5l3/9JMvLq0WPxROwoQUAAAD8pJdePJjBHX2ZnVvMex+c3nghmTL69POLmZycTldnR958/bmix+EJCVoAAADAjxoa6s8Lz+9Ps9nMx5+cS73eKHqkX+zjT89ndbWWveM7XRJfUoIWAAAA8IOq1Up+/ebzqVYrOX/hZu5NzRY90qZYXFzJ519eSpK8/urRdHd1FDwRj0vQAgAAAH7Qt48anjp9ZdM/fyVJZyrZkUqGUs2OVNKZSn7+62M/uctXJnNrciqdnR15w9HD0hG0AAAAgL8yMNCzpUcN25LsSDW9qaSRSlaTNFJJbyrZkWraNvXZftgnf/l64+jh3vGdT+EZ2SyCFgAAAPBXjh3Zm2q1kstXJjf9qGElSX+qaSRZTfLwivnm+tuN9Y9v9abW4tJKvlrfPHvu2N4tfjY2k6AFAAAAfEd7e1sOHli7LP38hZub/vk71o8V/tjOVyNr0avjKRw+vHL1dlZXa9m9azA7Bnq3/PnYHIIWAAAA8B0HD+xOR0d77ty9n9nZhU3//N1Jao94TG39cVutVqvn6rXbSZKjR8aewjOyGQQtAAAA4DuOHhlPkly4OLEln7+aysYxwx/TXH/c03Dx0q0kycEDe9Le/jRu7+KXErQAAACADbt27sjgjr4sLq3k5sS9LXmORpqPTFWV9cc9DQ9mF3Ln7v10dLTn4P7dT+U5+WUELQAAAGDD4UNrx+4uX76VZnNrgtJSkvZHPKZ9/XFPy8VLa9tohw87dlgGghYAAACwYefIQJLkxs2t2c5KktU0148U/rBqHr7i4dPZ0EqSmxP30mg0MjTYl7Y2uaTV+RUCAAAAkiQdHW3p7+9JvV7Pg9n5LXueZpK5NFJN0pFsHD+srL9dXf/408tZSaPRzIPZhVQqlQwN9j3FZ+ZJCFoAAABAkmRosD9JMnN/Plt02nBDPcmDNLKQZqpproesZhbSzIM0Ut/ap/9B0zNzSZKhof4Cnp3H8agjqwAAAMA2MbwecmbWw85WayZZSTMrG28Va2ZmLjn0zf8PtC4bWgAAAECSbzaTpme27rhhK7OhVR6CFgAAAJDkm82k6ZnZgicpxv37C2k0Gtkx0Oti+BbnVwcAAABIkvT0dCVJ5ueXCnn+3bsG8/yxvdm7d2chz99oNLK4uJJKpZLurs5CZuDncYcWAAAAkCQbW0n1euOpP/fxFw7k5ROHNt6+eu12Pvz43FOfo15fu47ehlZrq7z2mz8Uf+saAAAAPMIf/vHdokcANtE//fMfn/jnyo0AAAAAlIoNLQAAAABKxYYWAAAAAKUiaAEAAABQKoIWAAAAAKUiaAEAAABQKoIWAAAAAKUiaAEAAABQKv8/zvAtRj22TeoAAAAASUVORK5CYII=\n", 234 | "text/plain": [ 235 | "
" 236 | ] 237 | }, 238 | "metadata": {}, 239 | "output_type": "display_data" 240 | } 241 | ], 242 | "source": [ 243 | "pad = 1/72\n", 244 | "figsize1 = 1536/72\n", 245 | "figsize2 = 1125/72\n", 246 | "fig = plt.figure(figsize=(figsize1, figsize2),facecolor='#2f3653') \n", 247 | "gs = gridspec.GridSpec(2, 2, width_ratios=[3.13, 1])\n", 248 | "ax1 = plt.subplot(gs[:, 0])\n", 249 | "ax2 = plt.subplot(gs[0, 1])\n", 250 | "ax3 = plt.subplot(gs[1, 1])\n", 251 | "pitch = Pitch(pitch_type='opta',orientation='vertical',view='half',layout=(1,1),figsize=(10,10),\n", 252 | " pitch_color='#2f3653',line_color='#82868f',goal_type='box',linewidth=2,\n", 253 | " pad_bottom=0.2,pad_top=4)\n", 254 | "pitch.draw(ax1)\n", 255 | "pitch.draw(ax2)\n", 256 | "pitch.draw(ax3)\n", 257 | "#plot lines\n", 258 | "pitch.lines(df_line.x_pass_start,df_line.y_pass_start,df_line.x_pass_end,df_line.y_pass_end,\n", 259 | " lw=9,transparent=True,comet=True,ax=ax1)\n", 260 | "pitch.lines(df_line.x_pass_start,df_line.y_pass_start,df_line.x_pass_end,df_line.y_pass_end,\n", 261 | " lw=9,transparent=True,comet=True,ax=ax2)\n", 262 | "# plot assists\n", 263 | "pitch.plot(df_assist.x_pass_end,df_assist.y_pass_end,\n", 264 | " marker='o', color='None',markersize=12,markerfacecolor='#34afed',\n", 265 | " linestyle='None',markeredgecolor='#34afed',ax=ax1)\n", 266 | "pitch.plot(df_assist.x_pass_end,df_assist.y_pass_end,\n", 267 | " marker='o', color='None',markersize=7,markerfacecolor='#34afed',\n", 268 | " linestyle='None',markeredgecolor='#34afed',ax=ax2)\n", 269 | "# plot other\n", 270 | "pitch.plot(df_other.x_pass_end,df_other.y_pass_end,markerfacecolor='#2f3653',\n", 271 | " marker='o', color='None',markersize=12,zorder=3,\n", 272 | " linestyle='None',markeredgecolor='#34afed',ax=ax1)\n", 273 | "pitch.plot(df_other.x_pass_end,df_other.y_pass_end,markerfacecolor='#2f3653',\n", 274 | " marker='o', color='None',markersize=7,zorder=3,\n", 275 | " linestyle='None',markeredgecolor='#34afed',ax=ax2)\n", 276 | "# plot pass start locations\n", 277 | "pitch.plot(df_pass.x_pass_start,df_pass.y_pass_start,\n", 278 | " marker='o', color='#a43967',markersize=10,alpha=0.25,linestyle='None',ax=ax1)\n", 279 | "pitch.plot(df_pass.x_pass_start,df_pass.y_pass_start,\n", 280 | " marker='o', color='#a43967',markersize=10,alpha=0.1,linestyle='None',ax=ax3)" 281 | ] 282 | } 283 | ], 284 | "metadata": { 285 | "kernelspec": { 286 | "display_name": "Python 3", 287 | "language": "python", 288 | "name": "python3" 289 | }, 290 | "language_info": { 291 | "codemirror_mode": { 292 | "name": "ipython", 293 | "version": 3 294 | }, 295 | "file_extension": ".py", 296 | "mimetype": "text/x-python", 297 | "name": "python", 298 | "nbconvert_exporter": "python", 299 | "pygments_lexer": "ipython3", 300 | "version": "3.8.2" 301 | } 302 | }, 303 | "nbformat": 4, 304 | "nbformat_minor": 2 305 | } 306 | -------------------------------------------------------------------------------- /01_statsbomb_json_to_feather.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas as pd\n", 10 | "import numpy as np\n", 11 | "import glob\n", 12 | "import os" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "This notebook takes the StatsBomb json files and turns them into feather files. These are extremely fast to load so good for this prototyping kind of analysis. See: https://medium.com/@steven.p.dye/feather-files-faster-than-the-speed-of-light-d4666ce24387.\n", 20 | "\n", 21 | "They are not really meant for long term storage though. The event files are then combined from all the matches." 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "# Change these paths/ parameters\n", 29 | "You will need to change these paths/ parameters depending on where the StatsBomb open-data is located, how and where you want to save the resulting data, and if you only want the new files to be processed." 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 2, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "# open data folder is one folder down in the directory. To change if run elsewhere\n", 39 | "STATSBOMB_DATA = os.path.join('..','open-data','data')\n", 40 | "# save files in folder in current directory. To change if want to save elsewhere\n", 41 | "DATA_PATH = os.path.join(os.getcwd(),'data')\n", 42 | "# if true, only processes files that don't already have a event file\n", 43 | "process_new_only = True" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "# Delete event data included in error" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "One event file seems to be added to the statsbomb data in error. See: https://github.com/statsbomb/open-data/issues/13. Deleting it here for consistency." 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 3, 63 | "metadata": {}, 64 | "outputs": [ 65 | { 66 | "name": "stdout", 67 | "output_type": "stream", 68 | "text": [ 69 | "../open-data/data/events/7298.json removed\n", 70 | "../open-data/data/lineups/7298.json removed\n" 71 | ] 72 | } 73 | ], 74 | "source": [ 75 | "ERROR_FILES = [os.path.join(STATSBOMB_DATA,'events','7298.json'),\n", 76 | " os.path.join(STATSBOMB_DATA,'lineups','7298.json')]\n", 77 | "for file in ERROR_FILES:\n", 78 | " if os.path.isfile(file):\n", 79 | " os.remove(file)\n", 80 | " print(file,'removed')" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "# Setup folders" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "I set up the following folders in a new data directory folder (location set above). These are the places we will save the processed json files, in feather-format.
\n", 95 | "├── data
\n", 96 | "│ ├── events_raw <- Data from the event file
\n", 97 | "│ ├── related_events_raw <- Data with the info on how events are connected.
\n", 98 | "│ ├── shot_freeze_raw <- DAta with the individual shot freeze frames
\n", 99 | "│ └── tactics_raw <- Data with the lineup tactics.
" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 4, 105 | "metadata": {}, 106 | "outputs": [], 107 | "source": [ 108 | "def make_dir(PATH):\n", 109 | " if os.path.isdir(PATH)==False: os.mkdir(PATH)" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 5, 115 | "metadata": {}, 116 | "outputs": [], 117 | "source": [ 118 | "# locations of new folders\n", 119 | "RAW_EVENT_PATH = os.path.join(DATA_PATH,'events_raw')\n", 120 | "RAW_RELATED_PATH = os.path.join(DATA_PATH,'related_events_raw')\n", 121 | "RAW_SHOT_PATH = os.path.join(DATA_PATH,'shot_freeze_raw')\n", 122 | "RAW_TACTICS_PATH = os.path.join(DATA_PATH,'tactics_raw')" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 6, 128 | "metadata": {}, 129 | "outputs": [], 130 | "source": [ 131 | "# making directories\n", 132 | "make_dir(DATA_PATH)\n", 133 | "make_dir(RAW_EVENT_PATH)\n", 134 | "make_dir(RAW_RELATED_PATH)\n", 135 | "make_dir(RAW_SHOT_PATH)\n", 136 | "make_dir(RAW_TACTICS_PATH)" 137 | ] 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "metadata": {}, 142 | "source": [ 143 | "# Get file paths" 144 | ] 145 | }, 146 | { 147 | "cell_type": "markdown", 148 | "metadata": {}, 149 | "source": [ 150 | "Retrieve a list of json file paths from which we will extract the infomation." 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": 7, 156 | "metadata": {}, 157 | "outputs": [], 158 | "source": [ 159 | "MATCH_PATH = glob.glob(os.path.join(STATSBOMB_DATA,'matches','**','*.json'),recursive=True)\n", 160 | "LINEUP_PATH = glob.glob(os.path.join(STATSBOMB_DATA,'lineups','**','*.json'),recursive=True)\n", 161 | "EVENT_PATH = glob.glob(os.path.join(STATSBOMB_DATA,'events','**','*.json'),recursive=True)\n", 162 | "COMPETITION_PATH = os.path.join(STATSBOMB_DATA,'competitions.json')" 163 | ] 164 | }, 165 | { 166 | "cell_type": "markdown", 167 | "metadata": {}, 168 | "source": [ 169 | "# Format competition data" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": {}, 175 | "source": [ 176 | "Get the competition data and save in feather format." 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 8, 182 | "metadata": {}, 183 | "outputs": [ 184 | { 185 | "name": "stdout", 186 | "output_type": "stream", 187 | "text": [ 188 | "Number of competitions in data: 20\n" 189 | ] 190 | } 191 | ], 192 | "source": [ 193 | "df_competition = pd.read_json(COMPETITION_PATH,convert_dates=['match_updated','match_available'])\n", 194 | "df_competition.sort_values(['competition_id','season_id'],inplace=True)\n", 195 | "df_competition.reset_index(drop=True,inplace=True)\n", 196 | "print('Number of competitions in data:',len(df_competition))" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": 9, 202 | "metadata": {}, 203 | "outputs": [ 204 | { 205 | "name": "stdout", 206 | "output_type": "stream", 207 | "text": [ 208 | "\n", 209 | "RangeIndex: 20 entries, 0 to 19\n", 210 | "Data columns (total 8 columns):\n", 211 | "competition_id 20 non-null int64\n", 212 | "season_id 20 non-null int64\n", 213 | "country_name 20 non-null object\n", 214 | "competition_name 20 non-null object\n", 215 | "competition_gender 20 non-null object\n", 216 | "season_name 20 non-null object\n", 217 | "match_updated 20 non-null datetime64[ns]\n", 218 | "match_available 20 non-null datetime64[ns]\n", 219 | "dtypes: datetime64[ns](2), int64(2), object(4)\n", 220 | "memory usage: 1.4+ KB\n" 221 | ] 222 | } 223 | ], 224 | "source": [ 225 | "# save to feather-format and show info\n", 226 | "df_competition.to_feather(os.path.join(DATA_PATH,'competition'))\n", 227 | "df_competition.info()" 228 | ] 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "metadata": {}, 233 | "source": [ 234 | "# Format match data" 235 | ] 236 | }, 237 | { 238 | "cell_type": "markdown", 239 | "metadata": {}, 240 | "source": [ 241 | "Get the match data and save in feather format." 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": 10, 247 | "metadata": {}, 248 | "outputs": [ 249 | { 250 | "name": "stdout", 251 | "output_type": "stream", 252 | "text": [ 253 | "Number of match files in data: 20\n", 254 | "Number of matches in data: 778\n" 255 | ] 256 | } 257 | ], 258 | "source": [ 259 | "print('Number of match files in data:',len(MATCH_PATH))\n", 260 | "match_list_dfs = [pd.read_json(file,convert_dates=['match_date','last_updated']) for file in MATCH_PATH]\n", 261 | "df_match = pd.concat(match_list_dfs,sort=False)\n", 262 | "print('Number of matches in data:',len(df_match))" 263 | ] 264 | }, 265 | { 266 | "cell_type": "code", 267 | "execution_count": 11, 268 | "metadata": {}, 269 | "outputs": [], 270 | "source": [ 271 | "def split_dict_col(df,col):\n", 272 | " '''function to split a dictionary column to seperate columns'''\n", 273 | " # handle missings by filling with an empty dictionary\n", 274 | " df[col] = df[col].apply(lambda x: {} if pd.isna(x) else x)\n", 275 | " # split the non missings and change column names\n", 276 | " df_temp_cols = pd.io.json.json_normalize(df[col]).set_index(df.index)\n", 277 | " col_names = df_temp_cols.columns\n", 278 | " # note add column description to column name if doesn't already contain it\n", 279 | " col_names = [(c).replace('.','_') if c[:len(col)]==col else (col+'_'+c).replace('.','_') for c in col_names]\n", 280 | " df[col_names] = df_temp_cols\n", 281 | " # drop old column\n", 282 | " df.drop(col,axis=1,inplace=True)\n", 283 | " return df" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": 12, 289 | "metadata": {}, 290 | "outputs": [], 291 | "source": [ 292 | "# loop through the columns that are still dictionary columns and add them as seperate cols to the dataframe\n", 293 | "dictionary_columns = ['competition','season','home_team','away_team','metadata','competition_stage',\n", 294 | " 'stadium','referee']\n", 295 | "for col in dictionary_columns:\n", 296 | " df_match = split_dict_col(df_match,col)\n", 297 | "# convert kickoff to datetime - date + kickoff time\n", 298 | "df_match['kick_off'] = pd.to_datetime(df_match.match_date.astype(str) +' '+ df_match.kick_off)\n", 299 | "# drop one gender column as always equal to the other\n", 300 | "# drop match status as always available\n", 301 | "df_match.drop(['away_team_gender','match_status'],axis=1,inplace=True)\n", 302 | "df_match.rename({'home_team_gender':'competition_gender'},axis=1,inplace=True)\n", 303 | "# manager is a list (len=1) containing a dictionary so lets split into columns\n", 304 | "df_match['home_team_managers'] = df_match.home_team_managers.str[0]\n", 305 | "df_match = split_dict_col(df_match,'home_team_managers')\n", 306 | "df_match['away_team_managers'] = df_match.away_team_managers.str[0]\n", 307 | "df_match = split_dict_col(df_match,'away_team_managers')\n", 308 | "df_match['home_team_managers_dob'] = pd.to_datetime(df_match['home_team_managers_dob'])\n", 309 | "df_match['away_team_managers_dob'] = pd.to_datetime(df_match['away_team_managers_dob'])\n", 310 | "for col in ['competition_id','season_id','home_team_id','competition_stage_id']:\n", 311 | " df_match[col] = df_match[col].astype(np.int64)\n", 312 | "# sort and reset index: ready for exporting to feather\n", 313 | "df_match.sort_values('kick_off',inplace=True)\n", 314 | "df_match.reset_index(inplace=True,drop=True)" 315 | ] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "execution_count": 13, 320 | "metadata": {}, 321 | "outputs": [ 322 | { 323 | "name": "stdout", 324 | "output_type": "stream", 325 | "text": [ 326 | "\n", 327 | "RangeIndex: 778 entries, 0 to 777\n", 328 | "Data columns (total 48 columns):\n", 329 | "match_id 778 non-null int64\n", 330 | "match_date 778 non-null datetime64[ns]\n", 331 | "kick_off 778 non-null datetime64[ns]\n", 332 | "home_score 778 non-null int64\n", 333 | "away_score 778 non-null int64\n", 334 | "last_updated 778 non-null datetime64[ns]\n", 335 | "match_week 778 non-null int64\n", 336 | "competition_id 778 non-null int64\n", 337 | "competition_country_name 778 non-null object\n", 338 | "competition_name 778 non-null object\n", 339 | "season_id 778 non-null int64\n", 340 | "season_name 778 non-null object\n", 341 | "home_team_id 778 non-null int64\n", 342 | "home_team_name 778 non-null object\n", 343 | "competition_gender 778 non-null object\n", 344 | "home_team_group 100 non-null object\n", 345 | "home_team_country_id 777 non-null float64\n", 346 | "home_team_country_name 777 non-null object\n", 347 | "away_team_id 778 non-null int64\n", 348 | "away_team_name 778 non-null object\n", 349 | "away_team_group 100 non-null object\n", 350 | "away_team_country_id 776 non-null float64\n", 351 | "away_team_country_name 776 non-null object\n", 352 | "metadata_data_version 778 non-null object\n", 353 | "metadata_shot_fidelity_version 591 non-null object\n", 354 | "metadata_xy_fidelity_version 501 non-null object\n", 355 | "competition_stage_id 778 non-null int64\n", 356 | "competition_stage_name 778 non-null object\n", 357 | "stadium_id 680 non-null float64\n", 358 | "stadium_name 680 non-null object\n", 359 | "stadium_country_id 549 non-null float64\n", 360 | "stadium_country_name 549 non-null object\n", 361 | "referee_id 732 non-null float64\n", 362 | "referee_name 732 non-null object\n", 363 | "referee_country_id 325 non-null float64\n", 364 | "referee_country_name 325 non-null object\n", 365 | "home_team_managers_id 520 non-null float64\n", 366 | "home_team_managers_name 520 non-null object\n", 367 | "home_team_managers_nickname 173 non-null object\n", 368 | "home_team_managers_dob 436 non-null datetime64[ns]\n", 369 | "home_team_managers_country_id 520 non-null float64\n", 370 | "home_team_managers_country_name 520 non-null object\n", 371 | "away_team_managers_id 520 non-null float64\n", 372 | "away_team_managers_name 520 non-null object\n", 373 | "away_team_managers_nickname 163 non-null object\n", 374 | "away_team_managers_dob 438 non-null datetime64[ns]\n", 375 | "away_team_managers_country_id 520 non-null float64\n", 376 | "away_team_managers_country_name 520 non-null object\n", 377 | "dtypes: datetime64[ns](5), float64(10), int64(9), object(24)\n", 378 | "memory usage: 291.9+ KB\n" 379 | ] 380 | } 381 | ], 382 | "source": [ 383 | "# save to feather-format and show info\n", 384 | "df_match.to_feather(os.path.join(DATA_PATH,'match'))\n", 385 | "df_match.info()" 386 | ] 387 | }, 388 | { 389 | "cell_type": "markdown", 390 | "metadata": {}, 391 | "source": [ 392 | "# Format lineup data" 393 | ] 394 | }, 395 | { 396 | "cell_type": "markdown", 397 | "metadata": {}, 398 | "source": [ 399 | "Get the lineup data and save in feather format." 400 | ] 401 | }, 402 | { 403 | "cell_type": "code", 404 | "execution_count": 14, 405 | "metadata": {}, 406 | "outputs": [ 407 | { 408 | "name": "stdout", 409 | "output_type": "stream", 410 | "text": [ 411 | "Number of lineup files in data: 778\n" 412 | ] 413 | } 414 | ], 415 | "source": [ 416 | "print('Number of lineup files in data:',len(LINEUP_PATH))\n", 417 | "# read as dataframe can't use list comprehension to read files as need to create the match_id from the file name\n", 418 | "lineup_list_dfs = []\n", 419 | "for file in LINEUP_PATH:\n", 420 | " df_temp = pd.read_json(file)\n", 421 | " df_temp['match_id'] = os.path.basename(file[:-5])\n", 422 | " lineup_list_dfs.append(df_temp)\n", 423 | "df_lineup = pd.concat(lineup_list_dfs,sort=False)\n", 424 | "df_lineup.reset_index(inplace=True,drop=True)\n", 425 | "# each line has a column named player that contains a list of dictionaries\n", 426 | "# we split into seperate columns and then create a new row for each player using melt\n", 427 | "df_lineup_players = df_lineup.lineup.apply(pd.Series)\n", 428 | "df_lineup = df_lineup.merge(df_lineup_players,left_index=True,right_index=True)\n", 429 | "df_lineup.drop('lineup',axis=1,inplace=True)\n", 430 | "df_lineup = df_lineup.melt(id_vars = ['team_id','team_name','match_id'], value_name = 'player')\n", 431 | "df_lineup.drop('variable',axis=1,inplace=True)\n", 432 | "df_lineup = df_lineup[df_lineup.player.notnull()].copy()\n", 433 | "df_lineup = split_dict_col(df_lineup,'player')\n", 434 | "# turn ids to integers if no missings\n", 435 | "df_lineup['match_id'] = df_lineup.match_id.astype(np.int64)\n", 436 | "df_lineup['player_id'] = df_lineup.player_id.astype(np.int64)\n", 437 | "# sort and reset index: ready for exporting to feather\n", 438 | "df_lineup.sort_values('player_id',inplace=True)\n", 439 | "df_lineup.reset_index(inplace=True,drop=True)" 440 | ] 441 | }, 442 | { 443 | "cell_type": "code", 444 | "execution_count": 15, 445 | "metadata": {}, 446 | "outputs": [ 447 | { 448 | "name": "stdout", 449 | "output_type": "stream", 450 | "text": [ 451 | "\n", 452 | "RangeIndex: 21416 entries, 0 to 21415\n", 453 | "Data columns (total 9 columns):\n", 454 | "team_id 21416 non-null int64\n", 455 | "team_name 21416 non-null object\n", 456 | "match_id 21416 non-null int64\n", 457 | "player_id 21416 non-null int64\n", 458 | "player_name 21416 non-null object\n", 459 | "player_nickname 12156 non-null object\n", 460 | "player_jersey_number 21409 non-null float64\n", 461 | "player_country_id 21328 non-null float64\n", 462 | "player_country_name 21328 non-null object\n", 463 | "dtypes: float64(2), int64(3), object(4)\n", 464 | "memory usage: 1.5+ MB\n" 465 | ] 466 | } 467 | ], 468 | "source": [ 469 | "# save to feather-format and show info\n", 470 | "df_lineup.to_feather(os.path.join(DATA_PATH,'lineup'))\n", 471 | "df_lineup.info()" 472 | ] 473 | }, 474 | { 475 | "cell_type": "markdown", 476 | "metadata": {}, 477 | "source": [ 478 | "# Format event data" 479 | ] 480 | }, 481 | { 482 | "cell_type": "markdown", 483 | "metadata": {}, 484 | "source": [ 485 | "Get the event data and save in feather format:\n", 486 | " - an events dataframe\n", 487 | " - a related events dataframe\n", 488 | " - a shot freeze frame dataframe\n", 489 | " - a tactics lineup dataframe\n", 490 | " \n", 491 | "Each match is stored in a seperate dataframe" 492 | ] 493 | }, 494 | { 495 | "cell_type": "code", 496 | "execution_count": 16, 497 | "metadata": {}, 498 | "outputs": [], 499 | "source": [ 500 | "def list_dictionary_to_df(df,col,value_name,var_name):\n", 501 | " '''Some columns are a list of dictionaries. This turns them into a new dataframe of rows'''\n", 502 | " df = df.loc[df[col].notnull(),['id',col]]\n", 503 | " df.set_index('id',inplace=True)\n", 504 | " df = df[col].apply(pd.Series).copy()\n", 505 | " df.reset_index(inplace=True)\n", 506 | " df = df.melt(id_vars='id',value_name=value_name,var_name=var_name)\n", 507 | " df[var_name] = df[var_name] + 1\n", 508 | " df = df[df[value_name].notnull()].copy()\n", 509 | " df.reset_index(inplace=True,drop=True)\n", 510 | " return df" 511 | ] 512 | }, 513 | { 514 | "cell_type": "code", 515 | "execution_count": 17, 516 | "metadata": {}, 517 | "outputs": [], 518 | "source": [ 519 | "def split_location_cols(df,col,new_cols):\n", 520 | " ''' Location is stored as a list. split into columns'''\n", 521 | " if col in df.columns:\n", 522 | " df[new_cols] = df[col].apply(pd.Series)\n", 523 | " df.drop(col,axis=1,inplace=True)" 524 | ] 525 | }, 526 | { 527 | "cell_type": "code", 528 | "execution_count": 18, 529 | "metadata": {}, 530 | "outputs": [ 531 | { 532 | "name": "stdout", 533 | "output_type": "stream", 534 | "text": [ 535 | "Number of event files in data: 778\n" 536 | ] 537 | } 538 | ], 539 | "source": [ 540 | "print('Number of event files in data:',len(EVENT_PATH))" 541 | ] 542 | }, 543 | { 544 | "cell_type": "code", 545 | "execution_count": 19, 546 | "metadata": {}, 547 | "outputs": [ 548 | { 549 | "name": "stdout", 550 | "output_type": "stream", 551 | "text": [ 552 | "Matches with no event file: []\n", 553 | "Events with no match file: []\n" 554 | ] 555 | } 556 | ], 557 | "source": [ 558 | "EVENT_FILE_NAMES = np.array([os.path.basename(file)[:-5] for file in EVENT_PATH]).astype(int)\n", 559 | "# quick check that all events have matches and vice versa.\n", 560 | "print('Matches with no event file:',list(set(df_match.match_id) - set(EVENT_FILE_NAMES)))\n", 561 | "print('Events with no match file:',list(set(EVENT_FILE_NAMES) - set(df_match.match_id)))" 562 | ] 563 | }, 564 | { 565 | "cell_type": "code", 566 | "execution_count": 20, 567 | "metadata": {}, 568 | "outputs": [ 569 | { 570 | "name": "stdout", 571 | "output_type": "stream", 572 | "text": [ 573 | "Event files to process: 1\n" 574 | ] 575 | } 576 | ], 577 | "source": [ 578 | "# if you set process_new_only to True then we will not process event jsons which already have feather files\n", 579 | "if process_new_only:\n", 580 | " event_set = set([os.path.basename(file) for file in glob.glob(os.path.join(RAW_EVENT_PATH,'*'))])\n", 581 | " related_set = set([os.path.basename(file) for file in glob.glob(os.path.join(RAW_RELATED_PATH,'*'))])\n", 582 | " shot_set = set([os.path.basename(file) for file in glob.glob(os.path.join(RAW_SHOT_PATH,'*'))])\n", 583 | " tactics_set = set([os.path.basename(file) for file in glob.glob(os.path.join(RAW_TACTICS_PATH,'*'))])\n", 584 | " to_delete = set.intersection(event_set,related_set,shot_set,tactics_set)\n", 585 | " mask_delete = [False if file in to_delete else True for file in (EVENT_FILE_NAMES).astype(str)]\n", 586 | " EVENT_PATH = np.array(EVENT_PATH)[mask_delete].tolist()\n", 587 | " print('Event files to process:',np.array(mask_delete).sum())" 588 | ] 589 | }, 590 | { 591 | "cell_type": "code", 592 | "execution_count": 21, 593 | "metadata": {}, 594 | "outputs": [], 595 | "source": [ 596 | "def create_event_feather_files(PATH):\n", 597 | " ''' Extracts individual event jsons and loads as four feather-format files: events, related events,\n", 598 | " shot freeze frames, and tactics lineups'''\n", 599 | " # timestamp defaults to today's date so store as a string - feather can't store time objects\n", 600 | " df = pd.read_json(PATH,encoding='utf-8')\n", 601 | " df['timestamp'] = df['timestamp'].dt.time.astype(str)\n", 602 | " \n", 603 | " # get match id\n", 604 | " match_id = int(os.path.basename(PATH)[:-5])\n", 605 | " \n", 606 | " # loop through the columns that are still dictionary columns and add them as seperate cols to the dataframe\n", 607 | " # these are nested dataframes in the docs - although dribbled_past/ pressure isn't needed here?\n", 608 | " # also some others are needed: type, possession_team, play_pattern, team, tactics, player, pposition\n", 609 | " dictionary_columns = ['50_50','bad_behaviour','ball_receipt','ball_recovery','block','carry',\n", 610 | " 'clearance','dribble','duel','foul_committed','foul_won','goalkeeper',\n", 611 | " 'half_end','half_start','injury_stoppage','interception',\n", 612 | " 'miscontrol','pass','play_pattern','player','player_off','position',\n", 613 | " 'possession_team','shot','substitution','tactics','team','type',] \n", 614 | " for col in dictionary_columns:\n", 615 | " if col in df.columns:\n", 616 | " df = split_dict_col(df,col)\n", 617 | " \n", 618 | " # sort and reset index: ready for exporting to feather\n", 619 | " df.sort_values(['minute','second','timestamp','possession'],inplace=True)\n", 620 | " df.reset_index(inplace=True,drop=True)\n", 621 | " \n", 622 | " # split location info to x, y and (z for shot) columns and drop old columns\n", 623 | " split_location_cols(df,'location',['x','y'])\n", 624 | " split_location_cols(df,'pass_end_location',['pass_end_x','pass_end_y'])\n", 625 | " split_location_cols(df,'carry_end_location',['carry_end_x','carry_end_y'])\n", 626 | " split_location_cols(df,'shot_end_location',['shot_end_x','shot_end_y','shot_end_z'])\n", 627 | " split_location_cols(df,'goalkeeper_end_location',['goalkeeper_end_x','goalkeeper_end_y'])\n", 628 | " \n", 629 | " # replace weird * character in the type_name for ball receipt\n", 630 | " df['type_name'] = df['type_name'].replace({'Ball Receipt*':'Ball Receipt'})\n", 631 | " \n", 632 | " # create a related events dataframe\n", 633 | " df_related_events = list_dictionary_to_df(df,col='related_events',\n", 634 | " value_name='related_event',var_name='event_related_id')\n", 635 | " # some carries don't have the corresponding events. This makes sure all events are linked both ways\n", 636 | " df_related_events.drop('event_related_id',axis=1,inplace=True)\n", 637 | " df_related_events_reverse = df_related_events.rename({'related_event':'id','id':'related_event'},axis=1)\n", 638 | " df_related_events = pd.concat([df_related_events,df_related_events_reverse],sort=False)\n", 639 | " df_related_events.drop_duplicates(inplace=True)\n", 640 | " # and add on the type_names, index for easier lookups of how the events are related\n", 641 | " df_event_type = df[['id','type_name','index']].copy()\n", 642 | " df_related_events = df_related_events.merge(df_event_type,on='id',how='left',validate='m:1')\n", 643 | " df_event_type.rename({'id':'related_event'},axis=1,inplace=True)\n", 644 | " df_related_events = df_related_events.merge(df_event_type,on='related_event',\n", 645 | " how='left',validate='m:1',suffixes=['','_related'])\n", 646 | " df_related_events.rename({'related_event':'id_related'},axis=1,inplace=True)\n", 647 | " \n", 648 | " # create a shot freeze frame dataframe - also splits dictionary of player details into columns\n", 649 | " df_shot_freeze = list_dictionary_to_df(df,col='shot_freeze_frame',\n", 650 | " value_name='player',var_name='event_freeze_id')\n", 651 | " df_shot_freeze = split_dict_col(df_shot_freeze,'player')\n", 652 | " split_location_cols(df_shot_freeze,'player_location',['x','y'])\n", 653 | "\n", 654 | " # create a tactics lineup frame dataframe - also splits dictionary of player details into columns\n", 655 | " df_tactics_lineup = list_dictionary_to_df(df,col='tactics_lineup',\n", 656 | " value_name='player',var_name='event_tactics_id')\n", 657 | " df_tactics_lineup = split_dict_col(df_tactics_lineup,'player')\n", 658 | " \n", 659 | " # drop columns stored as a seperate table \n", 660 | " df.drop(['related_events','shot_freeze_frame','tactics_lineup'],axis=1,inplace=True)\n", 661 | " \n", 662 | " # add match id to dataframes\n", 663 | " df['match_id'] = match_id\n", 664 | " df_related_events['match_id'] = match_id\n", 665 | " df_shot_freeze['match_id'] = match_id \n", 666 | " df_tactics_lineup['match_id'] = match_id\n", 667 | " \n", 668 | " # save as feather files\n", 669 | " df.to_feather(os.path.join(RAW_EVENT_PATH,str(match_id)))\n", 670 | " df_related_events.to_feather(os.path.join(RAW_RELATED_PATH,str(match_id)))\n", 671 | " df_shot_freeze.to_feather(os.path.join(RAW_SHOT_PATH,str(match_id)))\n", 672 | " df_tactics_lineup.to_feather(os.path.join(RAW_TACTICS_PATH,str(match_id)))" 673 | ] 674 | }, 675 | { 676 | "cell_type": "code", 677 | "execution_count": 22, 678 | "metadata": {}, 679 | "outputs": [ 680 | { 681 | "name": "stdout", 682 | "output_type": "stream", 683 | "text": [ 684 | "0 2275036.json\n" 685 | ] 686 | } 687 | ], 688 | "source": [ 689 | "# loop through and save all the event jsons as 4 seperate feather-files\n", 690 | "for i, file in enumerate(EVENT_PATH):\n", 691 | " create_event_feather_files(file)\n", 692 | " if i%10 == 0:\n", 693 | " print(i,os.path.basename(file))" 694 | ] 695 | }, 696 | { 697 | "cell_type": "markdown", 698 | "metadata": {}, 699 | "source": [ 700 | "# Combine the raw dataframes and save as a single dataframe" 701 | ] 702 | }, 703 | { 704 | "cell_type": "markdown", 705 | "metadata": {}, 706 | "source": [ 707 | "Combine the event dataframes into a single dataframe for each type:\n", 708 | "- events\n", 709 | "- related_events\n", 710 | "- shot freeze frame\n", 711 | "- tactics\n", 712 | "\n", 713 | "Note that the resulting feather file will be large (3gb+)" 714 | ] 715 | }, 716 | { 717 | "cell_type": "code", 718 | "execution_count": 23, 719 | "metadata": {}, 720 | "outputs": [], 721 | "source": [ 722 | "def combine_single_file(PATH,SAVE_PATH):\n", 723 | " ''' loads individual feather files and combines into a mega feather file'''\n", 724 | " files = glob.glob(os.path.join(PATH,'*'))\n", 725 | " dfs = [pd.read_feather(file) for file in files]\n", 726 | " df = pd.concat(dfs,sort=False)\n", 727 | " if 'index' in df.columns:\n", 728 | " df.sort_values(['match_id','index'],inplace=True)\n", 729 | " df.reset_index(drop=True,inplace=True)\n", 730 | " print(df.info(verbose=True,null_counts=True))\n", 731 | " df.to_feather(SAVE_PATH)" 732 | ] 733 | }, 734 | { 735 | "cell_type": "code", 736 | "execution_count": 24, 737 | "metadata": {}, 738 | "outputs": [ 739 | { 740 | "name": "stderr", 741 | "output_type": "stream", 742 | "text": [ 743 | "/home/andy/anaconda3/envs/statsbomb-explore/lib/python3.7/site-packages/pyarrow/pandas_compat.py:752: FutureWarning: .labels was deprecated in version 0.24.0. Use .codes instead.\n", 744 | " labels, = index.labels\n" 745 | ] 746 | }, 747 | { 748 | "name": "stdout", 749 | "output_type": "stream", 750 | "text": [ 751 | "\n", 752 | "RangeIndex: 2797557 entries, 0 to 2797556\n", 753 | "Data columns (total 153 columns):\n", 754 | "id 2797557 non-null object\n", 755 | "index 2797557 non-null int64\n", 756 | "period 2797557 non-null int64\n", 757 | "timestamp 2797557 non-null object\n", 758 | "minute 2797557 non-null int64\n", 759 | "second 2797557 non-null int64\n", 760 | "possession 2797557 non-null int64\n", 761 | "duration 2046570 non-null float64\n", 762 | "off_camera 27283 non-null float64\n", 763 | "out 16363 non-null float64\n", 764 | "under_pressure 604676 non-null float64\n", 765 | "counterpress 86916 non-null float64\n", 766 | "ball_receipt_outcome_id 110299 non-null float64\n", 767 | "ball_receipt_outcome_name 110299 non-null object\n", 768 | "ball_recovery_offensive 298 non-null object\n", 769 | "ball_recovery_recovery_failure 6325 non-null object\n", 770 | "block_save_block 176 non-null object\n", 771 | "block_offensive 423 non-null object\n", 772 | "clearance_right_foot 7995 non-null object\n", 773 | "clearance_body_part_id 26528 non-null float64\n", 774 | "clearance_body_part_name 26528 non-null object\n", 775 | "clearance_left_foot 4733 non-null object\n", 776 | "clearance_head 13659 non-null object\n", 777 | "clearance_aerial_won 4886 non-null object\n", 778 | "dribble_outcome_id 32587 non-null float64\n", 779 | "dribble_outcome_name 32587 non-null object\n", 780 | "dribble_overrun 1948 non-null object\n", 781 | "duel_type_id 48472 non-null float64\n", 782 | "duel_type_name 48472 non-null object\n", 783 | "duel_outcome_id 30420 non-null float64\n", 784 | "duel_outcome_name 30420 non-null object\n", 785 | "foul_committed_offensive 921 non-null object\n", 786 | "foul_committed_type_id 1397 non-null float64\n", 787 | "foul_committed_type_name 1397 non-null object\n", 788 | "foul_committed_card_id 2492 non-null float64\n", 789 | "foul_committed_card_name 2492 non-null object\n", 790 | "foul_committed_penalty 229 non-null object\n", 791 | "foul_won_defensive 5429 non-null object\n", 792 | "foul_won_penalty 192 non-null object\n", 793 | "goalkeeper_type_id 23560 non-null float64\n", 794 | "goalkeeper_type_name 23560 non-null object\n", 795 | "goalkeeper_position_id 19906 non-null float64\n", 796 | "goalkeeper_position_name 19906 non-null object\n", 797 | "goalkeeper_outcome_id 11203 non-null float64\n", 798 | "goalkeeper_outcome_name 11203 non-null object\n", 799 | "goalkeeper_body_part_id 5730 non-null float64\n", 800 | "goalkeeper_body_part_name 5730 non-null object\n", 801 | "goalkeeper_technique_id 7702 non-null float64\n", 802 | "goalkeeper_technique_name 7702 non-null object\n", 803 | "half_start_late_video_start 32 non-null object\n", 804 | "interception_outcome_id 15212 non-null float64\n", 805 | "interception_outcome_name 15212 non-null object\n", 806 | "miscontrol_aerial_won 723 non-null object\n", 807 | "pass_length 769576 non-null float64\n", 808 | "pass_angle 769576 non-null float64\n", 809 | "pass_recipient_id 716166 non-null float64\n", 810 | "pass_recipient_name 716166 non-null object\n", 811 | "pass_height_id 769576 non-null float64\n", 812 | "pass_height_name 769576 non-null object\n", 813 | "pass_type_id 151071 non-null float64\n", 814 | "pass_type_name 151071 non-null object\n", 815 | "pass_body_part_id 724127 non-null float64\n", 816 | "pass_body_part_name 724127 non-null object\n", 817 | "pass_outcome_id 163709 non-null float64\n", 818 | "pass_outcome_name 163709 non-null object\n", 819 | "pass_cross 16541 non-null object\n", 820 | "pass_assisted_shot_id 13984 non-null object\n", 821 | "pass_shot_assist 12333 non-null object\n", 822 | "pass_switch 20890 non-null object\n", 823 | "pass_aerial_won 11234 non-null object\n", 824 | "pass_goal_assist 1651 non-null object\n", 825 | "pass_no_touch 507 non-null object\n", 826 | "pass_inswinging 1871 non-null object\n", 827 | "pass_technique_id 8987 non-null float64\n", 828 | "pass_technique_name 8987 non-null object\n", 829 | "pass_cut_back 1444 non-null object\n", 830 | "pass_straight 520 non-null object\n", 831 | "pass_through_ball 5002 non-null object\n", 832 | "pass_outswinging 1594 non-null object\n", 833 | "play_pattern_id 2797557 non-null int64\n", 834 | "play_pattern_name 2797557 non-null object\n", 835 | "player_id 2782289 non-null float64\n", 836 | "player_name 2782289 non-null object\n", 837 | "position_id 2782289 non-null float64\n", 838 | "position_name 2782289 non-null object\n", 839 | "possession_team_id 2797557 non-null int64\n", 840 | "possession_team_name 2797557 non-null object\n", 841 | "shot_statsbomb_xg 19934 non-null float64\n", 842 | "shot_key_pass_id 13984 non-null object\n", 843 | "shot_aerial_won 1209 non-null object\n", 844 | "shot_type_id 19934 non-null float64\n", 845 | "shot_type_name 19934 non-null object\n", 846 | "shot_body_part_id 19934 non-null float64\n", 847 | "shot_body_part_name 19934 non-null object\n", 848 | "shot_technique_id 19934 non-null float64\n", 849 | "shot_technique_name 19934 non-null object\n", 850 | "shot_outcome_id 19934 non-null float64\n", 851 | "shot_outcome_name 19934 non-null object\n", 852 | "shot_first_time 5275 non-null object\n", 853 | "shot_one_on_one 1239 non-null object\n", 854 | "substitution_outcome_id 4289 non-null float64\n", 855 | "substitution_outcome_name 4289 non-null object\n", 856 | "substitution_replacement_id 4294 non-null float64\n", 857 | "substitution_replacement_name 4294 non-null object\n", 858 | "tactics_formation 2929 non-null float64\n", 859 | "team_id 2797557 non-null int64\n", 860 | "team_name 2797557 non-null object\n", 861 | "type_id 2797557 non-null int64\n", 862 | "type_name 2797557 non-null object\n", 863 | "x 2775055 non-null float64\n", 864 | "y 2775055 non-null float64\n", 865 | "pass_end_x 769576 non-null float64\n", 866 | "pass_end_y 769576 non-null float64\n", 867 | "carry_end_x 637990 non-null float64\n", 868 | "carry_end_y 637990 non-null float64\n", 869 | "shot_end_x 19934 non-null float64\n", 870 | "shot_end_y 19934 non-null float64\n", 871 | "shot_end_z 14422 non-null float64\n", 872 | "goalkeeper_end_x 12306 non-null float64\n", 873 | "goalkeeper_end_y 12306 non-null float64\n", 874 | "match_id 2797557 non-null int64\n", 875 | "50_50_outcome_id 1232 non-null float64\n", 876 | "50_50_outcome_name 1232 non-null object\n", 877 | "bad_behaviour_card_id 545 non-null float64\n", 878 | "bad_behaviour_card_name 545 non-null object\n", 879 | "dribble_nutmeg 1064 non-null object\n", 880 | "foul_committed_advantage 2940 non-null object\n", 881 | "foul_won_advantage 3034 non-null object\n", 882 | "goalkeeper_success_in_play 15 non-null object\n", 883 | "injury_stoppage_in_chain 303 non-null object\n", 884 | "pass_miscommunication 478 non-null object\n", 885 | "pass_backheel 978 non-null object\n", 886 | "block_deflection 849 non-null object\n", 887 | "dribble_no_touch 84 non-null object\n", 888 | "pass_deflected 875 non-null object\n", 889 | "shot_deflected 195 non-null object\n", 890 | "clearance_other 141 non-null object\n", 891 | "shot_open_goal 236 non-null object\n", 892 | "goalkeeper_punched_out 90 non-null object\n", 893 | "shot_redirect 63 non-null object\n", 894 | "goalkeeper_lost_in_play 20 non-null object\n", 895 | "goalkeeper_shot_saved_off_target 72 non-null object\n", 896 | "shot_saved_off_target 72 non-null object\n", 897 | "shot_follows_dribble 17 non-null object\n", 898 | "goalkeeper_shot_saved_to_post 54 non-null object\n", 899 | "shot_saved_to_post 49 non-null object\n", 900 | "goalkeeper_lost_out 10 non-null object\n", 901 | "half_end_early_video_end 8 non-null object\n", 902 | "goalkeeper_saved_to_post 2 non-null object\n", 903 | "goalkeeper_success_out 8 non-null object\n", 904 | "player_off_permanent 7 non-null object\n", 905 | "goalkeeper_penalty_saved_to_post 1 non-null object\n", 906 | "shot_kick_off 1 non-null object\n", 907 | "dtypes: float64(49), int64(10), object(94)\n", 908 | "memory usage: 3.2+ GB\n", 909 | "None\n" 910 | ] 911 | } 912 | ], 913 | "source": [ 914 | "combine_single_file(RAW_EVENT_PATH,SAVE_PATH=os.path.join(DATA_PATH,'events'))" 915 | ] 916 | }, 917 | { 918 | "cell_type": "code", 919 | "execution_count": 25, 920 | "metadata": {}, 921 | "outputs": [ 922 | { 923 | "name": "stdout", 924 | "output_type": "stream", 925 | "text": [ 926 | "\n", 927 | "RangeIndex: 5450328 entries, 0 to 5450327\n", 928 | "Data columns (total 7 columns):\n", 929 | "id 5450328 non-null object\n", 930 | "id_related 5450328 non-null object\n", 931 | "type_name 5450328 non-null object\n", 932 | "index 5450328 non-null int64\n", 933 | "type_name_related 5450328 non-null object\n", 934 | "index_related 5450328 non-null int64\n", 935 | "match_id 5450328 non-null int64\n", 936 | "dtypes: int64(3), object(4)\n", 937 | "memory usage: 291.1+ MB\n", 938 | "None\n" 939 | ] 940 | } 941 | ], 942 | "source": [ 943 | "combine_single_file(RAW_RELATED_PATH,SAVE_PATH=os.path.join(DATA_PATH,'related_events'))" 944 | ] 945 | }, 946 | { 947 | "cell_type": "code", 948 | "execution_count": 26, 949 | "metadata": {}, 950 | "outputs": [ 951 | { 952 | "name": "stdout", 953 | "output_type": "stream", 954 | "text": [ 955 | "\n", 956 | "RangeIndex: 244803 entries, 0 to 244802\n", 957 | "Data columns (total 10 columns):\n", 958 | "id 244803 non-null object\n", 959 | "event_freeze_id 244803 non-null int64\n", 960 | "player_teammate 244803 non-null bool\n", 961 | "player_id 244803 non-null int64\n", 962 | "player_name 244803 non-null object\n", 963 | "player_position_id 244803 non-null int64\n", 964 | "player_position_name 244803 non-null object\n", 965 | "x 244803 non-null float64\n", 966 | "y 244803 non-null float64\n", 967 | "match_id 244803 non-null int64\n", 968 | "dtypes: bool(1), float64(2), int64(4), object(3)\n", 969 | "memory usage: 17.0+ MB\n", 970 | "None\n" 971 | ] 972 | } 973 | ], 974 | "source": [ 975 | "combine_single_file(RAW_SHOT_PATH,SAVE_PATH=os.path.join(DATA_PATH,'shot_freeze_frame'))" 976 | ] 977 | }, 978 | { 979 | "cell_type": "code", 980 | "execution_count": 27, 981 | "metadata": {}, 982 | "outputs": [ 983 | { 984 | "name": "stdout", 985 | "output_type": "stream", 986 | "text": [ 987 | "\n", 988 | "RangeIndex: 32211 entries, 0 to 32210\n", 989 | "Data columns (total 8 columns):\n", 990 | "id 32211 non-null object\n", 991 | "event_tactics_id 32211 non-null int64\n", 992 | "player_jersey_number 32204 non-null float64\n", 993 | "player_id 32211 non-null int64\n", 994 | "player_name 32211 non-null object\n", 995 | "player_position_id 32211 non-null int64\n", 996 | "player_position_name 32211 non-null object\n", 997 | "match_id 32211 non-null int64\n", 998 | "dtypes: float64(1), int64(4), object(3)\n", 999 | "memory usage: 2.0+ MB\n", 1000 | "None\n" 1001 | ] 1002 | } 1003 | ], 1004 | "source": [ 1005 | "combine_single_file(RAW_TACTICS_PATH,SAVE_PATH=os.path.join(DATA_PATH,'tactics'))" 1006 | ] 1007 | } 1008 | ], 1009 | "metadata": { 1010 | "kernelspec": { 1011 | "display_name": "Python 3", 1012 | "language": "python", 1013 | "name": "python3" 1014 | }, 1015 | "language_info": { 1016 | "codemirror_mode": { 1017 | "name": "ipython", 1018 | "version": 3 1019 | }, 1020 | "file_extension": ".py", 1021 | "mimetype": "text/x-python", 1022 | "name": "python", 1023 | "nbconvert_exporter": "python", 1024 | "pygments_lexer": "ipython3", 1025 | "version": "3.7.5" 1026 | } 1027 | }, 1028 | "nbformat": 4, 1029 | "nbformat_minor": 2 1030 | } 1031 | -------------------------------------------------------------------------------- /demo_crawley.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "from mplsoccer.pitch import Pitch\n", 10 | "import numpy as np\n", 11 | "import matplotlib.pyplot as plt\n", 12 | "from urllib.request import urlopen\n", 13 | "from PIL import Image\n", 14 | "import numpy as np" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 2, 20 | "metadata": {}, 21 | "outputs": [], 22 | "source": [ 23 | "background_color = '#004D98'\n", 24 | "line_color='#d2dde1'\n", 25 | "marker_color = '#dcdf4c'\n", 26 | "figsize = (9,16)\n", 27 | "width, height = figsize\n", 28 | "aspect = width/height" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 3, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "pitch = Pitch(pitch_color=background_color,line_color=line_color,orientation='vertical',pitch_type='opta',\n", 38 | " view='half')\n", 39 | "# going to use this to plot a legend - cheap hack that lines are same color as the background so\n", 40 | "# the lines won't show up\n", 41 | "empty_pitch = Pitch(pitch_color=background_color,line_color=background_color,\n", 42 | " orientation='vertical',pitch_type='opta',view='full')" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 4, 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "IMAGE_URL = 'https://upload.wikimedia.org/wikipedia/en/8/8b/Crawley_Town_FC_logo.png'\n", 52 | "crawley_logo = np.array(Image.open(urlopen(IMAGE_URL)))" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 5, 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "# for this image the aspect is different so you have to calculate the logo height from its width\n", 62 | "# so that you can get the height and width of the logo axis right\n", 63 | "def calculate_display_height(img,img_display_width,aspect):\n", 64 | " img_height, img_width, _ = img.shape\n", 65 | " img_aspect = img_width/img_height\n", 66 | " img_display_height = img_display_width/img_aspect*aspect\n", 67 | " return img_display_height" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "# Note that the logo is slightly transparent (alpha = 0.9) I like this better, but you can delete" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 6, 80 | "metadata": { 81 | "scrolled": false 82 | }, 83 | "outputs": [ 84 | { 85 | "data": { 86 | "image/png": "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8KPxbFRpngty/P6265nx1kz+eu//I5VuB5flRz++mttv/x98z8cRRD0uHWQymXXu99pL47lcjqlTf13sB2qtpbm5mQW1B270d7zh356IiIhIGS3wx5PoO7zXY//+97834YjHQpNw6OrqKj437lcw/cXpuDAkdNGsWmtrM4MHD6SmKsk778zGYLDWkIjHWbx4MRdddBH/euxfnHzZ5XTEE6SMJed7OAM2X9BiigXdhYbkpQGz9ziNiwLvOsE4P8aGhmjpuaqqCheGxONxrOfx5JNPEYvFIF8pD+BZL3rzHXYkl+6GTADZHON23x2sz69//RtuvPFG+vTpR5jPsel0ipoaqKutI52BTDZLZ1cHA3eoZuLEiXSn2glddJZlGEb3b31cyThuueUWampq8P2o5CabzVK147j3+f1snIKliIiIlFU6F9Ix8Sza29uLTcwbGho48cTPkM5k13p2zx7AntlAWLlqFQYvP8sXUFvbQGOfvgRBFE6feWY6nz3laP70l5t45OH/jV4bOiriCWIxn9raai757vcY/emT+O3s+Ty6dA3PrelgHobVyQraq6vorqomnayhuyJOdzxGt++R9Txy1ie0BlcIwdYQRl3JC5Od0V5Kl4u+xjJ58mTA0n/AAG699VaGDB5CPB7nn//6J3379SsGUEMYLVkbSHd1kvIMP732B3zikMkMGzmc0eNGc8stN9PQUEdlZWXxaMqqymruv/8ZTj75ZJYtW00YOKoqk0x/+SXeeedt7r73BrLZXNTY3HOsalqVLyRaKyDnv+/u7uaWW34JQBAEeJ5Hn4mHf+C9lQWqChcREZEtYvTxl7DyyalANFM2f/58xo8bz/z581m3oCTMzxhG31ub35NpAByJijg1VYBztHe0c9u13+dzn7+Um2+6ld/89kYuveQnUQW5jWHxKewhrK6vY7GxLHEW15WD7iZsNoefzZIMA+JAjYGaRJyaWJzaRIKYNVT7MZJxn7jvEfcsngXPeLR7MchkSYXg5QLSqQ5WrFjBpEmTmDdvHrFYgqFDh/Kd73ybM77wBQYMGMDSZStoa2tj+fLltLQ2k0uDH48Ri3n4CR/78CNYDA2NfaMZVaLip5ifAHrC4L13P8qa5iYOPOhGampr6ezq4OCD9uK6H08tbgGN/pji16WzxIWv//a3+7n44m/T2FhffHxFW4YVyb0+9O9c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vYwxpNNprrrqKt5++20uuOACdtxxR2pra4tB9+mnn97ASUU5IIcjW/w6atfk5SvQo/f44hfP5K233qJPnz7FV2azWQYed9WH7le5IQqWIiIi8pEaf+yFvQKkc46+ffty7rnnAhSD1QfR1taGtaZ4nYpkBZ7n8fRTT9Pe3s7uu+9enDG11vZa8o72NobFr0sfj8ZZ+k5RSHz33Xc57rjjiMVi+L7PggULsNYyeNBgZs+aXZydLHwm5xy5XEBLSwttba2ceuqpfPnLX+brX/86zz3/HKtWrSpWcTc1NW3wPkRbBUx0lnr+++JZ5KGjra2dJ554ongfCqG2OQVz12zsWM0PTsFSREREPlIzmxMMOPjM4hnVEIXL1197g6OPPrYkTJU2US/9AxuKMIMG7UBra1uxldGPrv0RF110EStXruTss8/mnHPOwTnH8OHDWbhwIbNmzSruf9xzrz25+uqrAVi+fDnQs2wN0NXVycSJE3uNubu7mxkzZtDR0YHnecWl9pqaGubNm9drxrIQphcvXsKCBQs45phjOfHEEznvvPN4+eWX+eZF36Surq54/aOOOmqt+1DgY4gBPrioGXzhlCJjLHPnzmW33XanT58+vdoKrWrPwUGXbdLv6INS8Y6IiIh85GZ09GXng77E8mf+0GsGMTrFZld+8pOfcswxnyw+PwpIhe96TutZm3OORx55hO985zu89957xGIxOjo6qKysZNasWVxwwQU45xg6dCj19fX079+fiooK7r//fs444ww863HTzTcVw1ixir22lhtuuBGA737vu1gbBblddtmFhQsXYoxh55135sEHH+QbF32DAf0HUFFRQRAGTJ8+nRkzZlBdXc1JJ53C7Nmz6ejooKqqCt/3OfTQQ/F9n6qqKsIwpLu7m+OPP56TTz55vZ+x5364XqfrOOe4//77uPzyy6mrq+v1+OouBwdv2VAJCpYiIiKylczo6s/Eyecy45Gp9Kk0BEFUeOL7MS677FIef/wxrrvuurVmMNc+CrI3YwwTJozn4YcfpqmpiXPPPZfp06dTX1+P7/fEnsbGRowxNDU1EYvFuOqqq3Auurbn+cWwa4yhu7ub8eMnFMdRX19P3759GT58ePE9nXPU19djjOGggw4CoLqqGqA4S+r7PnPmzCm2Wyo0jPd9n/b2durr69l33325+eab8TxDodfkusvh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6jU+Mzrg/ZusbzsULEVERORjYXG/wxnXZxBznriDZDJJIpHo1QOz0PPROUdFRQWVlZUEQcAjjzzCww8/zJAhQ9hjjz0YNHgQe+y+B6NHj2bHHXckHo+vtYS97rxkc3MzCxYsYObMmSxZsoTp06fz9ttv09nZSTKZJB6PF5e4C+eP53JRlbvnecUxdnV1YWp3ZMcp5/D2mm2j0ntzKFiKiIjIx8ZsuxNMuZYOYGhiMbOf/As1XoZYLFY89rA0bFprqaurA6CtrY0nn3wS5xx3/s+dBEFAEARkshlwkMvliq8rNG431mCNJRaL4ft+8dphGOL7PnV1dcVZyMLjhf2ThbG0trZSP2J3ErucTFNr9B4dLdtfqAQFSxEREfmYmpkeDPt9ixZg58qVtC56i6WvP0Z1dTWxWKwY+EqrxUtDp+d5eJ5HPB5f7/VLWxiVKgTW0r9LZznb2trw6gbRb+g43MjDWdWSYyVAPlRuzxQsRURE5GNvRld/6DsFDptCGzC+MUfnu0/RumoxnUtnF5erCzOJ6wuda1u7DyXQa7k9DAPa29sxxpDoP4rBkw5lZXwEmY4oQC4C8kf5fGwoWIqIiMh/nFlrfOgzBfoA46EDqK3w+NaenSxduoRZs2azfPlyurq6yGazxYKctWc2jTF4nkcikaCxsZFhw4bRv39/9tlnH866a1Xx/dLAzAyQ+XgFybUpWIqIiIgAbamA7z9bAYyCxCgYtnmvXwC80gF0wNR5qzby7I8nHekoIiIiImWhYCkiIiIiZaFgKSIiIiJloWApIiIiImWhYCkiIiIiZaFgKSIiIiJloWApIiIiImWhPpYi/2HeuOHorT0EERH5mNKMpYiIiIiUhWYsRf5DTPrmI1t7CCIi8jGnGUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLBUsRERERKQsFSxEREREpCwVLERERESkLf2sPQERkW5aMe+wyrI64b1m4qov3mrq29pBERLZZCpYiIuuRjHtceOxYPrXPIGqSseLjz89u4saH3uGtRa1bcXQiItsmBUsRkbVUxCxTz9ub3UY09HrcOcd+4/qy28gGzvvVS7w8d81WGqGIyLZJeyxFRNby1SNGrRMqAYwxAFTEPH58xq741nzUQxMR2aYpWIqIlIh5ls/uP2SjzxtQX8Ghuwz4CEYkIrL9ULAUESkxvH8lfWoSm/TcPUetO6spIvKfTMFSRKSEZzf9n0VPS+EiIr0oWIqIlFi8uotUJtik585Z1rGFRyMisn1RsBQRKdGRyvHwy0s3+ryudI4HX9r480RE/pMoWIqIrOWXj85hZWsKiFoMrc/PH5hNZzr3UQ5LRGSbp2ApIrKWFS0pzrzxBV5f0FxsMVTQ3JHh+3e9yV+eXbSVRicisu1Sg3QRkfVYvLqLM254nglDajlgXF9ivmXhyk4ee2MFmVy4tYcnIrJNUrAUEXkfM99rY+Z7bVt7GCIi2wUthYuIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWWDNxI8AACAASURBVChYioiIiEhZKFiKiIiISFkoWIqIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWShYioiIiEhZKFiKiIiISFkoWIqIiIhIWfhbewDyn+uNG47e2kMQERGRMtKMpYiIiIiUhWYs5SM36ZuPbO0hyAf0jWPH8tUjRtHeneWMG55n3oqOrT0k2QKsgRvO2oPJEwewYGUnX7jhOdq6slt7WCKyHdCMpYhsspsefofHXl9OTTLGzWfvSUNVfGsPSbaAi08Yz+SJA2jtzHDhb15SqBSRTaZgKSKbzDn43h2vM2NRK4P7VvKbC/amsVrh8uPkgqPH8KVDR5ANQr5166ssXNW1tYckItsRBUsR2SypbMjXf/MS81Z0MHbHWn57wT70qVG4/Dj4xnFjOfeo0eSCkCvueIPpc9Zs7SGJyHZGwVJENtvq9gxfuekF5ixrZ/QONfz+6/vSrzaxtYclH8K3TxjHVw8fRTYIueyPr/OPV5dt7SGJyHZIwVJEPpA1HRnOuvlF3lnaxogB1fzu6/syoK5iaw9LPoBLP70TX5oykmwQcsltr/Gv15dv7SGJyHZKwVJEPrDmzgxfveVF3l7cxvD+Vfz+wn3ZoUHhcnthDHz3sxP4wieGk82FfPv3r/L4myu29rBEZDumYCkiH0pLZ5azf/EiMxa1MqRvJb+/cF8GNSa39rBkI4yBK07amdMPHkY6G3DR717hiRkrt/awRGQ7p2ApIh9aW1eWc375Im8ubGFQYyW3f3N/9hjZsLWHJRtQXeFz/Vf24JQDh5LKRKHymbdXbe1hicjHgIKliJRFe3eOc385nRffWU3f2gS/uWAfPnfIsK09LFnLqIHV3Pmt/ZmyywDaurNc+JuX+fespq09LBH5mFCwFJGy6UjlOPdX0/nD4/OIeZbLPzOB//uFXUnGva09NPn/7N13eNX13f/x1zk52XsnZBAgrLC3IAJWZbhHHXW0rrbuulr7a/W2Vju8ay2uu1qsVlut4qhWBXGiMlVAwggJKwPI3js54/dHhgYMQz7JN8l5Pq6LS0lOTt4JJznP8/kuSfMnJuiF22YqLS5E2ftrdMlDa7R+Z7nVYwEYQAhLAEa53B79+b/ZuvMfm9TQ7NQZUwfpn7eeoJSYIKtH81o+dpvuOHukHrpykoL8HXrnywO6YvFa7Svn5OcAzCIsAfSI974q0mV/WavcknqNGBSmf98xSydlxFo9lteJCvHTU9dP6zyd0B9f367/96/Namp1Wz0agAGIsATQY3YX1enSh9fooy3FCgv01RM/mapbzhghPwe/enrDjOHRevnOEzV9eLRKq5t07eOf68VP86weC8AAxm93AD2qrsmp257ZqEffzpbb7dG1pw3Ta3fN1gkjoq0ebcCKCvHT7y8fryU3Tld8RIA27qnQxX9eo017K60eDcAA57B6AAADn8cjPf3BHm3YXal7Lhqj9MRQ/e2G6Vq24YD+9EaWymtbrB5xQLDZpAtmpujWM0cqLMhXTS0uPfXeLj338V45XR6rxwPgBQhLAL1m095KXfTQav1w3hD9dEG6Tp8ySLMzYvXIW9l6dW2BPLTPdzY8MVT3XDRGE4e0nT90VVapfvfqNu0vb7R4MgDehLAE0KucLo+e+XCPVmwq1K++n6GTMuJ0z0Vjdfb0JN2/dJtyDtRaPWK/Eujno+sWpOuKeWly+NhVWt2kB/+Tpfe+4nrfAHofYQnAEvsrGnXj3zbotAkJ+sV5ozUhLVIv3TFL//18v5a8v1v7K1hpOxxfH7vOOyFZ1546VAmRgXK7PXrx01w9vmyn6pqcVo8HwEsRlgAs9f7mIq3ZUaabTh+uS04arPNnpuis6Ul66/P9WvLBbjblHsTXx67zT0jWNe1BKUlZBdX67dJt2lZQbfF0ALwdYQnAcvXNTj34nyz9+7M8/WT+MJ0xNUnnz0zR2dOT9O6mQj338V5l7/fuTeQhAQ59f2aKLpubpviIAElSzoEaPbVitz7ILGL/VAB9AmEJoM/IL2vQ3S9u0d/e260fzx+mM6YM0plTk3Tm1CStzS7T8x/v1ZrsMq+KqISIAF02N00XzExRSEDbr+zs/TV6asUufbil2Ku+FwD6PsISQJ+TX9age17cov9bvlOXt0fVzJExmjkyRgcqGvXupkK9u7FQO/bXWD1qjwgP8tWpExK0aHKipg6Lkt1ukyStyy7Tcx/v1eodZRZPCADfjrAE0GcVVjbpT2/s0JMrdun7s1J1yexUDYoK1NWnDNXVpwzV3uI6vbupUMs3Fiq3pN7qcY9LsL9DJ4+L08JJiZo5Kka+Pm3Xr2hxuvX+xkI9v3KvsvYNzJAGMHAQlgD6vNpGp579cI/+8dEeTUyL1KLJiZo/MUFD4kN0/cLhun7hcGXtq9G7mwr1weYiFZQ1WD3yUQn2d2jWqBgtnJSokzJiFeDnI0lyutxanVWq5RsL9dGWYo7yBtBvEJYA+g2Pp+0k65v2VurB/2Rp+vBoLZycqFPGx2t0cphGJ4fptrNGqqymWZtzK7V5b5W+yq3U9oIatTjdVo+vlJggTRwSoQlpkZo4JELpCaGdm7kl6ctdFXp3U6He/6pIlfVcjQhA/0NYAuiXXG6P1maXaW12mR5Yuk0njo7RosmJmjE8WjFh/jplfIJOGZ8gSWp1urV9X7U251Zp894q7S6qU1FVoxqaXT0ym8NuU0yYv5JjgjRucIQmpkVoQlqEokL9u9yu1elWZl6V3t9cpPc2Fam4uqlH5gGA3kJYAuj3Wl1urdxaopVbSyR9+8rghLRITUiLlOZ9/XG1ja0qrmpScVWTig76b0OzUy63R06XR06XW26P5PCxtf+xy9fHrpgwP8WHByghMrD9vwGKCw9QbJh/l5XIDuW1zfpqb99bSQUAUwhLAANOQVmDCsoa9NYXByS1nQNybGq4Jg6J1Pi0CCVHByo+IlChgb4KDfRVemKo0c/vdns6gzVrX7W+ag9JTvYOYKAjLAEMeHVNTq3LKde6nPIubw8P8lV8RIASIgK6/Dc+IkD+vj6dq5MOu012u01Ol7t9BbNtFbOirkVFVU0qqmxUcXWTiirbYrKspllONyeYBOB9CEsAXqu6oVXVDa3KOeDdV/UBAFPsVg8AAACAgYGwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARhCWAAAAMIKwBAAAgBGEJQAAAIwgLAEAAGAEYQkAAAAjCEsAAAAYQVgCAADACMISAAAARjisHgAAepvNJsWFBygu3F8xYf6KDQtQbJi/YsPa/x4eoLAghxx2u3zsNjl8bLJJcrk9cro9crk9ampxqay2WaXVzSqtaVZZTbNKq5tUWtP296LKRjW1uq3+UgGgVxGWAAY0m00aHBusjOQwZaSGKyM5XKOSwxQScPy//obEh3T7Ppfbo73FdcraV6PtBdXaXlCjHftr1NjiOu7PCwB9FWEJYEDx9bFranqUZo2K0ZiU7iOyvLZZRZVNKqtpVklN239LazpWIJtUXd+qVpdbTlfbCqUk+dhtnX+C/B1tq5zhXVc6O1Y+E6MClZ4YqvTEUJ01LUmS5HZ7tKc9NjfurtAn20tVVtPcq98fAOhJhCWAfi8syFcnjY7VvLFxOnF07CEhWVzVpO0F1drWvnK4vaBaFXUtx/159xTXdfs+P4ddIwaFKiMlXBkpYcpICdewhJBDYnNLXpVWbi3Ryq3F2lnY/f0BQH9AWALol5KiAvW98fGaNzZOk4ZEyuHz9bGIOQdq9Om2Um3aW6ntBdUqrz3+iDxWLU63tuZXa2t+defbOmJzbGq4ThwVqxkjojVucITGDY7QzWeM0P7yhvbILNEXu8rVvlAKAP0GYQmg37DbpJMy4nTx7FTNHh3b+fZWl1vrssu0cluJPtlaov0VjRZO2b1vxuZLq/IV6OejGSOiNW9snOaNiVNSdJAum5umy+amaX95g5auKdAb6/apsr73wxgAvgvCEkCfFxXip/NOSNaFs1I1KCpQktTc6tJHW4r10ZZirdlRptpGp8VTHrvGFlfnCqXdJo0dHKF5Y+K0aHKikqKDdNtZI3XjouFasalQL6/OV2ZuldUjA8BhEZYA+qwJaRG6ZPZgzZ+YIF9H26bugrIGLV2drzfW71N1Q6vFE5rj9kiZuVXKzK3S48tyNGtUrC6enaqTRsfqrGlJOmtakrL21Wjpqjy9s+EApzIC0CcRlgD6nNHJYfrZmSM1a1SMpLajqVduLdbLq/K1JrtMngG+76HbI63KKtWqrFIlRQXq+7NSdN4JKRqdHKZ7Lxmn6xcN15MrdumNdfvkZEdMAH0IYQmgz0iNCdJNZ4zQwkmJkqTaxla9vDpfr64p0IE+ut9kT9tf0ahH3s7RX9/dpdMmJOiH89I0OiVc/3PRWP1w3hA9vixH728uGvCxDaB/ICwBWC4mzF/XLUjXeScky9fHruZWl176LE9Pf7BnQG3uPh4tTrfe2XBAyzYe0GkTEnTT6SOUFhesh66cpG351Vr8drbW55RbPSYAL0dYArBMgK9d1542TFfMTVOgv0Mut0evry3QX1fsUnFVk9Xj9Ukej/TeV0X6KLNY58xI1vUL0zUmNVxLbpiutdlleuiNHdpZWGv1mAC8FGEJwBKThkTqt5eO0+DYYEnSB5uL9NiyHO0trrd4sv7B6fbotbUFeufL/frBnDRdc8pQzRwZo5fumKWn3tulZz7Yw/6XAHodYQmgVwX42nXzGSN02Zw02e025Ryo0W9f3qbMPE6l8100tbr17Id79OqafN18+ghdctJg3XT6CJ0yLl53v7iF1UsAvcp+5JsAgBmThkTqlV/M1hXzhsjt8eipFbt0yZ/XEJUG1DY69fvXtuuax9drf3mDRqeE66U7ZumnC9LlsNusHg+AlyAsAfS4AF+7fn7uKD178wwNjg3WzgO1uuwva/XE8p1yuthca9IXuyp0/oOr9NJnefJ12HXjouF64fZZGjEo1OrRAHgBwhJAj0qODtKLt886ZJUya1+N1aMNWI0trq6rl8lh+vfts3TBCclWjwZggCMsAfSYGcOj9e/bZyo9MVR7ius6VylbXVw1pjd0rF4uXZ0vX4dd914yTr88fzSbxgH0GMISQI+4dM5g/fW6qQoP9tPKrcW67OG1rFJaoLHFpQde2aZ7XsxUi9OtS+ektf27BPlaPRqAAYiwBGCUr49dv7l4rH55foYcPnYteW+Xfvb3japvdlo9mld78/P9uubx9SqradaMETF68fZZGpYQYvVYAAYYwhKAMVEhflpy4zSdPzNFTS0u3fX8V3ps2U4uN9hHbM6t0g8eXqPtBdVKiQnSv26dqXlj4qweC8AAQlgCMCI5Okgv3D5Tk4dGqaiyUT96dJ2Wbyy0eiwcpLiqSVc+uk7LNx5QcIBDi6+ZrItPTLV6LAADBGEJ4LilxQXr2ZtnKCkqSFvy2lbF2J+y72pqdeuu5zfrsXdyZLfb9OsLx+iKeWlWjwVgACAsARyX9IQQPXPTDMVHBOjLXRX68f99rvLaFqvHwlFY8v5uPfDKNknSz88drWtPHWrxRAD6Oy7pCOA7GxofoqdvnK6oUH+t2VGmW/++QU2tnEqoP1m6Ol8tTrd+c/FY3XLmSEnS0x/ssXgqAP0VK5YAvpPUmCAtuWGaokL9tSqrVLc8TVT2V2+s36dfvZApt9ujW84cyWZxAN8ZYQngmCVFBerpG6crNjxA63PKdNszG9XiJCr7s2UbDujel7ZIatssfvFsDugBcOwISwDHJCTAoSd+OlUJkYHauLtCtzy9Uc2sVA4Ib36+v3Ofy/93fganIgJwzAhLAEfNbpP+eMUEDY0P0c4DtbrxbxvU2OKyeiwYtHR1fufR4n+4YgInUQdwTAhLAEftljNHas6YOFXWteiWpzdwNZ0Basn7uzvPc/notVO4/COAo0ZYAjgqp08ZpKtPGSqny607/7FJ+ysarR4JPejef2/pvELPQ1dOlMNus3okAP0AYQngiMakhOu+S8ZKkh58PUtf7KqweCL0tKZWt372942d1xa/49xRVo8EoB8gLAEcVmyYvxZfM1n+vj5aujpfL6/Ot3ok9JLiqibd2n7E/2Vz0nTBCclWjwSgjyMsAXTLZpP++MMJio8I0IbdFfrj69utHgm9LDO3Svcv3SpJ+tX3x2jEoFCLJwLQlxGWALp1yezBmpYerfLaZt3x7CY5XR6rR4IF3vx8v5auzpevw677fzCO/S0BdIuwBPCtkqODdOuZIyRJ9y/dpoo6rv/tzf785g7tL2/Q6JRwXc01xQF0g7AEcAibTfrtD8Yp0N+hZRsO6KMtxVaPBIs1trj0P/9uuzLPT+ena3gim8QBHIqwBHCIS2YP1tT0KJXXNusPr7FfJdp8satCL32WJ1+HXQ9cyiZxAIciLAF0cfAm8OqGVosnQl/yl7ey2SQOoFuEJYBONpt03w/Gsgkc3Tp0kziXfATwNcISQKfTJiR0HgXOJnB055ubxO88d7TV4wDoQwhLAJIkh92mm05v2wT+xPKdbALHYT2+fKdqGlo1c2SMZoyItnocAH0EYQlAknTuCclKiwtWbkm93li3z+px0MfVNLTqmQ/3SJJuPXOkxdMA6CsISwAK8LXrugXpkqTH3smR082J0HFkL36aq5LqJo1JDddpExKsHgdAH0BYAtClc9IUFx6gbfnV+iCzyOpx0E80tbr15IpdkqSbzxjB6YcAEJaAtwsL8u08bczit7PlYbESx+CNdfuUW1KvtLhgnTMj2epxAFiMsAS83NWnDFVYoK/WZpdpfU651eOgn3G6PXp8WY4k6fqF6Qrw5WkF8Gb8BgC8WJC/jy46MVWS9OjbORZPg/7q/c1FyiqoVlx4gE6fMsjqcQBYiLAEvNgZUwYpJMChDbsrtK2g2upx0E95PNI/P8mVJF08e7C1wwCwFGEJeLGLZ7etVr68Kt/iSdDfvfdVkSrrWjQ6OUzjB0dYPQ4AixCWgJeaPDRSIwaFqby2mSPBcdxanG79Z33b+U87XrAA8D6EJeClOp78X1tbIKeLQ8Fx/F5Zky+326MFkxIVEexr9TgALEBYAl4oOtRPp45PkMvt0atrCqweBwPE/vJGrcoqlZ/DrvM49RDglQhLwAudf0KKfB12fbKtREVVTVaPgwHk5dVt++teOCtVnC8d8D6EJeCFzm1fTVq6moN2YNbqrFLtL29QckyQpqZHWT0OgF5GWAJeZlhCiFJiglRR26x12WVWj4MBxu2Rlm8qlCTNGxtv8TQAehthCXiZeWPjJEmfbC+Vm2N20ANWbi2RJM0bE2fxJAB6G2EJeJnOsGx/8gdM25pXpYraZiXHBCk9IcTqcQD0IsIS8CJRIX4alxqh5laX1rIZHD3E7WlbEZe+fiEDwDsQloAXmTMmTna7TetzytXY4rJ6HAxgK7cWS2I/S8DbEJaAF+lYPVq5jc3g6FnrssvV3OrS+LQIRYf6WT0OgF5CWAJewt/XrpkjYyRJnxKW6GGNLS6tyymXJM3lIB7AaxCWgJcYnRymQD8f5RyoUUl1s9XjwAuszmrbz3Ly0EiLJwHQWwhLwEtkpIRLkrbmVVs8CbzFtoK2x1rHYw/AwEdYAl5iTPuT+/Z9NRZPAm+Rc6BWTpdbQ+JDFOjnY/U4AHoBYQl4idHJYZKk7QWsWKJ3NLe6tbuoTj52m0YmhVo9DoBeQFgCXiDQz0dD4kPU6nIr50Ct1ePAi7A5HPAuhCXgBUYmhcrHbtPuojq1ON1WjwMvklXQtutFRvuKOYCBjbAEvEDHahGbwdHbtu9jxRLwJoQl4AUyOvev5MAd9K5vHsAT4MtTDjDQ8VMOeIFBUUGSpLySeosngbdpbnWrsLJJPnabEiIDrR4HQA8jLAEvEBPmL0kqqWmyeBJ4o9Lqtsddx+MQwMBFWAJeILb9Cb2shivuoPeVtj/uYglLYMAjLIEBLsjfR8EBDjW2uFTb6LR6HHghwhLwHoQlMMCxWgmrEZaA9yAsgQEuNjxAklTK/pWwSFlNxz6WARZPAqCnOaweAEDP6lglKq1mxfJY2W3SiaNjNWtkjHwdduWV1uutL/arqr7V6tH6lZL2x15sOCuWwEBHWAIDXAybwr+TUUlheujKiUqNDe7y9lvOGKG/vbdbS97fbdFk/U8Zm8IBr0FYAgNcgK+PJKmhmQN3jlZaXLCevnG6woJ8D3mfv6+Pbj5jhCQRl0ep47Hn3/5YBDBwsY8lMMA5fGySJJfbY/Ek/cdP56d/a1R+00/mD1P4EW6DNh2PPR+7zeJJAPQ0whIY4DqezFtdhOXRCAvy1fyJCfJ4Dv/98vf10VnTknppqv7N2f7Y63iRA2DgsumsJy15tslcvMiKTwsAADDgjb91uSWflxVLAAAAGGH5wTtWFTXgLW5YNFzXLUjXE8t36qkVu6wep8/zsdu07J65SowMPOJtb3jqS63KKu2Fqfq36FA/fXz/KSqtbtIp935s9TjAgGb1FmFWLIEBjgMnjo3L7dHS1fmSdNj9LPNL67VmB1F5NBz2tqcaDiADBj7CEhjgXC63JMmXAyeO2nMf7dWn20pks3X9nnWEZk1Dq+78x1eik45O55kJjnBAFID+j7AEBriaxrZzCEYE+1k8Sf/hdHt06983avFb2SqsbOx8e6vLo7e/3K/LF6/Vjv01Fk7Yv3Q89mq4YhEw4Fm+jyWAnlVS3XGdZq56ciycbo+e+XCPnvt4r9LiguXrY9eBykbVNBBHx6rjijslXP0JGPAIS2CA67icXhxh+Z243B7tLqqzeox+reMa4VxWFBj42BQODHCl1W1P5qxYwiodK5alhCUw4BGWwABXXtsst9ujqFB/jgyHJTpe1JS275YBYOAiLIEBzun2qLK+RT52m6JCOIAHvS82PEASK5aANyAsAS/Q8YTO5nBYoWNTOPtYAgMfYQl4gY5NkAmRARZPAm8UH8GKJeAtCEvAC+wprpckjRgUZvEk8DbRoX6KDvVXXZOz89RXAAYuwhLwAlkF1ZKkjGTCEr0rIyVckpS1r1pceAcY+AhLwAts39d2lZiOJ3mgt4xpf8xtL+BKRYA3ICwBL5BXWq+6L2bn1wAAIABJREFUJqfiIwIUHcqR4eg9GSltq+Tb21fNAQxshCXgBTyetk2REquW6F2jkztWLAlLwBsQloCX6NgUSViit8SE+Ss+IkB1TU7llzVYPQ6AXkBYAl6CA3jQ2zoeaxy4A3gPwhLwEtvaw3JCWoRsXNkRvWDikEhJ0vZ8NoMD3oKwBLxEXmmD9pc3KCrUX+NSI6weB15g7pg4SdKqHWUWTwKgtxCWgBdZubVEkjRvbJzFk2CgS4oO1PBBoaptbNWG3RVWjwOglxCWgBchLNFb5nWsVmaVyuliB0vAWxCWgBfZsLtCNY2tSk8MVXJ0kNXjYADrePHyybZSiycB0JtsOutJXkoCAADguLFiCQAAACMISwAAABhBWAIAAMAIwhIAAABGEJYAAAAwgrAEAACAEYQlAAAAjCAsAQAAYARhCQAAACMISwAAABhBWAIAAMAIwhIAAABGEJYAAAAwgrAEAACAEYQlAAAAjCAsAQAAYARhCQAAACMISwAAABhBWALAAOFjd1s9AgAvR1gCwACQkVyh31+yWVOGlFs9CgAvRlgCwABw7tT9CvJr1VUn79aN87MVEtBi9UgAvBBhCQD93EmjChUb3iy3xy6326ZRSdX6zfe3KD68werRAHgZh9UDAAC+O1+HU98bUyJ5bHLLI7tskqTcsiAVVwdZPB0Ab0NYAkA/tmB8oYIDnXJ5bJJHcts8qm/y1bMfD7N6NABeiLAEgH4qJKBZU4dVyO22SfLIZpNcHpteWJWm+mY/q8cD4IUISwDop86YfEC+do+cLpt8fGyyyaNPtsYpuzDC6tEAeCkO3kGflBpTr99cuEWbHnxXOY+8rU0PvqvfXLhFqTH1ls10/cJ0ZS5e1Pnng/tO1sNXTVJydN/ej83hY9P1C9M1MinU6P3On5igs6cnHdVtMxcv0iWzU41+/qPR3dc+KCpQmYsXaU5GbK/PZMqgyDqNSqyWy21rP2hHyi0J0fLNyb02w/J75ipz8SKlxJj/Gbj/0nH69+2zjvr2M0fG6PK5ad2+f/7EBH302+91+/7l/zNXd5w98rCfY2p6lDIXL1J6QshRzyVJZ09PUubiRQr08zmmj0uNCdIXf5qvK08ecsj7Hr12st65e678HDyNo2/hEYk+Z87oEr1916e6aGa+QgOdstuk0ECnLpqZr7fv+lRzRpdYNltNY6su/8taXf6XtXr4zR0amRSmJTdOO+YnjN7k62PX9QuHa2RSmNH7XTAxUeccZVhapbuvvbS6WZf/Za027a20aLLjt2BCoTyyye2WPJJqGxx6YdXgXvv8E9IilNT+omrhpETj9//Uit2658XMo779rJHRumxu91//nIxYfZZVelwzZRXU6PK/rFVBee8cbZ9f1qB/fLRX1y1MV3xEQOfbTx4Xp3lj4/WH17apxclJ8dG3EJboU1Jj6vX41RsU5O+Sn8PT5X1+Do+C/F16/OoNlq1culweZeZVKTOvSss2FuruFzKVFBWk2aP778rXsfL37f+/NlpdbmXmVam20Wn1KN/JqEFVSohskstja/vjlF7/PEW1jf69NsOiyYlqaHYqM7dKiyabD8t95Q3aVVRn5L5sNunE0bH6bNvxvSitb3YqM69Kza29F3NL3t+t8toW3XXeaElSoJ+P7jovQx9sLtKqrLJemwM4WuxjiT7l6pP3yOFz+F/aDh+3rpq3R/e9Oq6Xpure9n3VkqSkqEBJ0vi0CF176lBlpIQrNMChvPYVh2UbDnR+TGigQ3ecPUqzM2IVHuSriroWrdlRpvte3ipJig8P0J3njtK09CgF+TtUWtOsZRsO6InlO7udY96YOF23MF1D4oLV6vIor7ReD/83Wxt2V2j9/86XJD1w6Xg9cOl4SdLC367UgYpG/ezMEZqTEaek6EDVNjr15a4KPfRmlsprvz659vL/masPNhertrFVF85KVVSon5ZtOKDTJiZIatvMLUl/fXen/vrurqP+3l0yO1WXzU1TYmSgiiob9dKqfP3rk9wutxmeGKpbzhihScMi5bDbtLuoTo+9k6N1OeUK9PPRrWeN1MyR0YqPCFRFbbM+216qR97OUX1zWzB297VL0rv/M083/e1Lfbq9bRXLbpN+uiBd585IVnSov/JL6/X0+7u1bGNh5zz3XzpO6QmheuTtbN157iilRAcpa3+N7l+6TbsNRdCR2GxuzRldLLfLJo/NJo/drS92xyinqPf2q7TbpPkTE7Vya4m+2FWhey8eq+GJodpZWNt5m+N9nHd8r3/w8Joj3t/1C9P1o+8NlfT14/HNz/fpnhe3SJLGpoYrLNBXa7OPfFWiy+em6UcnD1Ggn49W7yjVA69s63wBMjU9Ss/cNEPn//GzzugNDXTo7gvHaN6YONU2OfXCp3mKCvbVqRMTtOi3n3S57+ToQN157mhNTItQUVWTHn0nRx9mFh92nhanW398fbue+MlUzR4dq2npUYoI9tWD/8k65LY3LhquC2elyM/XR+9vLtLaHWX63x9N7Px5B3oDYYk+5Zyp+w9ZqTyYn8Ojc6ft7xNhOag9KMtqm9v+HhmoTXurtHR1gVqcLk0cEqn7fzBOHo9Hy9sDpeOJ5U9vZKmspkUJEQGaMiyy8z5/d9l4+fvZdd/SraptdCo5OkhD4oK7nSE5Okh/vmqSXvg0Vw//d4f8HD7KSAlTeJCvJOmax9fr7zfN0FMrdumz9ogqrW6bNyrUX09/sFsl1c2KCvHTD09O09M3ztAFD34m9zf+GU6fnKjdRXX63Svb5ONjU/b+WiVGBCo00KHfvbpdklRc1XTU37cLTkjWr74/Rs99vFdrdpRp2vAo3XnOKPk57Hrmwz2SpLS4YD3/sxOUW1KvB5ZuU1V9i8akhishsu17HuDrIx+7TY+9s1MVdW3fxx/PH6aHrpqo65/88rBfe2z4oSt7Ny4aritPGaon392lbQXVOnV8vP74w4nySJ3/dpKUGBmg288ZpSXv71Zzi1u3nzNKf/rRRJ3/4Kqj/vqPx+Sh5QoJcMnpknzsdh2oDND7meZXDA9n+vBoxYT5692Nhdq4t1K/uiBDi6YkaufbX4el6cf54e7v9bX7lBoTrOnDo3TbM5skSRV1X784OikjThv3VHS+4OjO/EmJyjlQq/te3qr4iAD9/NxRqmlo7XyMf5sHLh2vSUMj9eB/slRW06wr5qVpcGywXJ5Df4/98YqJenVtgf7x0V5detJg/e8PJ+r0+z9RcfXhf3Y+216qDzOLdO/FYxUV6qfH3s455Oft8rlpuva0YVry/m5t2lOpk8fG6bYj7DMK9ATCEn1KcMDRbZoM9rduE6aPve0E1MnRgfr198eorsmpdTltKyHvbirsctsNuysVHxGgC05I6YyTcanhemlVvlZsKuq83TvfWNEcOzhcdz2/WZ+0b7b7clfFYecZnRym+manHv5vdufbVn1jX7Kt+W2rqgXlDcrMq+rysff+e0vn/9tt0ubcSn1w3/c0aUikNuzpuv/hTUs2dNmfq7qhVTa7DrnPI7HZpOsWDtcb6/fpz2/ukCStzS5TaIBD15w6VP/6JFctTreuX5iuuianrnxsXeemx47vsyRV1rfogVe2df7dx27T/ooGPf+zmUqICFBRVdNhv/ZvCgvy1eVz07Tkvd1a8v5uSdKaHWWKjwjQ9QvTu4RlWJCvfvjIOuWXte1nZ7NLj1wzRWlxwcot6dldNPwdrZo6uFJut2Sz2dXcbNd/vkhRb+/VtGjKINU0tGrVjlI5XR6tzS7TokmJevTtnM7bmH6cH+7+iqubVFbTpJb2XRwONicjtsvn7o7T5dGtf98oV/urqmEJIVo4KbHbsExPCNHJ4+J1x7Ob9P7mtrnW7yzXe/eerIaWQ39H/fOTXL2xfp8kaXtBtT6+/3uaMyZWr6wpOOJsTyzbqdd/eZIKyhr0z4NW9u026arvDdErq/P1f+0rvmuzy5QUHajE9hdiQG8hLNGn1Dc5FBp45Gisb7bmoRsZ4qdNDy/s/PuBikb94rlNKqtpWwEMDXTohkXDdfLYeMWF+8vh0/aE/83VhR37a3Tl94bI7fZoXU6Z8kq7HgiwY3+NfnbmCIUH++rznHIVHWElcGdhrUICHHrg0nF6Z0OhvtpbqcYW11F9PbNHx+gn89M1LCFEoYG+nW8fHBfcJSzX7yw3dpBAfHiA4iMC9N5XRV3e/u6mIl08e7CGJ4ZqW0G1pg+P1ttfHjjs/mxnTh2kK+YN0eDYIAX5f/2YGBwXfMTv2zcNTwhRoL/jkJlWbCrSA5eNV1SIX+cK2IGKxs6olKQ97ZtE4yMCejwsZ6SXyeHnksttk83u0YrNCb26X6XUdkDUKePi9eGWYjldbQG2fGOh/nDFBI1Pi1BmblvYmX6cH+n+uhMT5q9RSWH65T83H/G2X+ws74xKSdpdVKeoED85fGydX+s3ZaSGS1JnHEtSc6tb63LKND7t0F0T1u74ep/I6oZWVdS1dDko53AumJUit9uj+IgApcQEdXmsJUQGKjY8QCsP2od05dYSnZQRd1T3D5hCWKJPefPLJF00M/+wm8NbnDa98YU1RyPXNLbqJ//3uTweqby2WSXtm5Q7PHDpeI1Pi9BTK3ZpT3Gd6pqcuujEVJ08Nr7zNn94bbtuWDRcP12Qrl9fOEZ5pfV6YtnOztXOXzz3lW4+Y4R+ce5ohQX5asf+Gv35jR1av/Pb9w/LLanXz/6+UdecMlRP/GSKnC6PPtpSrAdfz1Jlfcu3fowkjUkJ1yPXTtFHmcV65oM9qqhrkUcevXDbrENOYfLNfS6PV8dm6PLart+7jr+HB7cFbniQb2ewf5vvjYvX7y+foJdX5emxd7JV3dCqmDB/PXLNFPkf4ylYYo4wU1j7Pn2SDjngp7U9OI71cx6r8KBmjUisk9tlk2zS1rwI7Szu/fNVzs6IUViQr1ZtL1VoYNtTyJe7KtTc6tKiyYmdYWn6cX6k++vOSaNjta+84aiiv7axtcvfW11u2e02+frY5XQd+mItJtRfdU3OQ150VdZ9+89Lzbfc/9E8bkYmheriE1P1h9e369KTBuuX52fouie/6DLHt33e7uYAehJhiT7lmY+H6vzp++Tn6H7Fzemy69mVQ3txqq+5XB5tL6j51vf5Oew6KSNWf3hte5dNW3abrcvtahudevD1LD34epaGJ4bqqlOG6A9XTFDOgVrtKa5TSXWz7nlxi2y2LRqXGqHrF6br0Wsna/59K1Xd0Hrwp5XUtg/WZ9tLFRLg0JyMWP3ivNH65QWjddfz3a/SnDI+XpV1Lfr5c191vi0xspvVk2/ZX+y76ti/Mzq065VhotufHKvr277GjlDszvyJCcrMreqymXLKsKjvNFNZ5z6nfl2+xwfPZKVpQ9tWu1xum0rr/PXZjvgjfETPWDR5kCTpz1dNOuR9CyYm6k//yZLbY/5xfqT7685JGbGd+9eaVlbbrJAAh/wc9i5xGRli9qpHd184RtsLavTyqnzlltRryQ3TddqEhM7N7x37eB/8eU3PARyN/n/eEAwo+WXBuumZKWpo9lGLs2uQtThtamj20U3PTFF+Wfc7+VvFz2GXw6frE0yQv4/mje1+U9TOwlo9/N9s+dhtGhLf9WvyeNr2X/zril0K9Hd0Hih0OHVNTi3bWKgPtxRrWPtJnFtdbfMcvDLi72s/ZPPeGVMGHfFzdGhbbTn283cWVzepuKpJp03sesDJgokJqm1s7TyyeH1OuRZMTOj2BND+vvZDVorOmNL1Prv72g+2s6hOjc1OzT9opvkTE5RbUnfYld/ekBBRr+ToRrlcNjW2+Oi9zES53b3/6zvQz0dzM2K1bMMBXf34+i5//vc/WYoJ89e04dGHfJzpx/m33V+ry3PI49HhY9MJI2M6j/w3bXv7Przf/Bn397Vr5sgYY5/jgpkpGpsaod+92rY/8fqccq3YVKifnzuq8/y5RZWNKq1u0skH/a453O8eoKewYok+59OsOJ354BxdNW+Pzp22X8H+TtU3O/TGF0l6duXQPhmVUlvUbcmr0nUL0lXf5JTbI11z6lDVNToVHPD1j9o/bpmhjzKLtauoTh6PdMHMZDU0O7U1r1ohAQ49ed00vfXFfuWW1svPYdeP5g1RaXVTt6sy35+VoglpEVqdVabS6ialxgZr/oQEvfVl28EKTpdH+8oatGBionYV1qnZ6VLOgVqtzS7XFfOG6BfnjdYnW0s0YUiEzpx69GG5t6ReJ4+N08nj4lRc1aTS6maVHmbTdQePR3ry3Z2656Kxqq5v0drsck0dFqmLTkzVo+/kdMbikyt26cXbZ+nZm2fo+ZV7VVXfqtFJYapqaNUb6/dpXXa5fn3hGP34tGHKzKvSSRmxmjGi6xN6d1/7wWoaWvWvT3L1k9OGyeVya1tBjU4ZH685Y+L0i2+s6FplclqlnB6b7HJrdXacanp5v8oOJ4+LV6C/Qy98mqstedVd3vfVnkr9+LRhWjQ5Uetzyo0/zg93f5K0t6ROMWH+Ont6knYV1qqqvlUpMUGy2458YNB3tauoTiu3FuvuC8co2N+hstpm/XBemppaXPIY2CU5IthXPztzhJauzlfWvq+3lPzpjSy9+f/m6KcL0rX4rWy5PdI/Pt6r288epcq6Fm3aW6V5Y+M0PLHtilNut7ktDsCREJbok/LLgnXfq+P6xCmFjsUv/7lZ9140Vr+7bLyqGlr10md5CvDz0SWzv74iSGZulc6ZnqxBUYFyeTzasa9GNzz1pYqrm+TrY9fOwlpdNnew4iMC1dTiUmZela578otuD2LJOVCreWPidOe5ozr3S3xt3T49sezr817e/8o23XHOSP3thmny9/XRwt+u1KqsUv3lvzv0g5MG64ITkrU5t0o3/W2D3r577lF9rS+vytOopFD99pJxCg/2O6bzWL62bp98HXZdPjdNl81JU3FVkx56c0eX81jmltTrR4+s061njdBvLm57HOwprus88viVNflKjg7UZXMG6yrfoVqXXaZf/vMrvXBb18sAftvX/m2eWL5TLrdHF52Y2nYey7IG/fKfm4+4D19PGxpbrbCgVjldNu0tCtOeknDLZlk0OVG5JfWHRKUkOd0evfdVoRZNHqTfvbLd+OP8cPcntR1oNS09WrefNVJRof568/N9qmlo1bqc8s6V655w94tbdPeFY/TL80erocWll1bla195o8akHv+/021nj5LL7dHjy3K6vL2kullPrdilm88YoTfW71NuSb3+uTJXYYG+umj2YF0xb4hWbi3R0x/s0d0XjjniaZYAk2w660leygBAH2SzubRg/H4F+7tV12zX+1uSLdkE3l/991dz9NxHe/Taun299jl97Da9ftdsbcmr0t0vbjnyB/Sg31w8VieMjOn2xRTQE1ixBIA+anhcrfx8pBanXWuy44nKY3T27z/t8c9x2oQExYX7a2dhrYIDHLrghBSlxgbr1y8c/XXOTUhPCNGCSYnanFspt0eaPTpW58xI1uK3so/8wYBBhCUA9EF+DqfS4urk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\n", 87 | "text/plain": [ 88 | "
" 89 | ] 90 | }, 91 | "metadata": {}, 92 | "output_type": "display_data" 93 | } 94 | ], 95 | "source": [ 96 | "# setup a figure\n", 97 | "fig = plt.figure(figsize=figsize,facecolor=background_color);\n", 98 | "# The dimensions [left, bottom, width, height] of the new axes.\n", 99 | "# All quantities are in fractions of figure width and height.\n", 100 | "pitch_top_rect = (0,0.5,1,0.45)\n", 101 | "ax_pitch_top = fig.add_axes(pitch_top_rect)\n", 102 | "legend1_rect = (0.2,0.45,0.1,0.05)\n", 103 | "ax_legend1 = fig.add_axes(legend1_rect)\n", 104 | "ax_legend1.axis('off')\n", 105 | "legend2_rect = (0.5,0.45,0.1,0.05) #dimensions for line legend\n", 106 | "ax_legend2 = fig.add_axes(legend2_rect) # ax for legend2\n", 107 | "pitch_bottom_rect = (0,0,1,0.45)\n", 108 | "ax_pitch_bottom = fig.add_axes(pitch_bottom_rect)\n", 109 | "title_rect = (0.02,0.95,0.7,0.05)\n", 110 | "ax_title= fig.add_axes(title_rect)\n", 111 | "ax_title.axis('off')\n", 112 | "logo_display_width = 0.2\n", 113 | "logo_display_height = calculate_display_height(crawley_logo,logo_display_width,aspect)\n", 114 | "logo_rect = (1-logo_display_width,1-logo_display_height,logo_display_width,logo_display_height)\n", 115 | "ax_logo = fig.add_axes(logo_rect)\n", 116 | "ax_logo.axis('off')\n", 117 | "ax_logo.imshow(crawley_logo,alpha=0.9)\n", 118 | "# draw pitches\n", 119 | "pitch.draw(ax=ax_pitch_top)\n", 120 | "pitch.draw(ax=ax_pitch_bottom)\n", 121 | "# draw legend circle\n", 122 | "ax_legend1.scatter(0.5,0.5,c=marker_color,s=100);\n", 123 | "# draw legend line\n", 124 | "empty_pitch.draw(ax=ax_legend2)\n", 125 | "empty_pitch.lines(np.array([20]),np.array([70]),np.array([70]),np.array([20]),\n", 126 | " comet=True,transparent=True,ax=ax_legend2,color=marker_color);\n", 127 | "# add title\n", 128 | "fig.text(0.03,0.98,\"Crawley Town\",verticalalignment='top',horizontalalignment='left',fontsize=50,color=line_color);\n", 129 | "fig.text(0.3,0.47,\"Pass start location\",fontsize=15,color=line_color);\n", 130 | "fig.text(0.6,0.47,\"Assist/ high Xg\",fontsize=15,color=line_color);" 131 | ] 132 | } 133 | ], 134 | "metadata": { 135 | "kernelspec": { 136 | "display_name": "Python 3", 137 | "language": "python", 138 | "name": "python3" 139 | }, 140 | "language_info": { 141 | "codemirror_mode": { 142 | "name": "ipython", 143 | "version": 3 144 | }, 145 | "file_extension": ".py", 146 | "mimetype": "text/x-python", 147 | "name": "python", 148 | "nbconvert_exporter": "python", 149 | "pygments_lexer": "ipython3", 150 | "version": "3.8.2" 151 | } 152 | }, 153 | "nbformat": 4, 154 | "nbformat_minor": 4 155 | } 156 | --------------------------------------------------------------------------------