Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
177 lines (130 sloc) 6.05 KB

NHL shot locations in 3D

Showing NHL shot locations in a more appealing and revealing way, using calculations that automatically convert the data from the NHL API to the 3D perspective (see dashboard:!/vizhome/ShotsIn3D/Dashboard2)


image alt text

Let’s start with that we know


The data from the NHL API that contains shot locations uses the NHL rink dimensions (~ 200 ft by 85 ft) with centre ice being 0,0. This creates the use of negative values (dimensioning the rink -100 to100 and -42.5 to 42.5), but more to come on that later.


The underlying reference image I use to project the data onto measures

image alt text

Black = rink dimensions along length

Purple = image dimensions along length

Green = image dimensions along width


To keep things manageable, and because they require a different approach, I worked on the X’s (length of the ice) and Y’s (width of the ice) separately.

I started by putting the numbers we know and can measure into a spreadsheet, with separate tabs for the X and Y. Here is the one for X:

Source Image (CM) Coord% Image% CalcImg%
200 20.5 100 100.0 100.3
189 20.1 94.5 98.0 97.7
125 17.2 62.5 83.9 83.6
100 15.4 50 75.1 75.6
75 13.2 37.5 64.4 64.5
11 3 5.5 14.6 13.7
0 0 0 0.0 0.0

The source were just X values for known values on the ice (based on rink dimensions): red lines at 11, 100 and 189 ft, blue lines at 75 and 125 ft. I measured those on the Image as well (as we need the "relative spread" the unit of measurement is not relevant, I use cm) and filled out the Image (CM) column.

Assuming the bottom is 0 ft and the top is 200 ft, I can easily calculate the % of total length for both the normal rink dimension (Coord%) and the image (Image%). When I plot this data in Tableau, I can create a function using Trend line which can then be used to calculate the Image% value for any rink dimension value (Coord%):

image alt text

Formula in Excel: =0.0000999252 * C9^3 + -0.025 * C9^2 + 2.5 * C9 + 0 (C9 holds the rink dimension % value)

In Tableau I can create the rink dimension % value like this: ([X]+100)/2

And then the Image% value uses the formulae like this:

(0.0001 * ([Coord%]^3)) + (-0.025 * ([Coord%]^2)) + (2.5 * ([Coord%])) + 0

If I now take shots from the 2016 season for example, using this formula in the calculated field I get this:

image alt text

What this is showing? That at 50% of Coord% down the length of the ice (shot X = 0) I am at 75% of the image height (CalcImg%).

To visually check if this is working ciorrectly I plotted the calculated Imag % values and the shot Y values and added the 3D image in the background. I also colour coded the original shot X values per "zone":

image alt text

This looks good. Now let’s look at the Y values. This is a bit of a different approach, as we want to reduce the width more as we move up on the ice. And where the X value was not influenced by the Y value, the Y value is influenced to the X value.

To be precise, in the bottom of the image we want Y to be 100% of the Y value, but at the other end of the ice (at the top of the image) we want it to be reduced by a certain percentage. This is what we know for Y:

XImage% Xsource XCoord% Yimage(CM) Ycoord%
100 100 100 13.4 38.3
75.12195122 0 50 19.5 55.7
0 -100 0 35 100.0

So over 200 ft of actual length, the width needs to be reduced from 0% at the bottom of the image to 61.7% at the top of the image. In other words the width is 100% of the width Y at the bottom and 38.3% of the width Y at the top. Note we need to use the reference image XImage%. We can plot that again in Tableau:

image alt text

We can draw a pretty well fitting line through here (R-squared = 0.998692) using -0.610731 * XImage% + 100.317 and after some juggling and realizing that my ruler-on-the-screen measurements may not have been exactly accurate, I adjusted the formula to (-0.72 * [XImage%] + 105).

That’s an awful long story, but what do we have now?

With the provide formulae, any NHL API shot location can be shown in a more visually appealing 3D format in Tableau:

  • Load the data with the shot locations into Tableau

  • Create a calculated field called XCoord% to convert the X value to a percentage along the length of the ice, with: ([X]+100)/2

  • Create a calculated field called XCalcImg% to convert the CoordX% value to projected value to match the 3D image, with: (0.0001 * ([Coord%]^3)) + (-0.025 * ([Coord%]^2)) + (2.5 * ([Coord%])) + 0

  • Create a calculated field called Ycalc to scale the Y value to the image, with: (-0.72 * [CalcImg%] + 105)/100 * [Y]

  • Show the shot locations in 3D:

image alt text

Note that not everybody wants to use this specific image. For using other images in 3D the formulae would have to be recalculated, but other than that everything will work the same as described above.