Skip to content

Commit

Permalink
spraychart scales (#227)
Browse files Browse the repository at this point in the history
* changes coord transform

* adds coordinate transform tests
  • Loading branch information
bdilday authored Jul 30, 2021
1 parent e6703ff commit cfde992
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 3 deletions.
27 changes: 24 additions & 3 deletions pybaseball/plotting.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from functools import partial
from pathlib import Path
from typing import List, Optional
import warnings
Expand All @@ -10,10 +11,30 @@
import pandas as pd

CUR_PATH = Path(__file__).resolve().parent
STADIUM_COORDS = pd.read_csv(Path(CUR_PATH, 'data', 'mlbstadiums.csv'), index_col=0)

# transform over x axis
STADIUM_COORDS['y'] *= -1

def _transform_coordinate(coord: pd.Series, center: float, scale: float, sign: float) -> pd.Series:
return sign * ((coord - center) * scale + center)


def transform_coordinates(coords: pd.DataFrame, scale: float, x_center: float = 125, y_center: float = 199) -> pd.DataFrame:
x_transform = partial(_transform_coordinate, center=x_center, scale=scale, sign=+1)
y_transform = partial(_transform_coordinate, center=y_center, scale=scale, sign=-1)
return coords.assign(x=coords.x.apply(x_transform), y=coords.y.apply(y_transform))


# transform STADIUM_COORDS to match hc_x, hc_y
# the scale factor determined heuristically by:
# - finding the scale of STADIUM_COORDS that will match the outfield dimensions, e.g.,
# for coors, https://www.seamheads.com/ballparks/ballpark.php?parkID=DEN02
# - finding the scale for mlbam data so that hc_x, hc_y match the hit_distance_sc field
# - the center (x=125, y=199) comes from this hardball times article
# https://tht.fangraphs.com/research-notebook-new-format-for-statcast-data-export-at-baseball-savant/

STADIUM_SCALE = 2.495 / 2.33
STADIUM_COORDS = transform_coordinates(
pd.read_csv(Path(CUR_PATH, 'data', 'mlbstadiums.csv'), index_col=0), scale=STADIUM_SCALE
)


def plot_stadium(team: str, title: Optional[str] = None, width: Optional[int] = None,
Expand Down
32 changes: 32 additions & 0 deletions tests/pybaseball/test_plotting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import pytest
import pandas as pd
from pandas.testing import assert_frame_equal, assert_series_equal
from pybaseball.plotting import transform_coordinates


@pytest.fixture
def coords():
return pd.DataFrame({"x": [1.0, 2.0, -1.0], "y": [1.0, 0.0, 10.0]})


def test_transform_coordinates_identity_scale(coords):
transformed_coords = transform_coordinates(coords, scale=1)
assert_series_equal(coords.x, transformed_coords.x)
assert_series_equal(-coords.y, transformed_coords.y)



def test_transform_coordinates(coords):
transformed_coords = transform_coordinates(coords, scale=2, x_center=0, y_center=0)
assert_series_equal(2 * coords.x, transformed_coords.x)
assert_series_equal(-2 * coords.y, transformed_coords.y)

transformed_coords = transform_coordinates(coords, scale=2, x_center=1, y_center=1)
expected = pd.DataFrame({"x": [1.0, 3.0, -3.0], "y": [-1.0, 1.0, -19.0]})
assert_frame_equal(expected, transformed_coords)

xc = 123.4
yc = 432.1
transformed_coords = transform_coordinates(coords, scale=0, x_center=xc, y_center=yc)
assert_series_equal(pd.Series(name="x", data=3 * [xc]), transformed_coords.x)
assert_series_equal(pd.Series(name="y", data=3 * [yc]), -transformed_coords.y)

0 comments on commit cfde992

Please sign in to comment.