A Python library for plotting hockey rinks with Matplotlib.

Overview

Hockey Rink

A Python library for plotting hockey rinks with Matplotlib.

Installation

pip install hockey_rink

Current Rinks

The following shows the custom rinks currently available for plotting.

from hockey_rink import NHLRink, IIHFRink, NWHLRink
import matplotlib.pyplot as plt

fig, axs = plt.subplots(1, 3, sharey=True, figsize=(12, 6), gridspec_kw={"width_ratios": [1, 98.4/85, 1]})
nhl_rink = NHLRink(rotation=90)
iihf_rink = IIHFRink(rotation=90)
nwhl_rink = NWHLRink(rotation=90)
axs[0] = nhl_rink.draw(ax=axs[0])
axs[1] = iihf_rink.draw(ax=axs[1])
axs[2] = nwhl_rink.draw(ax=axs[2])

The NWHL logo comes from the NWHL site.

Customization

There is also room for customization. The image at the top was created as follows:

rink = Rink(rotation=45, boards={"length": 150, "width": 150, "radius": 75})

Rinks also allow for additional features to be added. Custom features should inherit from RinkFeature and override the _get_centered_xy method. The draw method can also be overridden if the desired feature can't be drawn with a matplotlib Polygon, though _get_centered_xy should still provide the feature's boundaries. CircularImage provides an example of this by inheriting from RinkCircle.

If a custom feature is to be constrained to only display within the rink, the returned object needs to have a set_clip_path method.

Plots

There are currently wrappers available for the following Matplotlib plots:
- plot
- scatter
- arrow
- hexbin
- pcolormesh (heatmap in Hockey Rink)
- contour
- contourf

If you'd like to bypass the wrappers, you can convert coordinates to the proper scale with convert_xy:

rink = Rink()
x, y = rink.convert_xy(x, y)

When plotting to a partially drawn surface, the plot will be applied to the entire rink, not what's visible. This can be avoided by setting plot_range (or plot_xlim and plot_ylim) in the plotting functions where they're available.

It's also important to realize that the plotting functions only allow arguments to be passed without keywords for the coordinates.
ie) hexbin(x, y, values) will throw an error.

The correct call is hexbin(x, y, values=values)

Examples

Let's look at some NWHL data via the Big Data Cup.

The first game is Minnesota vs Boston, so we'll go with that and do a scatter plot of each team's shots.

from hockey_rink import NWHLRink
import pandas as pd

df = pd.read_csv("https://raw.githubusercontent.com/bigdatacup/Big-Data-Cup-2021/main/hackathon_nwhl.csv")
game_df = df.loc[(df["Home Team"] == "Minnesota Whitecaps") & (df["Away Team"] == "Boston Pride")]
shots = game_df.loc[(game_df.Event.isin(["Shot", "Goal"]))]
boston_shots = shots[shots.Team == "Boston Pride"]
minnesota_shots = shots[shots.Team == "Minnesota Whitecaps"]
rink = NWHLRink(x_shift=100, y_shift=42.5)
ax = rink.draw()
rink.scatter(boston_shots["X Coordinate"], boston_shots["Y Coordinate"])
rink.scatter(200 - minnesota_shots["X Coordinate"], 85 - minnesota_shots["Y Coordinate"])

Extending the example, let's look at all of Boston's passes.

boston_passes = game_df.loc[(game_df.Team == "Boston Pride") & (game_df.Event == "Play")]
ax.clear()
rink.draw()
arrows = rink.arrow(boston_passes["X Coordinate"], boston_passes["Y Coordinate"], 
                    boston_passes["X Coordinate 2"], boston_passes["Y Coordinate 2"], color="yellow")

For some of the other plots, let's look at some NHL shooting percentages.

To mix things up a little, binsize will take different values in each plot and the heatmap won't include shots from below the goal line. We'll also throw in a colorbar for the contour plot.

from hockey_rink import NHLRink
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

pbp = pd.read_csv("https://hockey-data.harryshomer.com/pbp/nhl_pbp20192020.csv.gz", compression="gzip")
pbp["goal"] = (pbp.Event == "GOAL").astype(int)
pbp["x"] = np.abs(pbp.xC)
pbp["y"] = pbp.yC * np.sign(pbp.xC)
shots = pbp.loc[(pbp.Ev_Zone == "Off") & ~pbp.x.isna() & ~pbp.y.isna() & (pbp.Event.isin(["GOAL", "SHOT", "MISS"]))]

fig, axs = plt.subplots(1, 3, figsize=(14, 8))
rink = NHLRink(rotation=270)
for i in range(3):
    rink.draw(ax=axs[i], display_range="ozone")
contour_img = rink.contourf(shots.x, shots.y, values=shots.goal, ax=axs[0], cmap="bwr", 
                            plot_range="ozone", binsize=10, levels=50, statistic="mean")
plt.colorbar(contour_img, ax=axs[0], orientation="horizontal")
rink.heatmap(shots.x, shots.y, values=shots.goal, ax=axs[1], cmap="magma",
             plot_xlim=(25, 89), statistic="mean", vmax=0.2, binsize=3)
rink.hexbin(shots.x, shots.y, values=shots.goal, ax=axs[2], binsize=(8, 12), plot_range="ozone", zorder=25, alpha=0.85)

Inspiration

This project was partly inspired by mplsoccer.

Hopefully, it can lower a barrier for someone looking to get involved in hockey analytics.

Contact

You can find me on twitter @the_bucketless or email me at [email protected] if you'd like to get in touch.

Open-source demos hosted on Dash Gallery

Dash Sample Apps This repository hosts the code for over 100 open-source Dash apps written in Python or R. They can serve as a starting point for your

Plotly 2.7k Jan 07, 2023
Standardized plots and visualizations in Python

Standardized plots and visualizations in Python pltviz is a Python package for standardized visualization. Routine and novel plotting approaches are f

Andrew Tavis McAllister 0 Jul 09, 2022
A tool to plot and execute Rossmos's Formula, that helps to catch serial criminals using mathematics

Rossmo Plotter A tool to plot and execute Rossmos's Formula using python, that helps to catch serial criminals using mathematics Author: Amlan Saha Ku

Amlan Saha Kundu 3 Aug 29, 2022
AB-test-analyzer - Python class to perform AB test analysis

AB-test-analyzer Python class to perform AB test analysis Overview This repo con

13 Jul 16, 2022
Data visualization electromagnetic spectrum

Datenvisualisierung-Elektromagnetischen-Spektrum Anhand des Moduls matplotlib sollen die Daten des elektromagnetischen Spektrums dargestellt werden. D

Pulsar 1 Sep 01, 2022
It's an application to calculate I from v and r. It can also plot a graph between V vs I.

Ohm-s-Law-Visualizer It's an application to calculate I from v and r using Ohm's Law. It can also plot a graph between V vs I. Story I'm doing my Unde

Sihab Sahariar 1 Nov 20, 2021
A site that displays up to date COVID-19 stats, powered by fastpages.

https://covid19dashboards.com This project was built with fastpages Background This project showcases how you can use fastpages to create a static das

GitHub 1.6k Jan 07, 2023
Fastest Gephi's ForceAtlas2 graph layout algorithm implemented for Python and NetworkX

ForceAtlas2 for Python A port of Gephi's Force Atlas 2 layout algorithm to Python 2 and Python 3 (with a wrapper for NetworkX and igraph). This is the

Bhargav Chippada 227 Jan 05, 2023
Jupyter Notebook extension leveraging pandas DataFrames by integrating DataTables and ChartJS.

Jupyter DataTables Jupyter Notebook extension to leverage pandas DataFrames by integrating DataTables JS. About Data scientists and in fact many devel

Marek Čermák 142 Dec 28, 2022
Movies-chart - A CLI app gets the top 250 movies of all time from imdb.com and the top 100 movies from rottentomatoes.com

movies-chart This CLI app gets the top 250 movies of all time from imdb.com and

3 Feb 17, 2022
Rubrix is a free and open-source tool for exploring and iterating on data for artificial intelligence projects.

Open-source tool for exploring, labeling, and monitoring data for AI projects

Recognai 1.5k Jan 07, 2023
Visualizations of linear algebra algorithms for people who want a deep understanding

Visualising algorithms on symmetric matrices Examples QR algorithm and LR algorithm Here, we have a GIF animation of an interactive visualisation of t

ogogmad 3 May 05, 2022
Wikipedia WordCloud App generate Wikipedia word cloud art created using python's streamlit, matplotlib, wikipedia and wordcloud packages

Wikipedia WordCloud App Wikipedia WordCloud App generate Wikipedia word cloud art created using python's streamlit, matplotlib, wikipedia and wordclou

Siva Prakash 5 Jan 02, 2022
Generate the report for OCULTest.

Sample report generated in this function Usage example from utils.gen_report import generate_report if __name__ == '__main__': # def generate_rep

Philip Guo 1 Mar 10, 2022
plotly scatterplots which show molecule images on hover!

molplotly Plotly scatterplots which show molecule images on hovering over the datapoints! Required packages: pandas rdkit jupyter_dash ➡️ See example.

150 Dec 28, 2022
Typical: Fast, simple, & correct data-validation using Python 3 typing.

typical: Python's Typing Toolkit Introduction Typical is a library devoted to runtime analysis, inference, validation, and enforcement of Python types

Sean 171 Jan 02, 2023
matplotlib: plotting with Python

Matplotlib is a comprehensive library for creating static, animated, and interactive visualizations in Python. Check out our home page for more inform

Matplotlib Developers 16.7k Jan 08, 2023
Epagneul is a tool to visualize and investigate windows event logs

epagneul Epagneul is a tool to visualize and investigate windows event logs. Dep

jurelou 190 Dec 13, 2022
Generate visualizations of GitHub user and repository statistics using GitHub Actions.

GitHub Stats Visualization Generate visualizations of GitHub user and repository statistics using GitHub Actions. This project is currently a work-in-

Aditya Thakekar 1 Jan 11, 2022
This is a small repository for me to implement my simply Data Visualisation skills through Python.

Data Visualisations This is a small repository for me to implement my simply Data Visualisation skills through Python. Steam Population Chart from 10/

9 Dec 31, 2021