Tracking Data Overview

Beginner 10 min read 0 views Nov 27, 2025
# Tracking Data Overview ## Introduction Player tracking data revolutionized basketball analytics by capturing spatial coordinates of all players and the ball at 25 frames per second. This guide introduces tracking data concepts and analysis. ## Understanding Tracking Data Structure ### Data Format ```python import pandas as pd import numpy as np # Example tracking data structure tracking_sample = { 'game_id': '0022300001', 'event_id': 1, 'timestamp': 0.04, # seconds 'quarter': 1, 'game_clock': 720.0, 'shot_clock': 24.0, 'ball': {'x': 25.0, 'y': 47.0, 'z': 10.0}, 'home_team': [ {'player_id': 201935, 'x': 10.5, 'y': 20.3, 'speed': 2.1}, {'player_id': 203507, 'x': 15.2, 'y': 25.8, 'speed': 1.8}, # ... 3 more players ], 'away_team': [ # 5 players ] } ``` ## Python Analysis Framework ```python import pandas as pd import numpy as np import matplotlib.pyplot as plt from scipy.spatial import distance class TrackingAnalyzer: def __init__(self, tracking_data): """Initialize with tracking DataFrame""" self.data = tracking_data self.court_length = 94 # feet self.court_width = 50 def calculate_player_distance(self, player1_coords, player2_coords): """Calculate Euclidean distance between players""" return distance.euclidean(player1_coords, player2_coords) def calculate_spacing(self, team_coords): """Calculate team spacing metric""" distances = [] for i in range(len(team_coords)): for j in range(i+1, len(team_coords)): dist = self.calculate_player_distance( team_coords[i], team_coords[j] ) distances.append(dist) return np.mean(distances) def get_player_speed(self, player_id, start_frame, end_frame): """Calculate player speed over time window""" frames = self.data[ (self.data['player_id'] == player_id) & (self.data['frame'] >= start_frame) & (self.data['frame'] <= end_frame) ] # Calculate frame-to-frame distance positions = frames[['x', 'y']].values distances = np.sqrt(np.sum(np.diff(positions, axis=0)**2, axis=1)) # Speed in feet per second (25 fps) speeds = distances * 25 return speeds.mean() def plot_positions(self, frame_num): """Visualize player positions at specific frame""" frame_data = self.data[self.data['frame'] == frame_num] fig, ax = plt.subplots(figsize=(10, 5)) # Draw court boundaries ax.plot([0, self.court_length], [0, 0], 'k-') ax.plot([0, self.court_length], [self.court_width, self.court_width], 'k-') ax.plot([0, 0], [0, self.court_width], 'k-') ax.plot([self.court_length, self.court_length], [0, self.court_width], 'k-') # Plot players home = frame_data[frame_data['team'] == 'home'] away = frame_data[frame_data['team'] == 'away'] ax.scatter(home['x'], home['y'], c='blue', s=100, label='Home') ax.scatter(away['x'], away['y'], c='red', s=100, label='Away') # Plot ball ball = frame_data[frame_data['is_ball'] == True] ax.scatter(ball['x'], ball['y'], c='orange', s=50, marker='*', label='Ball') ax.legend() ax.set_xlim(-5, 99) ax.set_ylim(-5, 55) plt.show() # Usage # analyzer = TrackingAnalyzer(tracking_df) # spacing = analyzer.calculate_spacing(team_positions) ``` ## R Implementation ```r library(dplyr) library(ggplot2) calculate_player_distance <- function(x1, y1, x2, y2) { sqrt((x2 - x1)^2 + (y2 - y1)^2) } calculate_team_spacing <- function(team_coords) { n <- nrow(team_coords) distances <- c() for (i in 1:(n-1)) { for (j in (i+1):n) { dist <- calculate_player_distance( team_coords$x[i], team_coords$y[i], team_coords$x[j], team_coords$y[j] ) distances <- c(distances, dist) } } mean(distances) } plot_tracking_frame <- function(tracking_data, frame_num) { frame_data <- tracking_data %>% filter(frame == frame_num) ggplot(frame_data, aes(x = x, y = y, color = team)) + geom_point(size = 4) + geom_point(data = frame_data %>% filter(is_ball), aes(x = x, y = y), color = "orange", size = 3, shape = 8) + xlim(-5, 99) + ylim(-5, 55) + coord_fixed() + theme_minimal() + labs(title = paste("Frame", frame_num)) } ``` ## Key Metrics from Tracking Data 1. **Spacing** - Average distance between teammates 2. **Speed/Distance** - Player movement metrics 3. **Defensive Pressure** - Closest defender distance 4. **Time in Paint** - Zone occupancy 5. **Ball Movement** - Passes and ball speed ## Data Sources - NBA Advanced Stats (limited public access) - Second Spectrum (NBA's official provider) - STATS SportVU (legacy system) - Research partnerships with teams

Discussion

Have questions or feedback? Join our community discussion on Discord or GitHub Discussions.