Chapter 13: Exercises - Play-by-Play Visualization

Overview

These exercises build skills in visualizing play-by-play football data, progressing from basic drive charts to complex animated game summaries.


Level 1: Conceptual Understanding

Exercise 1.1: Play-by-Play Data Structure

Given the following play record, identify all the information that could be visualized:

play = {
    'game_id': 'GAME2024_001',
    'drive_id': 4,
    'play_number': 28,
    'quarter': 2,
    'time': '3:45',
    'down': 3,
    'distance': 7,
    'yard_line': 58,
    'play_type': 'pass',
    'yards_gained': 22,
    'touchdown': False,
    'first_down': True,
    'epa': 1.85,
    'wp_before': 0.42,
    'wp_after': 0.51
}

Questions: a) What pre-play state information is available? b) What post-play outcome information exists? c) What advanced metrics can be derived? d) How would you represent this play in a drive chart?

Exercise 1.2: Chart Type Selection

For each scenario, select the best visualization type:

a) Showing a team's field position throughout a single drive b) Comparing win probability between two rival games c) Displaying EPA distribution for all 3rd down plays d) Showing the relationship between down/distance and success rate e) Presenting play-by-play momentum shifts in a game

Options: Line chart, Bar chart, Heatmap, Drive chart, Scatter plot, Win probability curve

Exercise 1.3: Audience Analysis

You need to create play-by-play visualizations for three audiences:

  1. TV broadcast during the game
  2. Coaching staff post-game film review
  3. Fan engagement on social media

For each audience: a) What level of detail is appropriate? b) What metrics should be emphasized? c) What interactivity is needed? d) What is the maximum viewing time?

Exercise 1.4: EPA Interpretation

A drive consists of these plays with their EPA values:

Play Down & Distance Result EPA
1 1st & 10 4-yard run -0.2
2 2nd & 6 8-yard pass +0.8
3 1st & 10 Incomplete -0.5
4 2nd & 10 12-yard pass +0.9
5 1st & 10 5-yard run +0.1
6 2nd & 5 Touchdown pass +3.2

Questions: a) What was the total drive EPA? b) Which play was most valuable? c) How would you color-code these plays in a visualization? d) What does the negative EPA on play 1 tell us despite gaining yards?

Exercise 1.5: Win Probability Analysis

Examine this win probability sequence:

Start of game: 50%
After Q1: 45%
After Q2: 38%
After opponent's opening Q3 TD: 28%
After our answering TD: 42%
After interception: 55%
Final: 62%

Questions: a) At what point was the comeback most unlikely? b) What was the biggest WP swing? c) How would you annotate key moments on this curve? d) What visual elements would emphasize the comeback narrative?


Level 2: Basic Visualizations

Exercise 2.1: Simple Drive Chart

Create a basic drive chart for the following drive:

drive = [
    {'yard_line': 20, 'yards_gained': 8, 'play_type': 'pass'},
    {'yard_line': 28, 'yards_gained': 4, 'play_type': 'rush'},
    {'yard_line': 32, 'yards_gained': 15, 'play_type': 'pass'},
    {'yard_line': 47, 'yards_gained': 3, 'play_type': 'rush'},
    {'yard_line': 50, 'yards_gained': 25, 'play_type': 'pass'},
    {'yard_line': 75, 'yards_gained': 8, 'play_type': 'rush'},
    {'yard_line': 83, 'yards_gained': 12, 'play_type': 'pass'},
    {'yard_line': 95, 'yards_gained': 5, 'play_type': 'rush', 'touchdown': True}
]

Requirements: 1. Draw a football field as background 2. Show each play as a segment 3. Color-code by play type 4. Mark the touchdown 5. Add a title with drive summary (plays, yards)

Exercise 2.2: EPA Bar Chart

Create a bar chart showing EPA for each play in the drive from Exercise 2.1. Use the following EPA values:

epa_values = [0.3, 0.1, 1.5, -0.2, 2.1, 0.4, 0.9, 2.8]

Requirements: 1. Horizontal bars for each play 2. Color-code positive (green) and negative (red) EPA 3. Include cumulative EPA line overlay 4. Add play descriptions as labels 5. Show total drive EPA

Exercise 2.3: Basic Win Probability Chart

Create a win probability chart from the following data:

wp_data = [
    {'time': 60, 'wp': 0.50},  # Start
    {'time': 55, 'wp': 0.48},
    {'time': 50, 'wp': 0.52},
    {'time': 45, 'wp': 0.58},  # TD
    {'time': 40, 'wp': 0.55},
    {'time': 35, 'wp': 0.45},  # Opponent TD
    {'time': 30, 'wp': 0.48},  # Halftime
    {'time': 25, 'wp': 0.42},
    {'time': 20, 'wp': 0.55},  # Big play
    {'time': 15, 'wp': 0.62},
    {'time': 10, 'wp': 0.58},
    {'time': 5, 'wp': 0.75},   # Late TD
    {'time': 0, 'wp': 0.85}    # Final
]

Requirements: 1. Time on x-axis (60 minutes to 0) 2. WP on y-axis (0% to 100%) 3. Fill area above/below 50% 4. Quarter markers 5. Title and team labels

Exercise 2.4: Down and Distance Heatmap

Create a heatmap showing success rate by down and distance:

success_rates = {
    # (down, distance_bin): success_rate
    (1, '1-3'): 0.72, (1, '4-6'): 0.58, (1, '7-10'): 0.48, (1, '11+'): 0.42,
    (2, '1-3'): 0.68, (2, '4-6'): 0.52, (2, '7-10'): 0.40, (2, '11+'): 0.32,
    (3, '1-3'): 0.65, (3, '4-6'): 0.45, (3, '7-10'): 0.28, (3, '11+'): 0.18,
}

Requirements: 1. Downs as rows, distance bins as columns 2. Color intensity by success rate 3. Cell annotations with percentages 4. Colorblind-accessible palette 5. Clear axis labels and title

Exercise 2.5: Play Sequence Diagram

Create a sequence diagram for a 5-play drive:

plays = [
    {'down': 1, 'distance': 10, 'play_type': 'rush', 'yards': 4, 'epa': 0.1},
    {'down': 2, 'distance': 6, 'play_type': 'pass', 'yards': 8, 'epa': 0.6},
    {'down': 1, 'distance': 10, 'play_type': 'pass', 'yards': 0, 'epa': -0.5},
    {'down': 2, 'distance': 10, 'play_type': 'rush', 'yards': 3, 'epa': -0.2},
    {'down': 3, 'distance': 7, 'play_type': 'pass', 'yards': 12, 'epa': 1.1},
]

Requirements: 1. Horizontal layout with play boxes 2. Show down & distance above each box 3. Play type indicator in box 4. Yards gained below box 5. EPA value color-coded


Level 3: Advanced Visualizations

Exercise 3.1: Multi-Drive Game Summary

Create a visualization showing all offensive drives in a game:

drives = [
    {'start_yl': 25, 'plays': 6, 'yards': 75, 'result': 'touchdown'},
    {'start_yl': 30, 'plays': 3, 'yards': -2, 'result': 'punt'},
    {'start_yl': 15, 'plays': 8, 'yards': 52, 'result': 'field_goal'},
    {'start_yl': 35, 'plays': 4, 'yards': 28, 'result': 'turnover'},
    {'start_yl': 20, 'plays': 7, 'yards': 80, 'result': 'touchdown'},
    {'start_yl': 40, 'plays': 5, 'yards': 35, 'result': 'downs'},
    {'start_yl': 25, 'plays': 9, 'yards': 75, 'result': 'touchdown'},
    {'start_yl': 55, 'plays': 4, 'yards': 45, 'result': 'touchdown'},
]

Requirements: 1. Stacked horizontal drive bars 2. Color-coded by result 3. Starting position indicated 4. Drive statistics displayed 5. Legend for result types

Exercise 3.2: WP Swing Analysis

Create a visualization showing the top 10 biggest win probability swings:

big_plays = [
    {'description': 'Pick-6 by defense', 'wpa': 0.28},
    {'description': '75-yard TD pass', 'wpa': 0.22},
    {'description': 'Fumble at goal line', 'wpa': -0.25},
    {'description': 'Game-winning FG', 'wpa': 0.18},
    {'description': '4th down conversion', 'wpa': 0.15},
    {'description': 'Red zone interception', 'wpa': -0.20},
    {'description': '50-yard TD run', 'wpa': 0.16},
    {'description': 'Blocked punt TD', 'wpa': 0.19},
    {'description': 'Failed 2-pt conversion', 'wpa': -0.12},
    {'description': 'Onside kick recovery', 'wpa': 0.14},
]

Requirements: 1. Horizontal bar chart 2. Bars extending from center (0) 3. Positive plays green, negative red 4. Sorted by absolute magnitude 5. WPA percentage labels

Exercise 3.3: EPA Flow Visualization

Create a cumulative EPA chart for a game:

import numpy as np
np.random.seed(42)

# 150 plays with EPA values
plays = []
for i in range(150):
    epa = np.random.normal(0.05, 0.8)
    plays.append({
        'play_num': i + 1,
        'team': 'home' if i % 2 == 0 else 'away',
        'epa': epa
    })

Requirements: 1. Separate cumulative lines for each team 2. Play numbers on x-axis 3. Shaded areas showing lead changes 4. Quarter markers 5. Final EPA totals annotated

Exercise 3.4: Situational Performance Comparison

Create a side-by-side comparison of two teams' EPA by situation:

team_a_epa = {
    '1st & 10': 0.15, '2nd & Short': 0.22, '2nd & Long': -0.08,
    '3rd & Short': 0.35, '3rd & Medium': 0.12, '3rd & Long': -0.25,
    'Red Zone': 0.42, 'Goal Line': 0.55
}

team_b_epa = {
    '1st & 10': 0.08, '2nd & Short': 0.18, '2nd & Long': 0.02,
    '3rd & Short': 0.28, '3rd & Medium': -0.05, '3rd & Long': -0.18,
    'Red Zone': 0.25, 'Goal Line': 0.32
}

Requirements: 1. Grouped bar chart or butterfly chart 2. Clear team identification 3. Zero reference line 4. Values labeled 5. Highlight biggest differences

Exercise 3.5: Play-by-Play Timeline

Create a timeline visualization for a single quarter:

quarter_plays = [
    {'time': '15:00', 'team': 'home', 'type': 'kickoff', 'epa': 0},
    {'time': '14:45', 'team': 'home', 'type': 'rush', 'epa': 0.2},
    {'time': '14:10', 'team': 'home', 'type': 'pass', 'epa': 1.1},
    {'time': '13:30', 'team': 'home', 'type': 'pass', 'epa': -0.3},
    # ... more plays
]

Requirements: 1. Vertical timeline 2. Plays alternating left/right by team 3. EPA encoded by marker size and color 4. Time labels on spine 5. Play type icons or indicators


Level 4: Dashboard Projects

Exercise 4.1: Single Game Dashboard

Create a comprehensive dashboard for a single game including:

  1. Win probability chart (main visual)
  2. Drive summary for both teams
  3. Key play highlights
  4. Situational performance comparison
  5. Final score and statistics

Use the data structure provided in the chapter or generate realistic game data.

Exercise 4.2: Drive Analysis Tool

Build an interactive drive analyzer that:

  1. Shows all drives in a game
  2. Allows selection of individual drives
  3. Displays detailed play-by-play for selected drive
  4. Shows EPA breakdown
  5. Compares to season averages

Exercise 4.3: Live Game Simulation

Create a visualization that simulates live game updates:

  1. Win probability that updates with each play
  2. Current game state display
  3. Recent plays feed
  4. Drive progress indicator
  5. Key statistics tracker

Level 5: Professional Projects

Exercise 5.1: Broadcast Graphics Package

Design and implement a set of play-by-play graphics for TV broadcast:

  1. Pre-snap down and distance display
  2. Post-play result graphic
  3. Drive summary chart
  4. Win probability meter
  5. Key moment highlight graphic

Requirements: - 1920×1080 resolution - 5-8 second display time - Clear from 10+ feet viewing distance

Exercise 5.2: Coaching Film Session Tool

Create visualizations for coaching staff film review:

  1. Play diagram with outcome
  2. Situational tendency charts
  3. EPA breakdown by formation
  4. Personnel performance comparison
  5. Drive efficiency analysis

Requirements: - Print-ready (300 DPI) - Dense information appropriate for study - Links to video timestamps

Exercise 5.3: Complete Game Recap Package

Build a full game recap visualization suite:

  1. Executive summary (1 page)
  2. Win probability narrative
  3. Drive-by-drive breakdown
  4. Key plays analysis
  5. Statistical comparison
  6. Next week preview implications

Requirements: - Multiple output formats (web, print, social) - Consistent branding - Automated generation capability


Submission Guidelines

For All Exercises:

  1. Include complete, runnable Python code
  2. Use consistent styling throughout
  3. Add appropriate titles, labels, and legends
  4. Document design decisions

Code Quality:

  • Functions for reusable components
  • Clear variable names
  • Comments explaining complex logic
  • Error handling for edge cases

Visualization Checklist:

  • [ ] Clear title describing the content
  • [ ] Labeled axes with units
  • [ ] Legend where needed
  • [ ] Colorblind-friendly palette
  • [ ] Appropriate data-ink ratio
  • [ ] Consistent styling

Answer Key Notes

Solutions are provided in code/exercise-solutions.py with: - Complete implementations - Multiple approaches where appropriate - Performance considerations - Extension suggestions