<commit_before>---
title: "Quantifying point overlap for NBA shot chart data"
layout: post
excerpt: Find the most and least similar shot patterns for basketall players.
category: rstats
tags:
  - hoops
  - analytics
  - nbastatr
image:
  feature: featureBallin.png
  credit: 
  creditlink: 
published: true
---

I saw this [article](http://www.espn.com/nba/story/_/id/25867382/trae-young-says-luka-doncic-trade-worked-teams) about similarities and differences between NBA rookies Trae Young and Luka Doncic, and it made me wonder if parts of their game could be summarized and compared using shot chart data. 

Back in 2016 I wrote about using [<NAME>’s](https://onlinelibrary.wiley.com/doi/abs/10.1111/geb.12455) point-proximity metric (_O_) to [measure spatial point overlap](https://luisdva.github.io/rstats/Measuring-point-overlap/). The metric was developed for evolutionary ecology, but I thought I could try it out on XY shooting data for various pairs of players. 

To summarize shot chart data, I went with a grid-cell approach to identify the spots on the courts where each player was taking the most shots. That way I could reuse what I learned when I explored [grid-based richness metrics](https://luisdva.github.io/rstats/richness/) for spatial data using the _sf_ package, together with the code I used recently to [access and plot NBA shot charts](https://luisdva.github.io/rstats/bball-shot-locations/).

All the code is in the gist at the end of the post, and the code should be fully reproducible as long as the relevant packages are installed. 

Below are the main steps in the workflow. Instead of copying and pasting extensively, I rolled some of the steps into functions that take lists and iterate over data frames of shot chart data for many players. The functions are pretty rough, and it was my first writing functions without for loops. I’m mostly comparing data from the ongoing season for point and shooting guards, but I added some of my favorite players from past seasons just for fun. 

All shot chart data corresponds to the 2019 season, except for the three Knicks legends (1999 season). 
 
|label |namePlayer       |
|:-----|:----------------|
|AH    |<NAME>    |
|BS    |<NAME>      |
|DR    |<NAME> |
|JT    |<NAME>     |
|JB    |<NAME>     |
|JE    |<NAME>      |
|KI    |<NAME>     |
|LJ    |<NAME>    |
|LS    |<NAME> |
|LBJ   |<NAME>     |
|LD    |<NAME>      |
|TY    |<NAME>       |

## Workflow:

- Download shot chart data and subset by player names.  
- Count the number of shots per cell on a custom grid overlaid on the court.  
- Identify the top _n_ highest-density grid cells and get their centroids.  
  
<figure>
    <a href="/images/court_grid.png"><img src="/images/court_grid.png"></a>
        <figcaption>court plot courtesy of ballR</figcaption>
</figure>
<br><br>  
- Once we have a court as a simple feature object, we can overlap a grid on in and get the shot richness. Here's an example of the intermediate steps involved, shown for only one of the players. <commit_msg>Update 2019-02-14-nba-overlap.md<commit_after>---
title: "Quantifying point overlap for NBA shot chart data"
layout: post
excerpt: Find the most and least similar shot patterns for basketall players.
category: rstats
tags:
  - hoops
  - analytics
  - nbastatr
image:
  feature: featureBallin.png
  credit: 
  creditlink: 
published: true
---

I saw this [article](http://www.espn.com/nba/story/_/id/25867382/trae-young-says-luka-doncic-trade-worked-teams) about similarities and differences between NBA rookies Trae Young and Luka Doncic, and it made me wonder if parts of their game could be summarized and compared using shot chart data. 

Back in 2016 I wrote about using [Cardillo and Warren’s](https://onlinelibrary.wiley.com/doi/abs/10.1111/geb.12455) point-proximity metric (_O_) to [measure spatial point overlap](https://luisdva.github.io/rstats/Measuring-point-overlap/). The metric was developed for evolutionary ecology, but I thought I could try it out on XY shooting data for various pairs of players. 

To summarize shot chart data, I went with a grid-cell approach to identify the spots on the courts where each player was taking the most shots. That way I could reuse what I learned when I explored [grid-based richness metrics](https://luisdva.github.io/rstats/richness/) for spatial data using the _sf_ package, together with the code I used recently to [access and plot NBA shot charts](https://luisdva.github.io/rstats/bball-shot-locations/).

All the code is in the gist at the end of the post, and the code should be fully reproducible as long as the relevant packages are installed. 

Below are the main steps in the workflow. Instead of copying and pasting extensively, I rolled some of the steps into functions that take lists and iterate over data frames of shot chart data for many players. The functions are pretty rough, and it was my first writing functions using _purrr_ instead of _for_ loops. I’m mostly comparing data from the ongoing season for point and shooting guards, but I added some of my favorite players from past seasons just for fun. 

All shot chart data corresponds to the 2019 season, except for the three Knicks legends (1999 season). 
 
|label |namePlayer       |
|:-----|:----------------|
|AH    |<NAME>    |
|BS    |<NAME>      |
|DR    |<NAME> |
|JT    |<NAME>     |
|JB    |<NAME>     |
|JE    |<NAME>      |
|KI    |<NAME>     |
|LJ    |<NAME>    |
|LS    |<NAME> |
|LBJ   |<NAME>     |
|LD    |<NAME>      |
|TY    |<NAME>       |

## Workflow:

- Download shot chart data and subset by player names.  
- Count the number of shots per cell on a custom grid overlaid on the court.  
- Identify the top _n_ highest-density grid cells and get their centroids.  
  
<figure>
    <a href="/images/court_grid.png"><img src="/images/court_grid.png"></a>
        <figcaption>court plot courtesy of ballR</figcaption>
</figure>
<br><br>  
- Once we have a court as a simple feature object, we can overlap a grid on in and get the shot richness. Here's an example of the intermediate steps involved, shown for only one of the players. 
{'fraction_non_alphanumeric': 0.08945216680294359, 'fraction_numerical': 0.011447260834014717, 'mean_word_length': 3.4383164005805513, 'pattern_counts': {'":': 0, '<': 46, '<?xml version=': 0, '>': 46, 'https://': 8, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7198460', 'n_tokens_mistral': 1864, 'n_tokens_neox': 1706, 'n_words': 820}