Analyzing NBA Player Movement Data with Python: Extraction, Visualization, and Metrics
This article demonstrates how to retrieve NBA play‑by‑play movement data via the stats.nba.com API, transform it into a pandas DataFrame, enrich it with player names, visualize player trajectories on a basketball court, and compute travel distances, speeds and inter‑player distances using Python libraries.
The author, a longtime NBA fan, presents a step‑by‑step tutorial for analyzing player movement data from a specific Clippers vs. Rockets playoff game using Python.
First, the API endpoints from stats.nba.com are called to obtain JSON data containing two parameters, eventid (the game ID) and gameid (the season ID). The response provides three dictionaries: home (home team players), visitors (away team players) and moments (a list of 700 time‑stamped position records.
Key code snippets include:
headers = ["team_id", "player_id", "x_loc", "y_loc", "radius", "moment", "game_clock", "shot_clock"]
player_moments = [] for moment in moments: for player in moment[5]: player.extend((moments.index(moment), moment[2], moment[3])) player_moments.append(player)
These rows are loaded into a DataFrame:
df = pd.DataFrame(player_moments, columns=headers)
Player IDs are mapped to names and jersey numbers using a dictionary built from the players list:
id_dict = {} for player in players: id_dict[player['playerid']] = [player["firstname"] + " " + player["lastname"], player["jersey"]] id_dict.update({-1: ['ball', np.nan]}) df["player_name"] = df.player_id.map(lambda x: id_dict[x][0]) df["player_jersey"] = df.player_id.map(lambda x: id_dict[x][1])
To visualize a player's trajectory, the court image is loaded with plt.imread("fullcourt.png") and plotted using plt.scatter where the colormap encodes game time. The author also provides a custom draw_court function that uses matplotlib.patches (Circle, Rectangle, Arc) to recreate the basketball court lines directly in the plot.
Travel distance for each player is calculated by taking the Euclidean distance between consecutive (x, y) points:
def travel_dist(player_locations): diff = np.diff(player_locations, axis=0) dist = np.sqrt((diff ** 2).sum(axis=1)) return dist.sum()
Applying this function with groupby yields total distance and average speed (converted to mph) for every participant, including the ball.
Inter‑player distances are computed using scipy.spatial.distance.euclidean inside a helper function player_dist , allowing the author to plot distance curves for specific moments (e.g., Harden vs. Jordan, Harden vs. the ball) and annotate key events such as Harden’s pass to Ariza.
Throughout the article, code snippets are shown exactly as written, and the resulting plots (court visualizations, distance‑time graphs) are embedded as images.
Qunar Tech Salon
Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.