Chapter 15: Exercises - Interactive Dashboards

Exercise Overview

These exercises build skills in creating interactive dashboards for football analytics, progressing from basic interactive charts to complete web applications.


Level 1: Conceptual Understanding

Exercise 1.1: Interaction Type Classification

For each scenario, identify the appropriate interaction type (filter, select, drill, link, hover):

a) User clicks a team dot to see detailed statistics b) User selects multiple conferences from a dropdown c) User moves from season view to game view to play view d) User hovers over a play to see the description e) User selects a game in one chart and all other charts update

Exercise 1.2: Framework Selection

Match each requirement to the most appropriate framework (Plotly, Dash, Streamlit):

  1. Quick prototype for analyst to explore data in Jupyter
  2. Production dashboard with authentication for coaching staff
  3. Simple data exploration app for recruiting coordinator
  4. Embeddable interactive chart for website
  5. Multi-page application with database connectivity

Exercise 1.3: Design Critique

Review this dashboard description and identify design problems:

"The dashboard loads all 50,000 plays immediately. The main chart shows a scatter plot with 130 team dots, all the same size and color. Clicking a dot does nothing visible. Filters are at the bottom of the page. There's no loading indicator when switching seasons."


Level 2: Implementation Basics

Exercise 2.1: Interactive Scatter Plot with Plotly

Create an interactive scatter plot showing team efficiency:

import plotly.express as px
import pandas as pd

teams_df = pd.DataFrame({
    'team': ['Georgia', 'Ohio State', 'Alabama', 'Michigan', 'Texas',
             'Oregon', 'Penn State', 'Washington', 'FSU', 'USC'],
    'offensive_epa': [0.28, 0.25, 0.22, 0.18, 0.21, 0.23, 0.15, 0.24, 0.19, 0.16],
    'defensive_epa': [-0.22, -0.18, -0.19, -0.24, -0.15, -0.14, -0.20, -0.12, -0.16, -0.10],
    'wins': [13, 12, 11, 13, 12, 12, 10, 14, 13, 8],
    'conference': ['SEC', 'Big Ten', 'SEC', 'Big Ten', 'SEC',
                   'Pac-12', 'Big Ten', 'Pac-12', 'ACC', 'Pac-12']
})

Requirements: - X-axis: offensive EPA - Y-axis: defensive EPA - Point size based on wins - Color by conference - Hover shows team name and all stats - Appropriate title and axis labels

Exercise 2.2: Interactive Bar Chart

Create an interactive horizontal bar chart ranking teams:

# Use the same teams_df from Exercise 2.1

Requirements: - Sort teams by offensive EPA (highest at top) - Color bars by conference - Hover template showing: Team, Conference, EPA, Wins - Animation on load

Exercise 2.3: Basic Streamlit App

Create a Streamlit app with filters:

# streamlit_basic.py
import streamlit as st
import pandas as pd

# Use teams_df from Exercise 2.1

Requirements: - Sidebar with conference multiselect filter - Slider for minimum wins filter - Display filtered data table - Show count of filtered teams


Level 3: Intermediate Applications

Exercise 3.1: Dash Dashboard with Callbacks

Create a Dash dashboard with interactive filtering:

from dash import Dash, html, dcc, callback, Output, Input
import dash_bootstrap_components as dbc

Requirements: - Conference dropdown filter - Minimum wins slider - Scatter plot that updates with filters - Bar chart that updates with filters - Both charts styled consistently

Exercise 3.2: Cross-Filtering Implementation

Extend Exercise 3.1 to add cross-filtering:

Requirements: - Selecting a point in scatter plot highlights that team's bar - Selecting a bar highlights that team's point - Selected team name displayed below charts

Exercise 3.3: Linked Time Series

Create linked charts for win probability:

# Sample play data
plays_df = pd.DataFrame({
    'play_num': range(1, 61),
    'game_time': [60 - i for i in range(60)],
    'wp_home': [0.5 + np.random.uniform(-0.05, 0.05) * i/10 for i in range(60)],
    'epa': np.random.uniform(-2, 2, 60),
    'play_type': np.random.choice(['pass', 'rush'], 60),
    'description': [f'Play {i}' for i in range(1, 61)]
})

Requirements: - Win probability chart (top) - EPA chart (bottom) - Selecting a range in WP chart filters EPA chart - Hover on either chart shows play description


Level 4: Advanced Techniques

Exercise 4.1: Drill-Down Dashboard

Create a dashboard with drill-down navigation:

Levels: 1. Conference view (aggregated stats) 2. Team view (all teams in conference) 3. Player view (players on selected team)

Requirements: - Click conference to drill to teams - Click team to drill to players - "Back" button to navigate up - Breadcrumb showing current path

Exercise 4.2: Performance Optimization

Optimize this slow dashboard:

# Current implementation (slow)
@callback(Output('chart', 'figure'), Input('filter', 'value'))
def update(filter_val):
    # Loads ALL plays every time
    all_plays = pd.read_csv('all_plays.csv')  # 500,000 rows
    filtered = all_plays[all_plays['team'] == filter_val]
    return px.scatter(filtered, x='yard_line', y='epa')

Requirements: - Implement caching - Add loading indicator - Paginate or aggregate large data - Use clientside callbacks where possible

Exercise 4.3: Custom Components

Create a custom KPI card component:

def create_kpi_card(title: str, value: float,
                    change: float = None,
                    format_str: str = '{:.1f}') -> html.Div:
    """
    Create a KPI card component.

    Args:
        title: Metric name
        value: Current value
        change: Change from previous period (optional)
        format_str: Format string for value

    Returns:
        Dash HTML Div component
    """
    pass  # Implement this

Requirements: - Title at top - Large formatted value - Change indicator (green up arrow / red down arrow) - Hover showing additional context


Level 5: Professional Applications

Exercise 5.1: Complete Game Analysis Dashboard

Build a full game analysis dashboard:

Data: - Play-by-play data (100+ plays) - Drive summaries - Player statistics - Win probability at each play

Required Components: 1. Game summary header (score, key stats) 2. Win probability chart with annotations 3. Drive summary visualization 4. Play-by-play table with filtering 5. Player stats comparison

Interactions: - Click drive to filter plays - Hover play for description - Filter by quarter, team, play type - Toggle between different metrics

Exercise 5.2: Multi-Page Analytics App

Create a multi-page Dash or Streamlit application:

Pages: 1. Season Overview (team rankings, standings) 2. Team Deep Dive (selected team analysis) 3. Player Comparison (compare any players) 4. Game Finder (filter games by criteria)

Requirements: - Navigation between pages - Shared filters/state across pages - Consistent styling - User authentication (if Dash)

Exercise 5.3: Real-Time Simulation Dashboard

Create a dashboard that simulates live game updates:

Requirements: - Timer that advances game clock - Win probability updates in real-time - Play-by-play feed that grows - Highlight key plays with animations - Pause/resume controls


Challenge Exercises

Challenge A: Mobile-Responsive Dashboard

Create a dashboard that works well on mobile devices: - Responsive layout - Touch-friendly interactions - Simplified mobile view

Challenge B: Embedded Visualizations

Create interactive charts that can be embedded in other websites: - Generate standalone HTML files - Maintain interactivity when embedded - Optimize for web performance

Challenge C: Collaborative Dashboard

Create a dashboard with collaboration features: - Save and share filter states - Annotations that persist - Export selections to report


Submission Checklist

For each exercise, submit:

  • [ ] Complete Python code (all files)
  • [ ] requirements.txt with dependencies
  • [ ] Screenshot of running dashboard
  • [ ] Brief description of design choices
  • [ ] Notes on performance considerations

Grading Criteria

Criterion Weight
Functionality 30%
Interactivity 25%
Design/UX 20%
Code quality 15%
Performance 10%