{ "cells": [ { "cell_type": "markdown", "id": "4756194f", "metadata": {}, "source": [ "# 📍 Recipe: Touch Location Heatmap for a Player\n", "\n", "In this example, we'll generate a heatmap of where a single player touched the ball during a match using StatsBomb open data.\n", "\n", "We'll use Flow to filter events, extract coordinates, and then visualize the result using mplsoccer.\n", "\n", "## 🧰 What You'll Learn\n", "\n", "- How to access StatsBomb data using `Flow.statsbomb` methods\n", "- How to filter events to those involving a given player\n", "- How to extract location data using or `.split_array()`\n", "- How to use `.pipe()` to apply a custom function to the Flow\n", "\n", "## Imports" ] }, { "cell_type": "code", "execution_count": 1, "id": "4248fe6e", "metadata": {}, "outputs": [], "source": [ "from IPython.display import HTML\n", "from penaltyblog.matchflow import Flow, where_equals\n", "from penaltyblog.viz import Pitch\n", "import plotly.io as pio" ] }, { "cell_type": "markdown", "id": "087075c2", "metadata": {}, "source": [ "## Load the Data" ] }, { "cell_type": "code", "execution_count": 2, "id": "ee5a686d", "metadata": {}, "outputs": [], "source": [ "# Load events for a StatsBomb match\n", "match_id = 22912 # Champions League Final 2018/2019\n", "\n", "flow = Flow.statsbomb.events(match_id)" ] }, { "cell_type": "markdown", "id": "4f53ac10", "metadata": {}, "source": [ "## Filter Events to Just Those by Trent Alexander-Arnold" ] }, { "cell_type": "code", "execution_count": 13, "id": "350cf117", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'x': 43.5, 'y': 65.7}\n", "{'x': 21.9, 'y': 59.6}\n", "{'x': 14.7, 'y': 65.9}\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/Users/martin/repos/penaltyblog/venv/lib/python3.13/site-packages/statsbombpy/api_client.py:21: NoAuthWarning:\n", "\n", "credentials were not supplied. open data access only\n", "\n" ] } ], "source": [ "touches = (\n", " flow.filter(where_equals(\"player.name\", \"Trent Alexander-Arnold\"))\n", " .split_array(\"location\", into=[\"x\", \"y\"])\n", " .select(\"x\", \"y\")\n", ")\n", "\n", "for touch in touches.head(3):\n", " print(touch)" ] }, { "cell_type": "markdown", "id": "d7680381", "metadata": {}, "source": [ "## Plot Heatmap of Touches" ] }, { "cell_type": "code", "execution_count": 14, "id": "8d2236c6", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "\n", "