@sportsdataverse/sporty gallery
Surfaces, options, units, shapes
{
"arcResolution: 12": {
"points": 1888,
"toSVG": "33.0 KB",
"toSVG arcs: \"svg\"": "14.8 KB"
},
"arcResolution: 200 (default)": {
"points": 24824,
"toSVG": "446.6 KB",
"toSVG arcs: \"svg\"": "32.6 KB"
}
}{
"baseball": {
"leagues": "custom, little league, milb, mlb, ncaa, nfhs, pony",
"displayRanges": 2,
"features": 10,
"colorKeys": 10,
"displayRanges (first 6)": "full, infield"
},
"basketball": {
"leagues": "custom, fiba, nba, nba g league, ncaa, nfhs, wnba",
"displayRanges": 49,
"features": 23,
"colorKeys": 26,
"displayRanges (first 6)": "full, in_bounds_only, in bounds only, offense, offence, offensivehalfcourt"
},
"curling": {
"leagues": "curling canada, custom, wcf",
"displayRanges": 4,
"features": 12,
"colorKeys": 14,
"displayRanges (first 6)": "full, in_bounds_only, in bounds only, house"
},
"football": {
"leagues": "cfl, custom, ncaa, nfhs11, nfhs6, nfhs8, nfhs9, nfl",
"displayRanges": 22,
"features": 21,
"colorKeys": 23,
"displayRanges (first 6)": "full, in_bounds_only, in bounds only, offense, offence, offensivehalffield"
},
"hockey": {
"leagues": "ahl, custom, echl, iihf, ncaa, nhl, nwhl, ohl, phf, pwhl, qmjhl, ushl",
"displayRanges": 21,
"features": 24,
"colorKeys": 25,
"displayRanges (first 6)": "full, in_bounds_only, in bounds only, offense, offence, defense"
},
"lacrosse": {
"leagues": "custom, ncaam, ncaaw, nll, pll, usam, usaw, world lacrosse",
"displayRanges": 13,
"features": 33,
"colorKeys": 35,
"displayRanges (first 6)": "full, in_bounds_only, in bounds only, offense, offence, offensivehalffield"
},
"soccer": {
"leagues": "custom, epl, fifa, mls, ncaa, nwsl",
"displayRanges": 13,
"features": 13,
"colorKeys": 15,
"displayRanges (first 6)": "full, in_bounds_only, in bounds only, offense, offence, offensivehalfpitch"
},
"tennis": {
"leagues": "atp, custom, ita, itf, ncaa, usta, wta",
"displayRanges": 22,
"features": 10,
"colorKeys": 13,
"displayRanges (first 6)": "full, in_bounds_only, in bounds only, serve, serving, servicehalf"
},
"volleyball": {
"leagues": "custom, fivb, ncaa, usa volleyball",
"displayRanges": 13,
"features": 10,
"colorKeys": 12,
"displayRanges (first 6)": "full, in_bounds_only, in bounds only, offense, offence, offensivehalfcourt"
}
}{
"surface(\"hockey\", \"khl\")": {
"name": "UnknownLeagueError",
"instanceof SportyError": true,
"instanceof UnknownLeagueError": true,
"instanceof UnknownDisplayRangeError": false,
"instanceof UnknownUnitError": false,
"instanceof InputError": false,
"message": "Unknown hockey league \"khl\"; expected one of: ahl, custom, echl, iihf, ncaa, nhl, nwhl, ohl, phf, pwhl, qmjhl,…"
},
"surface(\"hockey\", \"nhl\", { displayRange: \"slot\" })": {
"name": "UnknownDisplayRangeError",
"instanceof SportyError": true,
"instanceof UnknownLeagueError": false,
"instanceof UnknownDisplayRangeError": true,
"instanceof UnknownUnitError": false,
"instanceof InputError": false,
"message": "Unknown hockey display range \"slot\"; expected one of: full, in_bounds_only, in bounds only, offense, offence, …"
},
"normalizeUnit(\"furlong\")": {
"name": "UnknownUnitError",
"instanceof SportyError": true,
"instanceof UnknownLeagueError": false,
"instanceof UnknownDisplayRangeError": false,
"instanceof UnknownUnitError": true,
"instanceof InputError": false,
"message": "Unknown unit \"furlong\"; expected one of: mm, cm, m, in, ft, yd (or a full name such as \"feet\")"
},
"surface(\"soccer\", \"epl\", { arcResolution: 1 })": {
"name": "SportyError",
"instanceof SportyError": true,
"instanceof UnknownLeagueError": false,
"instanceof UnknownDisplayRangeError": false,
"instanceof UnknownUnitError": false,
"instanceof InputError": false,
"message": "arcResolution must be an integer >= 2; got 1"
},
"drawScene(ctx, surface(\"soccer\", \"epl\", { xlim: [0, 0] }))": {
"name": "InputError",
"instanceof SportyError": true,
"instanceof UnknownLeagueError": false,
"instanceof UnknownDisplayRangeError": false,
"instanceof UnknownUnitError": false,
"instanceof InputError": true,
"message": "soccer \"epl\" has an empty bbox [0, -50, 0, 50]; nothing to draw"
}
}{
"BASKETBALL_SPECS.nba lane": {
"court_units": "ft",
"lane_width": "16, 12",
"lane_length": "19, 19",
"free_throw_line_to_backboard": 15,
"basket_center_to_three_point_arc": "23.75"
},
"@sportsdataverse/sporty/specs": {
"BASEBALL_SPECS": "7 leagues: custom, little league, milb, mlb, ncaa, nfhs, pony",
"BASKETBALL_SPECS": "7 leagues: custom, fiba, nba, nba g league, ncaa, nfhs, wnba",
"CURLING_SPECS": "3 leagues: curling canada, custom, wcf",
"FOOTBALL_SPECS": "8 leagues: cfl, custom, ncaa, nfhs11, nfhs6, nfhs8, nfhs9, nfl",
"HOCKEY_SPECS": "12 leagues: ahl, custom, echl, iihf, ncaa, nhl, nwhl, ohl, phf, pwhl, qmjhl, ushl",
"LACROSSE_SPECS": "8 leagues: custom, ncaam, ncaaw, nll, pll, usam, usaw, world lacrosse",
"SOCCER_SPECS": "6 leagues: custom, epl, fifa, mls, ncaa, nwsl",
"TENNIS_SPECS": "7 leagues: atp, custom, ita, itf, ncaa, usta, wta",
"VOLLEYBALL_SPECS": "4 leagues: custom, fivb, ncaa, usa volleyball"
}
}placeFeature(…, reflectX, reflectY)reflectCoords(…, { overY: true })rotateCoords(…, 90)the shape
court.units: mcourt.bbox (m): -16.76, -9.14, 16.76, 9.14convertUnits(94, 'ft', 'm'): 28.651convertPoints([[47, 25]], 'ft', 'yd'): [[15.666666666666666,8.333333333333334]]normalizeUnit('Metres'): mFT_PER_UNIT.m: 3.2808
Observable Plot
back_linebuttoncentre_linecentre_zonecourtesy_lineendhack_footholdhack_linehog_linehouse_ringsheet_aprontee_line
{
"baseball little league": "14 of 14 polygons drawn",
"basketball fiba": "60 of 64 polygons drawn",
"curling curling canada": "30 of 30 polygons drawn",
"football cfl": "444 of 496 polygons drawn",
"hockey ahl": "63 of 63 polygons drawn",
"lacrosse ncaam": "73 of 73 polygons drawn",
"soccer epl": "35 of 35 polygons drawn",
"tennis atp": "23 of 23 polygons drawn",
"volleyball fivb": "39 of 39 polygons drawn"
}D3
SVG renderer
[ "baseball little league 26 KB -> 2.5 KB", "basketball fiba 91.6 KB -> 7.1 KB", "curling curling canada 30.4 KB -> 3.4 KB", "football cfl 65.2 KB -> 65.2 KB", "hockey ahl 446.6 KB -> 32.6 KB", "lacrosse ncaam 146.5 KB -> 51.7 KB", "soccer epl 86.5 KB -> 4.8 KB", "tennis atp 2.3 KB -> 2.3 KB", "volleyball fivb 3.7 KB -> 3.7 KB" ]
Canvas renderer
Every surface
baseball: little leaguebaseball: milbbaseball: mlbbaseball: ncaabaseball: nfhsbaseball: ponybasketball: fibabasketball: nbabasketball: nba g leaguebasketball: ncaabasketball: nfhsbasketball: wnbacurling: curling canadacurling: wcffootball: cflfootball: ncaafootball: nfhs11football: nfhs6football: nfhs8football: nfhs9football: nflhockey: ahlhockey: echlhockey: iihfhockey: ncaahockey: nhlhockey: nwhlhockey: ohlhockey: phfhockey: pwhlhockey: qmjhlhockey: ushllacrosse: ncaamlacrosse: ncaawlacrosse: nlllacrosse: plllacrosse: usamlacrosse: usawlacrosse: world lacrossesoccer: eplsoccer: fifasoccer: mlssoccer: ncaasoccer: nwsltennis: atptennis: itatennis: itftennis: ncaatennis: ustatennis: wtavolleyball: fivbvolleyball: ncaavolleyball: usa volleyball
Coordinate frames
Frame: data with the origin in a cornerFrame: write your ownFrame: ESPN football yardlinesFrame: the HockeyTech 600x300 canvasFrame: stats.nba.com legacy shot coordinates (LAL at DEN, fourth quarter; made green, missed red)The built-in frames
[
{
"px": 504,
"py": 0,
"surface_x": 42,
"surface_y": 0
},
{
"px": -282,
"py": 120,
"surface_x": -23.5,
"surface_y": 10
}
][
{
"team": "PHI",
"period": 1,
"clock": "6:15",
"yardline": 99,
"field_x": 49,
"field_y": null
},
{
"team": "PHI",
"period": 2,
"clock": "1:35",
"yardline": 88,
"field_x": 38,
"field_y": null
},
{
"team": "PHI",
"period": 3,
"clock": "2:40",
"yardline": 54,
"field_x": 4,
"field_y": null
},
{
"team": "KC",
"period": 3,
"clock": "0:34",
"yardline": 24,
"field_x": -26,
"field_y": null
},
{
"team": "KC",
"period": 4,
"clock": "2:54",
"yardline": 7,
"field_x": -43,
"field_y": null
},
{
"team": "KC",
"period": 4,
"clock": "1:48",
"yardline": 50,
"field_x": 0,
"field_y": null
}
]{
"hockeytech": "HockeyTech 600x300 canvas, top-left origin -> 200x85 ft centre origin (fastRhockey hockeytech_analytics: x/3-100, 42.5-y*85/300). The canvas is stylised rather than true to scale: converted end-zone faceoff dots land at about ±67 ft and ±52 ft against regulation ±69 ft, so the converted feet are approximate",
"PWHL Boston at Montreal, 2024-03-02 (game 42): goals": [
"MTL Marie-Philip Poulin, P1 3:51: (90, 123) -> (-70.0, 7.7) ft",
"MTL Mélodie Daoust, P2 4:50: (57, 105) -> (-81.0, 12.8) ft",
"BOS Hilary Knight, P2 14:55: (470, 117) -> (56.7, 9.3) ft",
"MTL Erin Ambrose, P3 2:29: (196, 61) -> (-34.7, 25.2) ft"
]
}{
"nba-legacy": "stats.nba.com shot frame: tenths of a foot, hoop origin, x across the court (sdvplot court_coords; input columns default to x_legacy/y_legacy)",
"nba-legacy-vertical": "stats.nba.com shot frame with the hoop at the bottom: points already in a rotation-90 scene's rotated frame (do not rotate them again); x across with its sign kept, y toward half court",
"hockeytech": "HockeyTech 600x300 canvas, top-left origin -> 200x85 ft centre origin (fastRhockey hockeytech_analytics: x/3-100, 42.5-y*85/300). The canvas is stylised rather than true to scale: converted end-zone faceoff dots land at about ±67 ft and ±52 ft against regulation ±69 ft, so the converted feet are approximate",
"espn-football-0-100": "ESPN football: x is a 0-100 yardline -> -50..50 along x; y passes through (yards)"
}From the API docs
3
[ "Restricted area", "Paint (non-RA)", "Mid-range", "Left corner 3", "Right corner 3", "Above-the-break 3" ]
[
{
"x_legacy": -53,
"y_legacy": 285,
"team": "LAL",
"player": "LeBron James",
"surface_x": -13.25,
"surface_y": -5.3
},
{
"x_legacy": -136,
"y_legacy": 214,
"team": "DEN",
"player": "Nikola Jokić",
"surface_x": -20.35,
"surface_y": -13.6
}
]