Skip to content

ahartnet/EPAViz

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EPA Density Viewer

An interactive GUI application for visualizing EPA (Estimated Performance Agility) distributions across FRC (FIRST Robotics Competition) team years. Built with Python and tkinter, it provides real-time exploration of team strength distributions with color-coded quartile displays.

Features

Core Visualization

  • Per-Year Density Curves: Each year gets its own colored kernel density estimation (KDE) curve
  • Interactive Year Selection: Checkbox controls to select/deselect years for analysis
  • Normalized EPA Display: Automatically normalizes EPA values to 0-100% scale (percentage of max EPA)
  • Percentile Lines: Optional vertical lines showing 25th (Q1), 50th (Q2/Median), and 75th (Q3) percentiles
  • Real-Time Updates: Plot updates instantly as you change selections

Data Controls & Analysis

  • Data Trimming: Remove outliers by specifying top/bottom percentages (e.g., trim top 5% and bottom 5%)
  • Select All/Deselect All: Quick buttons to manage year selections
  • Always-Visible Quartiles: Color-coded spreadsheet showing Q1, Q2, Q3 values for each year
    • Green (55+): Strong teams
    • Yellow (27.5-55): Average teams
    • Red (<27.5): Below average

Interactive Features

  • Hover Tooltips: Mouse over curves to see exact EPA%, percentile rank, and year information
  • Per-Year Status: Real-time count of teams included when selections change
  • Automatic Recalculation: Trimming and selections update statistics and plot instantly

Distribution

  • Full Source Code: Complete Python source for customization and cross-platform use
  • Easy Setup: Simple pip install of dependencies

Installation & Usage

Requirements:

  • Python 3.7+
  • pandas
  • numpy
  • matplotlib
  • scipy
  • tkinter (included with Python)

Install dependencies:

pip install pandas numpy matplotlib scipy

Run the application:

python EPADensityViewer.py

User Guide

Getting Started

  1. Load Data: The app automatically loads all_team_years.json on startup
  2. Select Years: Use checkboxes or "Select All"/"Deselect All" buttons
  3. Toggle Percentile Lines: Check boxes next to Q1, Q2, Q3 to show/hide them
  4. Adjust Trimming: Enter percentages to trim extreme values
  5. Review Quartiles: Check the spreadsheet on the left for per-year statistics

Example Workflows

Comparing all-time trends:

  • Click "Select All"
  • Observe how distributions have changed across decades

Analyzing a single season:

  • Uncheck all years except one
  • Focus on Q1/Q2/Q3 values to understand that year's team spread

Removing outliers:

  • Set "Trim top %": 5
  • Set "Trim bottom %": 5
  • View cleaner distribution with extreme teams excluded

Recent years comparison:

  • Select only 2022, 2023, 2024, 2025, 2026
  • Compare distribution shapes and see if EPA values are changing

Data Format

The application expects all_team_years.json with this structure:

[
  {
    "team": 1234,
    "year": 2022,
    "epa_unitless": 1450.0,
    "epa_norm": 1450.0,
    "epa": 25.5
  },
  {
    "team": 1235,
    "year": 2022,
    "epa_unitless": 1500.0,
    "epa_norm": 1500.0,
    "epa": 50.0
  }
]

Required fields: team, year, epa
Optional fields: epa_unitless, epa_norm

Terminology

  • EPA: Estimated Performance Agility - metric from Statbotics API measuring team strength
  • KDE (Kernel Density Estimation): Smooth curve showing distribution shape
  • Normalized EPA: Each year's EPA values scaled to 0-100% relative to that year's max
  • Quartiles:
    • Q1 (25th percentile): 25% of teams below this
    • Q2 (50th percentile): Median - half above, half below
    • Q3 (75th percentile): 75% of teams below this
  • Trimming: Removes specified percentage from top/bottom before recalculating statistics

UI Components

Left Panel:

  • Year checkboxes with live team count
  • Spreadsheet showing per-year Q1/Q2/Q3 values with color gradient
  • Select All/Deselect All buttons
  • Percentile line toggles (Q1, Q2, Q3)
  • Trim percentage inputs (with 500ms debounce)

Right Panel:

  • Interactive matplotlib plot showing density curves
  • Legend with year labels and actual max EPA values
  • Hover tooltips with detailed statistics

Technical Details

Normalization Pipeline

  1. Original EPA values from data
  2. Normalize to % of original year max
  3. Apply trimming (top/bottom percentages)
  4. Renormalize trimmed data to 0-100 scale
  5. Compute KDE on final normalized values
  6. X-axis always shows 0-100 for consistent comparison

Color Gradient (Quartile Cells)

  • 55-100: Green (full saturation)
  • 27.5-55: Yellow (transitional)
  • 0-27.5: Red (low values)

Performance

  • Efficient KDE computation with scipy
  • Debounced trimming input (500ms) to prevent excessive updates
  • Parallelizable density calculations
  • Fast matplotlib rendering with FigureCanvasTkAgg

Updating Data

Use the companion script UpdateTeamYearsWeekly.py to fetch latest EPA data:

python UpdateTeamYearsWeekly.py

This script:

  • Fetches current year data from Statbotics API
  • Merges with existing historical data
  • Shows which teams were updated
  • Displays EPA statistics for the year
  • Uses efficient batch API calls (only 5 API calls vs 250+)

Example output:

EPA Team Years Weekly Update Script
Current Year: 2026
Timestamp: 2026-03-18 00:52:00

Fetching all 2026 team_years (approach 1: year param)...
  Page 1: Retrieved 1000 records (total so far: 1000)
  Page 2: Retrieved 1000 records (total so far: 2000)
  Page 3: Retrieved 1000 records (total so far: 3000)
  Page 4: Retrieved 763 records (total so far: 3763)

API calls made: 5
Fetched 3763 new records for 2026

TEAMS UPDATED IN 2026
Total teams with new data: 365
...

Architecture

Code Structure

  • EPADensityViewer.py (485 lines): Main application with OOP design

    • Single EPADensityViewer class handles UI, data, and visualization
    • Modular methods for data loading, plotting, and event handling
    • Event-driven architecture with tkinter callbacks
  • UpdateTeamYearsWeekly.py (350 lines): Data update utility

    • Efficient batch API fetching from Statbotics
    • Incremental cache updates (no duplicates)
    • Detailed progress reporting and statistics

Dependencies

  • tkinter: Native GUI (included with Python)
  • matplotlib: Plotting engine with tkinter backend
  • pandas: Data manipulation and statistics
  • numpy: Numerical computations
  • scipy.stats.gaussian_kde: Kernel density estimation

Troubleshooting

Issue: Plot not updating after changing selections

  • Ensure year checkboxes are properly tied to plot update callbacks
  • Check that update_plot() is called on all relevant events

Issue: Import errors

  • Make sure all dependencies are installed: pip install pandas numpy matplotlib scipy
  • Check Python version is 3.7 or higher: python --version

Performance

  • Startup: ~2 seconds (data loading and initial plot)
  • Plot update: <100ms for interactive re-plotting
  • Memory: ~50 MB for full dataset (48,000+ records)
  • API update: ~30 seconds for complete year refresh (5 API calls)

License

[Specify your license - MIT, GPL, Apache 2.0, etc.]

Contributing

Contributions welcome! Areas for enhancement:

  • Export to PNG/PDF
  • Side-by-side year comparisons
  • Team filtering/search
  • Statistical overlays (mean, stdev, etc.)
  • Dark mode UI theme

Data Source

EPA data sourced from Statbotics API

Acknowledgments

  • Statbotics team for the EPA metric and API
  • FIRST Robotics Community for the inspiration

About

compare EPA densities over the years

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages