COURT
VISION

Pick a player. See every shot they take, and where they score better than the rest of the league. Then meet their statistical twin.

Scroll to take the shot
COURT VISION
— player-seasons

SHOT CHART EXPLORER

Search any player below. Each hexagon is a spot on the floor — bigger where he shot more, warm where he scored better than the league from that spot, and cool where he scored worse.

BELOW LEAGUE
ABOVE LEAGUE • small = few shots    ⬢ big = high volume

League-relative means measured against every NBA player's average from that exact zone that season. A hot hex in the corner is worth more than a hot hex at the elbow because a corner three is worth three points. Rare spots (a lone half-court heave) are dropped as noise.

STATISTICAL TWINS

Each player-season is a point in a 13-dimensional box-score space (scoring, playmaking, rebounding, shot diet, efficiency), rescaled so no single stat dominates. The nearest points are the twins, and they cross eras freely.

Pick a player

Similarity is box-score only. It cannot see defense, spacing, role, or who set the screen, and a 45-game season is noisier than an 82-game one. Read a twin as "these two produced a similar statistical shape," not "these two are the same player."

HOW IT WORKS

Two tools sit on one dataset: a decade of NBA player-seasons, every shot located on the floor and every box-score line rescaled for fair comparison.

  1. Shot location. Every field-goal attempt carries an x, y spot and a made/missed flag. Attempts are binned into hexagons; each hex gets the player's points-per-shot there minus the league's points-per-shot from the same zone that season.
  2. League-relative color. The same NBA feed returns league shooting by zone, so "above average" always means above that season's league, not a fixed number. Threes are scored as three points, so efficient corners glow brighter than efficient elbows.
  3. Similarity space. Thirteen per-100-possession and shot-diet stats are standardized across the whole pool, then straight-line distance ranks the nearest player-seasons. A player's own other seasons are excluded so the twins are genuinely someone else.
  4. Archetype + scouting. A rule reads each box profile into an archetype (movement shooter, rim-running big, lead creator, and so on). The scouting blurb is generated from the baked numbers, so every figure it cites is exact, none of it is invented.

Honesty

  • Shot value is league-relative and location-based. It rewards taking, and making, high-value shots. It is not a total-offense rating and says nothing about defense.
  • Similarity is box-score only. It has no idea who the primary option was, how good the spacing was, or how the shots were created.
  • The pool is the league's top scorers across eight seasons, not every player, so a "twin" is the closest match inside this set.

Data & build

Shot and box data come from the public nba_api feed for stats.nba.com (no scraping of Sports-Reference). A local Python pipeline pulls the data, bins the shots, builds the similarity matrix, and bakes small JSON tables; the page does every lookup in your browser, so there is zero server cost and the numbers are fully inspectable.

Built end to end with Claude Code — the data pipeline, the hexbin and similarity math, and this interface. Source: github.com/agv117/nba. Project 03 in a series of interactive sports-analytics builds.