Creating a Football Heat Map React Component with Recharts

Damian Cummins
The Startup
Published in
4 min readSep 18, 2019

Heat maps are a great visualisation to start with when exploring sports event data that includes coordinates, allowing viewers to immediately focus on areas of the field that matter most.

In this post I’ll walk through how we can build a React.js component that can display a football player’s pitch coverage across particular zones for a given match using the charting library Recharts. I’ve decided to work with the Recharts library for this example because they do not actually have a heat map component, but this post will demonstrate that it is a very intuitive and extensible library.

The event data

The event data used in this example is taken from a FA Women’s Super League match (Chelsea FCW (0) vs Manchester City WFC (0) ) from the 2018/19 season. The sports analytics organisation StatsBomb, have made a number of their datasets freely available for learning purposes.

The JSON data is an array of different events which include many attributes, but the ones we are interested in are:

"player": {"id": 10395, “name": “Maren Naevdal Mjelde"}

"location": [53.0, 10.0]

We will need to filter for events that match the player name and also contain location data in order to plot the heat map.

Shaping the data

Before we look at what the heat map component will render, first we need to transform the events data so that it can be visualised by the Recharts Scatter Chart component.

Here we define a function that will retrieve a list of all locations in the match dataset for a given player:

This returns an array of objects containing the location coordinates:

[
{ x: 10, y: 10},
...
]

Then we need a way of dividing the pitch into a grid and counting the number of events that are present in each cell. This will be the data used to plot our heat map.

The getHeatmapSectors function accepts our array of coordinates, along with the number of columns and rows that we want to divide the pitch into for the heat map.

It then iterates over each sector in the pitch, counting the coordinate objects that fall within that sector, resulting in an array that looks like this:

[
{
count: 10,
x1: 0,
x2: 30,
y1: 0,
y2: 20
},
...
]

In the above example, the bottom left sector of the pitch contains 10 events.

Building the chart

Install the Recharts library with npm install recharts to use the latest stable version.

We can then import the following components required to build a Scatter chart:

import {
ReferenceDot,
ReferenceLine,
ReferenceArea,
ScatterChart,
Scatter,
CartesianGrid,
Tooltip,
XAxis,
YAxis
} from "recharts";

The bulk of JSX to be rendered by this component is going to be the Reference shapes that are drawn onto the Scatter chart to depict the football pitch layout:

The above function accepts an array of locations, an array of sectors, and a scale value. The components are drawn on top of one another based on their order within the <ScatterChart> component, which is why the heat sectors are rendered on top of some shapes, but behind some others, as we do not want the opacity of the sectors to obscure any important features of the pitch.

These are the main parts of the heat map component. Once they have been tied together in a React component, it can be rendered like so:

<Heatmap   data={matchData}   playerName="Ramona Bachmann"/>
Ramona Bachmann — Chelsea FCW (0) vs Manchester City WFC (0) Date: 2018–09–09

Summary

In this post we have looked at an example of a football event data point, manipulating events into locations for a particular player, as well as aggregating events for different sectors of the pitch.

We then plotted both the locations onto a Scatter Chart and overlaid the outline of a football pitch onto the chart as well as visualising the sectors with the most coverage using the Recharts library.

The complete Heatmap component code can be found here and can be seen in action on this FAWSL Dashboard.

--

--