Generating a d3.js-based NBA Shot Chart

Jed Ong
2 min readJan 13, 2021

As I started building out otherbasketballstats over the past few weeks, a graphic I really wanted to include was the shot chart. The shot chart has always been one of my favourite basketball-related visuals — I think it provides a lot of digestible information about a player’s tendencies and performance that otherwise wouldn’t be obvious through a table-based data format.

I have been using Python (Django-based) and JavaScript to build out otherbasketballstats, and since I’m not a web developer by trade, I had a tough time figuring out exactly how to go about building a dynamic shot chart. After a lot of searching and trial-and-error, I finally got a solid lead through this stackoverflow question.

Anyway, given the amount of work I did, I thought it would be useful to write a quick summary to remind myself in the future as well as hopefully to help someone out!

Here’s a screenshot of what it looks like on otherbasketballstats:

Check out Kawhi’s mid-range shots!

And here’s what the HTML/JS code looks like:

A few quick notes:

  • As mentioned, I’m using Python & Django as my backend so I’m dynamically passing in my shots data through {{shots_df_data|safe}}. The data being passed is a list that looks like this:

The 1st element of each list item is the shot description, the 2nd and 3rd elements are the shot coordinates, and the 4th element is a binary flag that indicates whether or not a shot went in. Depending on how you are building your site, the data being passed can definitely be modified — just make sure to modify the code above accordingly.

  • Line 20, which is the courtBGUrl variable, refers to a static image that serves as the background of the basketball court itself. This is the base image that the shots data will be generated on.
  • The make/miss colours of the shot markers can be modified through the code in lines 48–55.
  • Finally, you’ll need to include the d3.js library to get it all up and running.

I can’t take credit for developing the code but was really happy to be able to adapt the code for how I was building otherbasketballstats. Hopefully this helps you as well!

--

--