Create Euroleague shot charts in Python

Georgios Giasemidis
4 min readOct 31, 2021

Learn how to create Euroleague short charts in Python using matplotlib.

I was recently approached by the fellow Euroleague fan, Stefano Gottardi, about Euroleague shooting data. Although I have spent much time collecting and analysing Euroleague data, see this article on arxiv.org, I never got into shot charts. But that question intrigued me. It must be possible. There are several solutions for NBA shot charts, see articles by Naveen Venkatesan, here, and Savvas Tjortjoglou, to mention a few, but I couldn’t find any for Euroleague using Python (there is one in R, see below).

The problem with Euroleague data is the lack of a complete API. Game data and standings are usually collected via web scrapping, but scrapping shot data would be more challenging and demanding. An R-package for collecting Euroleague data was brought to my attention, where there is a mention for an API url for shooting data and ranges of Euroleague games. Could this work? Let’s try out.

Data Collection

With the following lines of code we collect the shooting data for the game Panathinaikos vs Anadolu Efes for the sixth round of the 2021–2022 Euroleague season.

import requests
import pandas as pd
url = "https://live.euroleague.net/api/Points?gamecode=54&seasoncode=E2021"r = requests.get(url)
print(r.status_code) # if all goes well this must return 200
data = r.json()
shots_df = pd.DataFrame(data['Rows'])

The API endpoint consists of the base url “https://live.euroleague.net/api/Points” followed by the parameters “gamecode” and “seasoncode”. To fetch data for another game, one needs to find the “gamecode” and specify the “seasoncode”, being the year of the start of the season. “gamecode” and “seasoncode” can be found on Euroleague’s website; head to Game Centre, search for the game of interest using the drop down menus and the url of the game page shows the game and season codes (see the url of the above game).

Next, we perform the request and the API returns the data in a nice structured json format, which is converted to a data-frame for easy analysis. A sample of the data is shown below.

Sample of the Euroleague shooting data

We get every shooting activity on the floor with timestamp, coordinates and zone. This is awesome.

Draw a FIBA basketball court using matplotlib

Now, I need to put these data on a basketball court shot chart. I don’t want to reinvent the wheel, so I am using the awesome work of Savvas Tjortjoglou with a few tweaks for Euroleague. There are two main changes:

  • European basketball court has different sizes from NBA courts
  • The Euroleague shot data is in a different coordinate system (resolution)

Therefore, we need to adjust the code to account for these changes. Here is the code

The shot charts

We are ready to test the function and plot some data. I created two plot functions, one scatter plot with “made” and “missed” shots and another hex-type density plot (for the latter I adopted the solution by Savvas Tjortjoglou).

Let’s put all the pieces together and produce the shot charts.

and here are the output plots

Panathinaikos shot chart
Anadolou Efes shot chart
Panathinaikos density shot chart.

Conclusion

Euroleague shot charts is a rather unexplored area, in contrast to the NBA, where several solutions have been created in Python. Here, I showed how one can collect shooting data from a (rather secret and restricted) Euroleague API. Adjusting existing code from the NBA community, we were able to create shot chart for a Euroleague game.

We now have all the building blocks for producing shot charts of any kind:

  • season shot chart of a team
  • career of season shot charts of a player

I leave these for another article.

Code and example is available on github.

--

--

Georgios Giasemidis

Data Scientist, DPhil (PhD) in Theoretical Physics, BSAC diver, evolution, raspberry pi, drone & LEGO enthusiast, fan of basketball and analytics