library(dplyr)
library(plotly)
library(ggplot2)
library(RColorBrewer)
data <- read.csv("regularStats.csv")
data2023 <- data %>%
filter(YEAR == 2023)
plot <- data2023 %>%
plot_ly(
x = ~TEAM,
y = ~PTS.G,
type = "scatter",
mode = "markers",
text = ~paste("Player:", NAME, "<br>PTS/G:", PTS.G),
color = ~TEAM,
hoverinfo = "text"
) %>%
layout(
title = "Points per Game by Team (Players > 1500 MINS)",
xaxis = list(title = "Team"),
yaxis = list(title = "Points Per Game") # leveled y-axis
)
plot
In the plot above we are graphing player points per game by the team that they are on for players with greater than 1500 minutes played as you need that many to be award eligible and I believe that is a good measure on if your statistics are significant to a team. Hovering over the points reveals which player the point represents and how many points per game they produced. My main issue with this plot was figuring out what to filter the data by so that the data was not overwhelming or cluttered. I ended up deciding on just focusing the data on one year to make things easier on myself and for the viewers.
players <- c("Kobe Bryant", "LeBron James", "Steph Curry", "Kevin Durant", "Carmelo Anthony", "Tim Duncan", "Shaquille O'Neal", "Kevin Garnett", "Dirk Nowitzki", "Dwyane Wade", "Chris Paul", "James Harden", "Allen Iverson")
careers <- data %>%
filter(NAME %in% players)
careers$hover <- paste(
"Player:", careers$NAME,
"<br>Year:", careers$YEAR,
"<br>PPG:", careers$PTS.G,
"<br>Minutes:", careers$MINS
)
colorlist = colorRampPalette(brewer.pal(12, "Set3"))(length(players))
names(colorlist) <- players
colorlist
## Kobe Bryant LeBron James Steph Curry Kevin Durant
## "#8DD3C7" "#F5FBB4" "#C8C5D3" "#EB8E8B"
## Carmelo Anthony Tim Duncan Shaquille O'Neal Kevin Garnett
## "#A9A0B2" "#C8B291" "#D8C965" "#D1D69C"
## Dirk Nowitzki Dwyane Wade Chris Paul James Harden
## "#F0D1E1" "#D1C2D2" "#BE91BE" "#D0EBBD"
## Allen Iverson
## "#FFED6F"
p_anim <- careers %>%
plot_ly(
x = ~PTS.G,
y = ~MINS,
color = ~NAME,
frame = ~YEAR,
text = ~hover,
hoverinfo = "text",
type = "scatter",
mode = "markers",
colors = colorlist
) %>%
add_text(
x = 12,
y = max(careers$MINS, na.rm = TRUE)-50,
text = ~YEAR,
frame = ~YEAR,
textfont = list(size = 40, color = "grey"),
showlegend = FALSE,
hoverinfo = "none"
) %>%
layout(
title = "NBA Player Careers: Minutes vs Points (Animated by Year)",
xaxis = list(title = "Points Per Game"),
yaxis = list(title = "Minutes Played")) %>%
animation_opts(
frame = 2000,
transition = 1500,
easing = "linear") %>%
animation_slider(hide = TRUE)
p_anim
This graph plots some notable NBA players over the last 20ish years and their points per game and total season minutes. You can see trends through the animation such as when a player is close to retirement it is likely that their points per game drop significantly, along with their minutes, showing the signs of aging on the game of basketball. Usually after this takes effect the player retires within a season or two. You can also see that more minutes usually results in more points per game. This is why many people use regularized stats in the modern NBA to view a player such as per 100 possessions or per 36 minutes. My main issue with this plot was getting every modifier i the right order whether it be the animation_opts or the layout. Having them even one spot out of order was causing me a lot of issues but by looking at code examples online I was able to sort them out properly.