Minnesota team notes:
Starting unit lacks a corner spacer, Anthony Edwards is only player in starting five to take more than 30 corner 3 attempts this year but he only took 10% of his three attempts from the corners.
Taurean Prince is the only corner 3pt threat in rotation.
Mike Conley and Karl Anthony Towns have had “hot” shooting seasons, both with a true shooting 10 pct points greater than their shot quality avg.
Anthony Edwards lead the team in above the break, mid-range, paint (non-restricted area), and restricted area shot attempts.
In regular season:
In play-in:
Heatmap Notes:
Colored areas represent areas of high shot frequency, the brighter the area = higher frequency.
Zones: Restricted Area, In the Paint(non-Restricted Area), Mid-Range, Above the Break 3, Left Corner 3, and Right Corner 3.
Left and right determined from the perspective of half-court facing the hoop.
Frequency dependent upon player’s total shot attempts (player’s with low shot attempts will have “noisier” shot charts).
library(tidyverse)
library(nbastatR)
library(plyr)
library(scales)
library(dplyr)
library(paletteer)
library(cowplot)
library(grid)
library(gridExtra)
library(png)
library(RCurl)
library(crosstalk)
library(plotly)
library(reactable)
library(reactablefmtr)
library(rpubs)
library(jsonlite)
library(janitor)
library(purrr)
Sys.setenv("VROOM_CONNECTION_SIZE" = 131072 * 2)
circle_points = function(center = c(0, 0), radius = 1, npoints = 360) {
angles = seq(0, 2 * pi, length.out = npoints)
return(data_frame(x = center[1] + radius * cos(angles),
y = center[2] + radius * sin(angles)))
}
width = 50
height = 94 / 2
key_height = 19
inner_key_width = 12
outer_key_width = 16
backboard_width = 6
backboard_offset = 4
neck_length = 0.5
hoop_radius = 0.75
hoop_center_y = backboard_offset + neck_length + hoop_radius
three_point_radius = 23.75
three_point_side_radius = 22
three_point_side_height = 14
court_themes = list(
light = list(
court = 'floralwhite',
lines = '#999999',
text = '#222222',
made = '#00bfc4',
missed = '#f8766d',
hex_border_size = 1,
hex_border_color = "#000000"
),
dark = list(
court = '#000004',
lines = '#999999',
text = '#f0f0f0',
made = '#00bfc4',
missed = '#f8766d',
hex_border_size = 0,
hex_border_color = "#000000"
)
)
plot_court = function(court_theme = court_themes$light, use_short_three = FALSE) {
if (use_short_three) {
three_point_radius = 22
three_point_side_height = 0
}
court_points = data_frame(
x = c(width / 2, width / 2, -width / 2, -width / 2, width / 2),
y = c(height, 0, 0, height, height),
desc = "perimeter"
)
court_points = bind_rows(court_points , data_frame(
x = c(outer_key_width / 2, outer_key_width / 2, -outer_key_width / 2, -outer_key_width / 2),
y = c(0, key_height, key_height, 0),
desc = "outer_key"
))
court_points = bind_rows(court_points , data_frame(
x = c(-backboard_width / 2, backboard_width / 2),
y = c(backboard_offset, backboard_offset),
desc = "backboard"
))
court_points = bind_rows(court_points , data_frame(
x = c(0, 0), y = c(backboard_offset, backboard_offset + neck_length), desc = "neck"
))
foul_circle = circle_points(center = c(0, key_height), radius = inner_key_width / 2)
foul_circle_top = filter(foul_circle, y > key_height) %>%
mutate(desc = "foul_circle_top")
foul_circle_bottom = filter(foul_circle, y < key_height) %>%
mutate(
angle = atan((y - key_height) / x) * 180 / pi,
angle_group = floor((angle - 5.625) / 11.25),
desc = paste0("foul_circle_bottom_", angle_group)
) %>%
filter(angle_group %% 2 == 0) %>%
select(x, y, desc)
hoop = circle_points(center = c(0, hoop_center_y), radius = hoop_radius) %>%
mutate(desc = "hoop")
restricted = circle_points(center = c(0, hoop_center_y), radius = 4) %>%
filter(y >= hoop_center_y) %>%
mutate(desc = "restricted")
three_point_circle = circle_points(center = c(0, hoop_center_y), radius = three_point_radius) %>%
filter(y >= three_point_side_height, y >= hoop_center_y)
three_point_line = data_frame(
x = c(three_point_side_radius, three_point_side_radius, three_point_circle$x, -three_point_side_radius, -three_point_side_radius),
y = c(0, three_point_side_height, three_point_circle$y, three_point_side_height, 0),
desc = "three_point_line"
)
court_points = bind_rows(
court_points,
foul_circle_top,
foul_circle_bottom,
hoop,
restricted,
three_point_line
)
court_points <- court_points
ggplot() +
geom_path(
data = court_points,
aes(x = x, y = y, group = desc),
color = court_theme$lines
) +
coord_fixed(ylim = c(0, 45), xlim = c(-25, 25)) +
theme_minimal(base_size = 22) +
theme(
text = element_text(color = court_theme$text),
plot.background = element_rect(fill = 'floralwhite', color = 'floralwhite'),
panel.background = element_rect(fill = court_theme$court, color = court_theme$court),
panel.grid = element_blank(),
panel.border = element_blank(),
axis.text = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank(),
legend.background = element_rect(fill = court_theme$court, color = court_theme$court),
legend.position = "bottom",
legend.key = element_blank(),
legend.text = element_text(size = rel(1.0))
)
}
pc <- plot_court(court_themes$light)
active_player_photos <- nba_players() %>%
filter( isActive == "TRUE") %>%
select(namePlayer,
idPlayer,
urlPlayerHeadshot,
urlPlayerActionPhoto)
#this chunk needs to be manually adjusted at pbp_url_4 and filter for pbp_df
pbp_url_4 <- "https://api.pbpstats.com/get-totals/nba?Season=2022-23&SeasonType=Regular%2BSeason&TeamId=1610612750&Type=Player"
pbp_4 <- read_json(pbp_url_4)
player_df <- pbp_4[["multi_row_table_data"]] %>%
bind_rows() %>%
clean_names() %>%
mutate_at(vars(shot_quality_avg,
ts_pct,
usage), funs(round(.,4))) %>%
mutate(shot_quality_avg = shot_quality_avg * 100,
ts_pct = ts_pct *100,
assisted2s_pct = assisted2s_pct * 100,
assisted3s_pct = assisted3s_pct * 100,
at_rim_frequency = at_rim_frequency * 100,
at_rim_pct_assisted = at_rim_pct_assisted * 100,
short_mid_range_frequency = short_mid_range_frequency * 100,
short_mid_range_pct_assisted = short_mid_range_pct_assisted * 100,
long_mid_range_frequency = long_mid_range_frequency * 100,
long_mid_range_pct_assisted = long_mid_range_pct_assisted * 100,
corner3frequency = corner3frequency * 100,
corner3pct_assisted = corner3pct_assisted * 100,
arc3frequency = arc3frequency * 100,
arc3pct_assisted = arc3pct_assisted *100,
at_rim_fg3a_frequency = at_rim_fg3a_frequency * 100) %>%
mutate( 'Corner 3 ppa' = corner3accuracy * 3,
'Arc 3 ppa' = arc3accuracy * 3)
pbp_url_5 <- "https://api.pbpstats.com/get-totals/nba?Season=2022-23&SeasonType=Regular%2BSeason&StartType=All&Type=Team"
pbp_5 <- read_json(pbp_url_5)
pbp_df <- pbp_5[["multi_row_table_data"]] %>%
bind_rows() %>%
clean_names() %>%
filter(name == "MIN") %>%
mutate( 'Corner 3 ppa' = corner3accuracy * 3,
'Arc 3 ppa' = arc3accuracy * 3)
player_df %>%
mutate('Corner 3 diff' = player_df$'Corner 3 ppa' - pbp_df$'Corner 3 ppa',
'Arc 3 diff' = player_df$'Arc 3 ppa' - pbp_df$'Arc 3 ppa') %>%
select(name,
'Corner 3 diff',
'Arc 3 diff') %>%
mutate_at(vars('Corner 3 diff', 'Arc 3 diff'), funs(round(.,4))) %>%
reactable( theme = espn(),
pagination = FALSE) %>%
add_title("Points per Attempt difference between player and team avg")
player_df_1 <- player_df %>%
filter(name == player_1)
player_1_shots <- team_df %>%
filter( namePlayer == player_1) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_1_shots$x <- player_1_shots$x * -1
shotData_player_1 <- player_1_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_1 <- shotData_player_1 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_1 <- shotData_player_1 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_1 <- shotData_player_1 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_1 <- shotData_player_1 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_1 <- shotData_player_1 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_1 <- shotData_player_1 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_1_heat <- plot_court() +
geom_density_2d_filled(player_1_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_1 <- shotData_player_1 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_1 <- rasterGrob(readPNG(getURLContent(headshot_player_1)),
width = unit(.15, "npc"))
player_1_heat +
geom_text(data = ra_player_1 , x = 0 , y = 7, label = ra_player_1$'points per attempt') +
geom_text(data = ra_player_1 , x = 0 , y = 5, label = ra_player_1$'shots') +
geom_text(data = ip_player_1, x = 0 , y = 15, label = ip_player_1$'points per attempt') +
geom_text(data = ip_player_1, x = 0 , y = 13, label = ip_player_1$'shots') +
geom_text(data = abb3_player_1, x = 0 , y = 33, label = abb3_player_1$'points per attempt') +
geom_text(data = abb3_player_1, x = 0 , y = 31, label = abb3_player_1$'shots') +
geom_text(data = mr_player_1, x = 0 , y = 24, label = mr_player_1$'points per attempt') +
geom_text(data = mr_player_1, x = 0 , y = 22, label = mr_player_1$'shots') +
geom_text(data = rc3_player_1, x = -22, y = 7, label = rc3_player_1$'points per attempt') +
geom_text(data = rc3_player_1, x = -22, y = 5, label = rc3_player_1$'shots') +
geom_text(data = lc3_player_1, x = 22, y = 7, label = lc3_player_1$'points per attempt') +
geom_text(data = lc3_player_1, x = 22, y = 5, label = lc3_player_1$'shots') +
geom_text(data = player_df_1, x = -8, y = 46, label = player_df_1$shot_quality_avg) +
geom_text(data = player_df_1, x = -8, y = 44, label = player_df_1$ts_pct) +
geom_text(data = player_df_1, x = -8, y = 42, label = player_df_1$usage) +
geom_text(data = player_df_1, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_1, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_1, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_1, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_1, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_1), newpage=FALSE)
## NULL
player_df_1 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_2 <- player_df %>%
filter(name == player_2)
player_2_shots <- team_df %>%
filter( namePlayer == player_2) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_2_shots$x <- player_2_shots$x * -1
shotData_player_2 <- player_2_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_2 <- shotData_player_2 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_2 <- shotData_player_2 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_2 <- shotData_player_2 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_2 <- shotData_player_2 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_2 <- shotData_player_2 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_2 <- shotData_player_2 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_2_heat <- plot_court() +
geom_density_2d_filled(player_2_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_2 <- shotData_player_2 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_2 <- rasterGrob(readPNG(getURLContent(headshot_player_2)),
width = unit(.15, "npc"))
player_2_heat +
geom_text(data = ra_player_2 , x = 0 , y = 7, label = ra_player_2$'points per attempt') +
geom_text(data = ra_player_2 , x = 0 , y = 5, label = ra_player_2$'shots') +
geom_text(data = ip_player_2, x = 0 , y = 15, label = ip_player_2$'points per attempt') +
geom_text(data = ip_player_2, x = 0 , y = 13, label = ip_player_2$'shots') +
geom_text(data = abb3_player_2, x = 0 , y = 33, label = abb3_player_2$'points per attempt') +
geom_text(data = abb3_player_2, x = 0 , y = 31, label = abb3_player_2$'shots') +
geom_text(data = mr_player_2, x = 0 , y = 24, label = mr_player_2$'points per attempt') +
geom_text(data = mr_player_2, x = 0 , y = 22, label = mr_player_2$'shots') +
geom_text(data = rc3_player_2, x = -22, y = 7, label = rc3_player_2$'points per attempt') +
geom_text(data = rc3_player_2, x = -22, y = 5, label = rc3_player_2$'shots') +
geom_text(data = lc3_player_2, x = 22, y = 7, label = lc3_player_2$'points per attempt') +
geom_text(data = lc3_player_2, x = 22, y = 5, label = lc3_player_2$'shots') +
geom_text(data = player_df_2, x = -8, y = 46, label = player_df_2$shot_quality_avg) +
geom_text(data = player_df_2, x = -8, y = 44, label = player_df_2$ts_pct) +
geom_text(data = player_df_2, x = -8, y = 42, label = player_df_2$usage) +
geom_text(data = player_df_2, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_2, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_2, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_2, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_2, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_2), newpage=FALSE)
## NULL
player_df_2 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_3 <- player_df %>%
filter(name == player_3)
player_3_shots <- team_df %>%
filter( namePlayer == player_3) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_3_shots$x <- player_3_shots$x * -1
shotData_player_3 <- player_3_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_3 <- shotData_player_3 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_3 <- shotData_player_3 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_3 <- shotData_player_3 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_3 <- shotData_player_3 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_3 <- shotData_player_3 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_3 <- shotData_player_3 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_3_heat <- plot_court() +
geom_density_2d_filled(player_3_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_3 <- shotData_player_3 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_3 <- rasterGrob(readPNG(getURLContent(headshot_player_3)),
width = unit(.15, "npc"))
player_3_heat +
geom_text(data = ra_player_3 , x = 0 , y = 7, label = ra_player_3$'points per attempt') +
geom_text(data = ra_player_3 , x = 0 , y = 5, label = ra_player_3$'shots') +
geom_text(data = ip_player_3, x = 0 , y = 15, label = ip_player_3$'points per attempt') +
geom_text(data = ip_player_3, x = 0 , y = 13, label = ip_player_3$'shots') +
geom_text(data = abb3_player_3, x = 0 , y = 33, label = abb3_player_3$'points per attempt') +
geom_text(data = abb3_player_3, x = 0 , y = 31, label = abb3_player_3$'shots') +
geom_text(data = mr_player_3, x = 0 , y = 24, label = mr_player_3$'points per attempt') +
geom_text(data = mr_player_3, x = 0 , y = 22, label = mr_player_3$'shots') +
geom_text(data = rc3_player_3, x = -22, y = 7, label = rc3_player_3$'points per attempt') +
geom_text(data = rc3_player_3, x = -22, y = 5, label = rc3_player_3$'shots') +
geom_text(data = lc3_player_3, x = 22, y = 7, label = lc3_player_3$'points per attempt') +
geom_text(data = lc3_player_3, x = 22, y = 5, label = lc3_player_3$'shots') +
geom_text(data = player_df_3, x = -8, y = 46, label = player_df_3$shot_quality_avg) +
geom_text(data = player_df_3, x = -8, y = 44, label = player_df_3$ts_pct) +
geom_text(data = player_df_3, x = -8, y = 42, label = player_df_3$usage) +
geom_text(data = player_df_3, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_3, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_3, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_3, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_3, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_3), newpage=FALSE)
## NULL
player_df_3 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_4 <- player_df %>%
filter(name == player_4)
player_4_shots <- team_df %>%
filter( namePlayer == player_4) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_4_shots$x <- player_4_shots$x * -1
shotData_player_4 <- player_4_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_4 <- shotData_player_4 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_4 <- shotData_player_4 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_4 <- shotData_player_4 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_4 <- shotData_player_4 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_4 <- shotData_player_4 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_4 <- shotData_player_4 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_4_heat <- plot_court() +
geom_density_2d_filled(player_4_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_4 <- shotData_player_4 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_4 <- rasterGrob(readPNG(getURLContent(headshot_player_4)),
width = unit(.15, "npc"))
player_4_heat +
geom_text(data = ra_player_4 , x = 0 , y = 7, label = ra_player_4$'points per attempt') +
geom_text(data = ra_player_4 , x = 0 , y = 5, label = ra_player_4$'shots') +
geom_text(data = ip_player_4, x = 0 , y = 15, label = ip_player_4$'points per attempt') +
geom_text(data = ip_player_4, x = 0 , y = 13, label = ip_player_4$'shots') +
geom_text(data = abb3_player_4, x = 0 , y = 33, label = abb3_player_4$'points per attempt') +
geom_text(data = abb3_player_4, x = 0 , y = 31, label = abb3_player_4$'shots') +
geom_text(data = mr_player_4, x = 0 , y = 24, label = mr_player_4$'points per attempt') +
geom_text(data = mr_player_4, x = 0 , y = 22, label = mr_player_4$'shots') +
geom_text(data = rc3_player_4, x = -22, y = 7, label = rc3_player_4$'points per attempt') +
geom_text(data = rc3_player_4, x = -22, y = 5, label = rc3_player_4$'shots') +
geom_text(data = lc3_player_4, x = 22, y = 7, label = lc3_player_4$'points per attempt') +
geom_text(data = lc3_player_4, x = 22, y = 5, label = lc3_player_4$'shots') +
geom_text(data = player_df_4, x = -8, y = 46, label = player_df_4$shot_quality_avg) +
geom_text(data = player_df_4, x = -8, y = 44, label = player_df_4$ts_pct) +
geom_text(data = player_df_4, x = -8, y = 42, label = player_df_4$usage) +
geom_text(data = player_df_4, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_4, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_4, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_4, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_4, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_4), newpage=FALSE)
## NULL
player_df_4 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_5 <- player_df %>%
filter(name == player_5)
player_5_shots <- team_df %>%
filter( namePlayer == player_5) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_5_shots$x <- player_5_shots$x * -1
shotData_player_5 <- player_5_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_5 <- shotData_player_5 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_5 <- shotData_player_5 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_5 <- shotData_player_5 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_5 <- shotData_player_5 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_5 <- shotData_player_5 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_5 <- shotData_player_5 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_5_heat <- plot_court() +
geom_density_2d_filled(player_5_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_5 <- shotData_player_5 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_5 <- rasterGrob(readPNG(getURLContent(headshot_player_5)),
width = unit(.15, "npc"))
player_5_heat +
geom_text(data = ra_player_5 , x = 0 , y = 7, label = ra_player_5$'points per attempt') +
geom_text(data = ra_player_5 , x = 0 , y = 5, label = ra_player_5$'shots') +
geom_text(data = ip_player_5, x = 0 , y = 15, label = ip_player_5$'points per attempt') +
geom_text(data = ip_player_5, x = 0 , y = 13, label = ip_player_5$'shots') +
geom_text(data = abb3_player_5, x = 0 , y = 33, label = abb3_player_5$'points per attempt') +
geom_text(data = abb3_player_5, x = 0 , y = 31, label = abb3_player_5$'shots') +
geom_text(data = mr_player_5, x = 0 , y = 24, label = mr_player_5$'points per attempt') +
geom_text(data = mr_player_5, x = 0 , y = 22, label = mr_player_5$'shots') +
geom_text(data = rc3_player_5, x = -22, y = 7, label = rc3_player_5$'points per attempt') +
geom_text(data = rc3_player_5, x = -22, y = 5, label = rc3_player_5$'shots') +
geom_text(data = lc3_player_5, x = 22, y = 7, label = lc3_player_5$'points per attempt') +
geom_text(data = lc3_player_5, x = 22, y = 5, label = lc3_player_5$'shots') +
geom_text(data = player_df_5, x = -8, y = 46, label = player_df_5$shot_quality_avg) +
geom_text(data = player_df_5, x = -8, y = 44, label = player_df_5$ts_pct) +
geom_text(data = player_df_5, x = -8, y = 42, label = player_df_5$usage) +
geom_text(data = player_df_5, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_5, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_5, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_5, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_5, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_5), newpage=FALSE)
player_df_5 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_6 <- player_df %>%
filter(name == player_6)
player_6_shots <- team_df %>%
filter( namePlayer == player_6) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_6_shots$x <- player_6_shots$x * -1
shotData_player_6 <- player_6_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_6 <- shotData_player_6 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_6 <- shotData_player_6 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_6 <- shotData_player_6 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_6 <- shotData_player_6 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_6 <- shotData_player_6 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_6 <- shotData_player_6 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_6_heat <- plot_court() +
geom_density_2d_filled(player_6_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_6 <- shotData_player_6 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_6 <- rasterGrob(readPNG(getURLContent(headshot_player_6)),
width = unit(.15, "npc"))
player_6_heat +
geom_text(data = ra_player_6 , x = 0 , y = 7, label = ra_player_6$'points per attempt') +
geom_text(data = ra_player_6 , x = 0 , y = 5, label = ra_player_6$'shots') +
geom_text(data = ip_player_6, x = 0 , y = 15, label = ip_player_6$'points per attempt') +
geom_text(data = ip_player_6, x = 0 , y = 13, label = ip_player_6$'shots') +
geom_text(data = abb3_player_6, x = 0 , y = 33, label = abb3_player_6$'points per attempt') +
geom_text(data = abb3_player_6, x = 0 , y = 31, label = abb3_player_6$'shots') +
geom_text(data = mr_player_6, x = 0 , y = 24, label = mr_player_6$'points per attempt') +
geom_text(data = mr_player_6, x = 0 , y = 22, label = mr_player_6$'shots') +
geom_text(data = rc3_player_6, x = -22, y = 7, label = rc3_player_6$'points per attempt') +
geom_text(data = rc3_player_6, x = -22, y = 5, label = rc3_player_6$'shots') +
geom_text(data = lc3_player_6, x = 22, y = 7, label = lc3_player_6$'points per attempt') +
geom_text(data = lc3_player_6, x = 22, y = 5, label = lc3_player_6$'shots') +
geom_text(data = player_df_6, x = -8, y = 46, label = player_df_6$shot_quality_avg) +
geom_text(data = player_df_6, x = -8, y = 44, label = player_df_6$ts_pct) +
geom_text(data = player_df_6, x = -8, y = 42, label = player_df_6$usage) +
geom_text(data = player_df_6, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_6, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_6, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_6, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_6, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_6), newpage=FALSE)
## NULL
player_df_6 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_7 <- player_df %>%
filter(name == player_7)
player_7_shots <- team_df %>%
filter( namePlayer == player_7) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_7_shots$x <- player_7_shots$x * -1
shotData_player_7 <- player_7_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_7 <- shotData_player_7 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_7 <- shotData_player_7 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_7 <- shotData_player_7 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_7 <- shotData_player_7 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_7 <- shotData_player_7 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_7 <- shotData_player_7 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_7_heat <- plot_court() +
geom_density_2d_filled(player_7_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_7 <- shotData_player_7 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_7 <- rasterGrob(readPNG(getURLContent(headshot_player_7)),
width = unit(.15, "npc"))
player_7_heat +
geom_text(data = ra_player_7 , x = 0 , y = 7, label = ra_player_7$'points per attempt') +
geom_text(data = ra_player_7 , x = 0 , y = 5, label = ra_player_7$'shots') +
geom_text(data = ip_player_7, x = 0 , y = 15, label = ip_player_7$'points per attempt') +
geom_text(data = ip_player_7, x = 0 , y = 13, label = ip_player_7$'shots') +
geom_text(data = abb3_player_7, x = 0 , y = 33, label = abb3_player_7$'points per attempt') +
geom_text(data = abb3_player_7, x = 0 , y = 31, label = abb3_player_7$'shots') +
geom_text(data = mr_player_7, x = 0 , y = 24, label = mr_player_7$'points per attempt') +
geom_text(data = mr_player_7, x = 0 , y = 22, label = mr_player_7$'shots') +
geom_text(data = rc3_player_7, x = -22, y = 7, label = rc3_player_7$'points per attempt') +
geom_text(data = rc3_player_7, x = -22, y = 5, label = rc3_player_7$'shots') +
geom_text(data = lc3_player_7, x = 22, y = 7, label = lc3_player_7$'points per attempt') +
geom_text(data = lc3_player_7, x = 22, y = 5, label = lc3_player_7$'shots') +
geom_text(data = player_df_7, x = -8, y = 46, label = player_df_7$shot_quality_avg) +
geom_text(data = player_df_7, x = -8, y = 44, label = player_df_7$ts_pct) +
geom_text(data = player_df_7, x = -8, y = 42, label = player_df_7$usage) +
geom_text(data = player_df_7, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_7, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_7, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_7, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_7, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_7), newpage=FALSE)
## NULL
player_df_7 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_8 <- player_df %>%
filter(name == player_8)
player_8_shots <- team_df %>%
filter( namePlayer == player_8) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_8_shots$x <- player_8_shots$x * -1
shotData_player_8 <- player_8_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_8 <- shotData_player_8 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_8 <- shotData_player_8 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_8 <- shotData_player_8 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_8 <- shotData_player_8 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_8 <- shotData_player_8 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_8 <- shotData_player_8 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_8_heat <- plot_court() +
geom_density_2d_filled(player_8_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_8 <- shotData_player_8 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_8 <- rasterGrob(readPNG(getURLContent(headshot_player_8)),
width = unit(.15, "npc"))
player_8_heat +
geom_text(data = ra_player_8 , x = 0 , y = 7, label = ra_player_8$'points per attempt') +
geom_text(data = ra_player_8 , x = 0 , y = 5, label = ra_player_8$'shots') +
geom_text(data = ip_player_8, x = 0 , y = 15, label = ip_player_8$'points per attempt') +
geom_text(data = ip_player_8, x = 0 , y = 13, label = ip_player_8$'shots') +
geom_text(data = abb3_player_8, x = 0 , y = 33, label = abb3_player_8$'points per attempt') +
geom_text(data = abb3_player_8, x = 0 , y = 31, label = abb3_player_8$'shots') +
geom_text(data = mr_player_8, x = 0 , y = 24, label = mr_player_8$'points per attempt') +
geom_text(data = mr_player_8, x = 0 , y = 22, label = mr_player_8$'shots') +
geom_text(data = rc3_player_8, x = -22, y = 7, label = rc3_player_8$'points per attempt') +
geom_text(data = rc3_player_8, x = -22, y = 5, label = rc3_player_8$'shots') +
geom_text(data = lc3_player_8, x = 22, y = 7, label = lc3_player_8$'points per attempt') +
geom_text(data = lc3_player_8, x = 22, y = 5, label = lc3_player_8$'shots') +
geom_text(data = player_df_8, x = -8, y = 46, label = player_df_8$shot_quality_avg) +
geom_text(data = player_df_8, x = -8, y = 44, label = player_df_8$ts_pct) +
geom_text(data = player_df_8, x = -8, y = 42, label = player_df_8$usage) +
geom_text(data = player_df_8, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_8, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_8, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_8, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_8, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_8), newpage=FALSE)
## NULL
player_df_8 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_9 <- player_df %>%
filter(name == player_9)
player_9_shots <- team_df %>%
filter( namePlayer == player_9) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_9_shots$x <- player_9_shots$x * -1
shotData_player_9 <- player_9_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_9 <- shotData_player_9 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_9 <- shotData_player_9 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_9 <- shotData_player_9 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_9 <- shotData_player_9 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_9 <- shotData_player_9 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_9 <- shotData_player_9 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_9_heat <- plot_court() +
geom_density_2d_filled(player_9_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_9 <- shotData_player_9 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_9 <- rasterGrob(readPNG(getURLContent(headshot_player_9)),
width = unit(.15, "npc"))
player_9_heat +
geom_text(data = ra_player_9 , x = 0 , y = 7, label = ra_player_9$'points per attempt') +
geom_text(data = ra_player_9 , x = 0 , y = 5, label = ra_player_9$'shots') +
geom_text(data = ip_player_9, x = 0 , y = 15, label = ip_player_9$'points per attempt') +
geom_text(data = ip_player_9, x = 0 , y = 13, label = ip_player_9$'shots') +
geom_text(data = abb3_player_9, x = 0 , y = 33, label = abb3_player_9$'points per attempt') +
geom_text(data = abb3_player_9, x = 0 , y = 31, label = abb3_player_9$'shots') +
geom_text(data = mr_player_9, x = 0 , y = 24, label = mr_player_9$'points per attempt') +
geom_text(data = mr_player_9, x = 0 , y = 22, label = mr_player_9$'shots') +
geom_text(data = rc3_player_9, x = -22, y = 7, label = rc3_player_9$'points per attempt') +
geom_text(data = rc3_player_9, x = -22, y = 5, label = rc3_player_9$'shots') +
geom_text(data = lc3_player_9, x = 22, y = 7, label = lc3_player_9$'points per attempt') +
geom_text(data = lc3_player_9, x = 22, y = 5, label = lc3_player_9$'shots') +
geom_text(data = player_df_9, x = -8, y = 46, label = player_df_9$shot_quality_avg) +
geom_text(data = player_df_9, x = -8, y = 44, label = player_df_9$ts_pct) +
geom_text(data = player_df_9, x = -8, y = 42, label = player_df_9$usage) +
geom_text(data = player_df_9, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_9, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_9, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_9, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_9, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_9), newpage=FALSE)
## NULL
player_df_9 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_10 <- player_df %>%
filter(name == player_10)
player_10_shots <- team_df %>%
filter( namePlayer == player_10) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_10_shots$x <- player_10_shots$x * -1
shotData_player_10 <- player_10_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_10 <- shotData_player_10 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_10 <- shotData_player_10 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_10 <- shotData_player_10 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_10 <- shotData_player_10 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_10 <- shotData_player_10 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_10 <- shotData_player_10 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_10_heat <- plot_court() +
geom_density_2d_filled(player_10_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_10 <- shotData_player_10 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_10 <- rasterGrob(readPNG(getURLContent(headshot_player_10)),
width = unit(.15, "npc"))
player_10_heat +
geom_text(data = ra_player_10 , x = 0 , y = 7, label = ra_player_10$'points per attempt') +
geom_text(data = ra_player_10 , x = 0 , y = 5, label = ra_player_10$'shots') +
geom_text(data = ip_player_10, x = 0 , y = 15, label = ip_player_10$'points per attempt') +
geom_text(data = ip_player_10, x = 0 , y = 13, label = ip_player_10$'shots') +
geom_text(data = abb3_player_10, x = 0 , y = 33, label = abb3_player_10$'points per attempt') +
geom_text(data = abb3_player_10, x = 0 , y = 31, label = abb3_player_10$'shots') +
geom_text(data = mr_player_10, x = 0 , y = 24, label = mr_player_10$'points per attempt') +
geom_text(data = mr_player_10, x = 0 , y = 22, label = mr_player_10$'shots') +
geom_text(data = rc3_player_10, x = -22, y = 7, label = rc3_player_10$'points per attempt') +
geom_text(data = rc3_player_10, x = -22, y = 5, label = rc3_player_10$'shots') +
geom_text(data = lc3_player_10, x = 22, y = 7, label = lc3_player_10$'points per attempt') +
geom_text(data = lc3_player_10, x = 22, y = 5, label = lc3_player_10$'shots') +
geom_text(data = player_df_10, x = -8, y = 46, label = player_df_10$shot_quality_avg) +
geom_text(data = player_df_10, x = -8, y = 44, label = player_df_10$ts_pct) +
geom_text(data = player_df_10, x = -8, y = 42, label = player_df_10$usage) +
geom_text(data = player_df_10, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_10, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_10, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_10, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_10, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_10), newpage=FALSE)
## NULL
player_df_10 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_11 <- player_df %>%
filter(name == player_11)
player_11_shots <- team_df %>%
filter( namePlayer == player_11) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_11_shots$x <- player_11_shots$x * -1
shotData_player_11 <- player_11_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_11 <- shotData_player_11 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_11 <- shotData_player_11 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_11 <- shotData_player_11 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_11 <- shotData_player_11 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_11 <- shotData_player_11 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_11 <- shotData_player_11 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_11_heat <- plot_court() +
geom_density_2d_filled(player_11_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_11 <- shotData_player_11 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_11 <- rasterGrob(readPNG(getURLContent(headshot_player_11)),
width = unit(.15, "npc"))
player_11_heat +
geom_text(data = ra_player_11 , x = 0 , y = 7, label = ra_player_11$'points per attempt') +
geom_text(data = ra_player_11 , x = 0 , y = 5, label = ra_player_11$'shots') +
geom_text(data = ip_player_11, x = 0 , y = 15, label = ip_player_11$'points per attempt') +
geom_text(data = ip_player_11, x = 0 , y = 13, label = ip_player_11$'shots') +
geom_text(data = abb3_player_11, x = 0 , y = 33, label = abb3_player_11$'points per attempt') +
geom_text(data = abb3_player_11, x = 0 , y = 31, label = abb3_player_11$'shots') +
geom_text(data = mr_player_11, x = 0 , y = 24, label = mr_player_11$'points per attempt') +
geom_text(data = mr_player_11, x = 0 , y = 22, label = mr_player_11$'shots') +
geom_text(data = rc3_player_11, x = -22, y = 7, label = rc3_player_11$'points per attempt') +
geom_text(data = rc3_player_11, x = -22, y = 5, label = rc3_player_11$'shots') +
geom_text(data = lc3_player_11, x = 22, y = 7, label = lc3_player_11$'points per attempt') +
geom_text(data = lc3_player_11, x = 22, y = 5, label = lc3_player_11$'shots') +
geom_text(data = player_df_11, x = -8, y = 46, label = player_df_11$shot_quality_avg) +
geom_text(data = player_df_11, x = -8, y = 44, label = player_df_11$ts_pct) +
geom_text(data = player_df_11, x = -8, y = 42, label = player_df_11$usage) +
geom_text(data = player_df_11, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_11, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_11, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_11, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_11, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_11), newpage=FALSE)
## NULL
player_df_11 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_12 <- player_df %>%
filter(name == player_12)
player_12_shots <- team_df %>%
filter( namePlayer == player_12) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_12_shots$x <- player_12_shots$x * -1
shotData_player_12 <- player_12_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_12 <- shotData_player_12 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_12 <- shotData_player_12 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_12 <- shotData_player_12 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_12 <- shotData_player_12 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_12 <- shotData_player_12 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_12 <- shotData_player_12 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_12_heat <- plot_court() +
geom_density_2d_filled(player_12_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_12 <- shotData_player_12 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_12 <- rasterGrob(readPNG(getURLContent(headshot_player_12)),
width = unit(.15, "npc"))
player_12_heat +
geom_text(data = ra_player_12 , x = 0 , y = 7, label = ra_player_12$'points per attempt') +
geom_text(data = ra_player_12 , x = 0 , y = 5, label = ra_player_12$'shots') +
geom_text(data = ip_player_12, x = 0 , y = 15, label = ip_player_12$'points per attempt') +
geom_text(data = ip_player_12, x = 0 , y = 13, label = ip_player_12$'shots') +
geom_text(data = abb3_player_12, x = 0 , y = 33, label = abb3_player_12$'points per attempt') +
geom_text(data = abb3_player_12, x = 0 , y = 31, label = abb3_player_12$'shots') +
geom_text(data = mr_player_12, x = 0 , y = 24, label = mr_player_12$'points per attempt') +
geom_text(data = mr_player_12, x = 0 , y = 22, label = mr_player_12$'shots') +
geom_text(data = rc3_player_12, x = -22, y = 7, label = rc3_player_12$'points per attempt') +
geom_text(data = rc3_player_12, x = -22, y = 5, label = rc3_player_12$'shots') +
geom_text(data = lc3_player_12, x = 22, y = 7, label = lc3_player_12$'points per attempt') +
geom_text(data = lc3_player_12, x = 22, y = 5, label = lc3_player_12$'shots') +
geom_text(data = player_df_12, x = -8, y = 46, label = player_df_12$shot_quality_avg) +
geom_text(data = player_df_12, x = -8, y = 44, label = player_df_12$ts_pct) +
geom_text(data = player_df_12, x = -8, y = 42, label = player_df_12$usage) +
geom_text(data = player_df_12, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_12, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_12, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_12, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_12, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_12), newpage=FALSE)
## NULL
player_df_12 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_13 <- player_df %>%
filter(name == player_13)
player_13_shots <- team_df %>%
filter( namePlayer == player_13) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_13_shots$x <- player_13_shots$x * -1
shotData_player_13 <- player_13_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_13 <- shotData_player_13 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_13 <- shotData_player_13 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_13 <- shotData_player_13 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_13 <- shotData_player_13 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_13 <- shotData_player_13 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_13 <- shotData_player_13 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_13_heat <- plot_court() +
geom_density_2d_filled(player_13_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_13 <- shotData_player_13 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_13 <- rasterGrob(readPNG(getURLContent(headshot_player_13)),
width = unit(.15, "npc"))
player_13_heat +
geom_text(data = ra_player_13 , x = 0 , y = 7, label = ra_player_13$'points per attempt') +
geom_text(data = ra_player_13 , x = 0 , y = 5, label = ra_player_13$'shots') +
geom_text(data = ip_player_13, x = 0 , y = 15, label = ip_player_13$'points per attempt') +
geom_text(data = ip_player_13, x = 0 , y = 13, label = ip_player_13$'shots') +
geom_text(data = abb3_player_13, x = 0 , y = 33, label = abb3_player_13$'points per attempt') +
geom_text(data = abb3_player_13, x = 0 , y = 31, label = abb3_player_13$'shots') +
geom_text(data = mr_player_13, x = 0 , y = 24, label = mr_player_13$'points per attempt') +
geom_text(data = mr_player_13, x = 0 , y = 22, label = mr_player_13$'shots') +
geom_text(data = rc3_player_13, x = -22, y = 7, label = rc3_player_13$'points per attempt') +
geom_text(data = rc3_player_13, x = -22, y = 5, label = rc3_player_13$'shots') +
geom_text(data = lc3_player_13, x = 22, y = 7, label = lc3_player_13$'points per attempt') +
geom_text(data = lc3_player_13, x = 22, y = 5, label = lc3_player_13$'shots') +
geom_text(data = player_df_13, x = -8, y = 46, label = player_df_13$shot_quality_avg) +
geom_text(data = player_df_13, x = -8, y = 44, label = player_df_13$ts_pct) +
geom_text(data = player_df_13, x = -8, y = 42, label = player_df_13$usage) +
geom_text(data = player_df_13, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_13, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_13, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_13, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_13, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_13), newpage=FALSE)
## NULL
player_df_13 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_14 <- player_df %>%
filter(name == player_14)
player_14_shots <- team_df %>%
filter( namePlayer == player_14) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_14_shots$x <- player_14_shots$x * -1
shotData_player_14 <- player_14_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_14 <- shotData_player_14 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_14 <- shotData_player_14 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_14 <- shotData_player_14 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_14 <- shotData_player_14 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_14 <- shotData_player_14 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_14 <- shotData_player_14 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_14_heat <- plot_court() +
geom_density_2d_filled(player_14_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_14 <- shotData_player_14 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_14 <- rasterGrob(readPNG(getURLContent(headshot_player_14)),
width = unit(.15, "npc"))
player_14_heat +
geom_text(data = ra_player_14 , x = 0 , y = 7, label = ra_player_14$'points per attempt') +
geom_text(data = ra_player_14 , x = 0 , y = 5, label = ra_player_14$'shots') +
geom_text(data = ip_player_14, x = 0 , y = 15, label = ip_player_14$'points per attempt') +
geom_text(data = ip_player_14, x = 0 , y = 13, label = ip_player_14$'shots') +
geom_text(data = abb3_player_14, x = 0 , y = 33, label = abb3_player_14$'points per attempt') +
geom_text(data = abb3_player_14, x = 0 , y = 31, label = abb3_player_14$'shots') +
geom_text(data = mr_player_14, x = 0 , y = 24, label = mr_player_14$'points per attempt') +
geom_text(data = mr_player_14, x = 0 , y = 22, label = mr_player_14$'shots') +
geom_text(data = rc3_player_14, x = -22, y = 7, label = rc3_player_14$'points per attempt') +
geom_text(data = rc3_player_14, x = -22, y = 5, label = rc3_player_14$'shots') +
geom_text(data = lc3_player_14, x = 22, y = 7, label = lc3_player_14$'points per attempt') +
geom_text(data = lc3_player_14, x = 22, y = 5, label = lc3_player_14$'shots') +
geom_text(data = player_df_14, x = -8, y = 46, label = player_df_14$shot_quality_avg) +
geom_text(data = player_df_14, x = -8, y = 44, label = player_df_14$ts_pct) +
geom_text(data = player_df_14, x = -8, y = 42, label = player_df_14$usage) +
geom_text(data = player_df_14, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_14, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_14, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_14, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_14, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_14), newpage=FALSE)
## NULL
player_df_14 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)
player_df_15 <- player_df %>%
filter(name == player_15)
player_15_shots <- team_df %>%
filter( namePlayer == player_15) %>%
mutate( x = as.numeric(as.character(locationX))/10,
y = as.numeric(as.character(locationY))/ 10 + hoop_center_y,
dateGame = as.numeric(dateGame))
player_15_shots$x <- player_15_shots$x * -1
shotData_player_15 <- player_15_shots %>%
filter( nameZone != "Back Court") %>%
mutate( isShotAttempted =
case_when(
isShotAttempted == "TRUE" ~ 1,
TRUE ~ 0
),
isShotMade =
case_when(
isShotMade == "TRUE" ~ 1,
TRUE ~ 0
)) %>%
right_join(active_player_photos)
abb3_player_15 <- shotData_player_15 %>%
filter( zoneBasic == "Above the Break 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot)) %>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Above the Break 3",
'points per attempt' = accuracy * 3)
lc3_player_15 <- shotData_player_15 %>%
filter( zoneBasic == "Left Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Left Corner 3",
'points per attempt' = accuracy * 3)
mr_player_15 <- shotData_player_15 %>%
filter( zoneBasic == "Mid-Range") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Mid-Range",
'points per attempt' = accuracy * 2)
rc3_player_15 <- shotData_player_15 %>%
filter( zoneBasic == "Right Corner 3") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Right Corner 3",
'points per attempt' = accuracy * 3)
ip_player_15 <- shotData_player_15 %>%
filter( zoneBasic == "In The Paint (Non-RA)") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "In the Paint (non RA)",
'points per attempt' = accuracy * 2)
ra_player_15 <- shotData_player_15 %>%
filter( zoneBasic == "Restricted Area") %>%
summarise( accuracy = mean(isShotMade),
shots = sum(isShotAttempted),
makes = sum(isShotMade),
avg_distance = mean(distanceShot))%>%
mutate_at(vars(accuracy, avg_distance), funs(round(.,4))) %>%
mutate( accuracy = accuracy ,
zone = "Restricted Area",
'points per attempt' = accuracy * 2)
palette <- paletteer_d( "RColorBrewer::YlOrRd", direction = -1 )
player_15_heat <- plot_court() +
geom_density_2d_filled(player_15_shots, mapping = aes( x = x, y = y,
fill = ..level..,),
contour_var = "ndensity" ,
breaks = seq(0.1,1.0, length.out = 10),
alpha = .75) +
scale_fill_manual( values = c(palette), aesthetics = c("fill", "color")) +
scale_x_continuous( limits = c(-27.5, 27.5)) +
scale_y_continuous( limits = c(0, 45)) +
theme( legend.position = "none",
plot.title = element_text( hjust = .5 , size = 22,
family = "Comic Sans MS",
face = "bold",
vjust = -4),
plot.subtitle = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
vjust = -5),
legend.direction = "horizontal",
legend.title = element_blank(),
legend.text = element_text( hjust = .5, size = 10,
family = "Comic Sans MS",
face = "bold",
color = "white"),
plot.caption = element_text(hjust = .5, size = 6,
family = "Comic Sans MS",
face = "bold",
color = "lightgrey",
vjust = 8)
)
headshot_player_15 <- shotData_player_15 %>%
select(urlPlayerHeadshot) %>%
.[1,1]
playerImg_player_15 <- rasterGrob(readPNG(getURLContent(headshot_player_15)),
width = unit(.15, "npc"))
player_15_heat +
geom_text(data = ra_player_15 , x = 0 , y = 7, label = ra_player_15$'points per attempt') +
geom_text(data = ra_player_15 , x = 0 , y = 5, label = ra_player_15$'shots') +
geom_text(data = ip_player_15, x = 0 , y = 15, label = ip_player_15$'points per attempt') +
geom_text(data = ip_player_15, x = 0 , y = 13, label = ip_player_15$'shots') +
geom_text(data = abb3_player_15, x = 0 , y = 33, label = abb3_player_15$'points per attempt') +
geom_text(data = abb3_player_15, x = 0 , y = 31, label = abb3_player_15$'shots') +
geom_text(data = mr_player_15, x = 0 , y = 24, label = mr_player_15$'points per attempt') +
geom_text(data = mr_player_15, x = 0 , y = 22, label = mr_player_15$'shots') +
geom_text(data = rc3_player_15, x = -22, y = 7, label = rc3_player_15$'points per attempt') +
geom_text(data = rc3_player_15, x = -22, y = 5, label = rc3_player_15$'shots') +
geom_text(data = lc3_player_15, x = 22, y = 7, label = lc3_player_15$'points per attempt') +
geom_text(data = lc3_player_15, x = 22, y = 5, label = lc3_player_15$'shots') +
geom_text(data = player_df_15, x = -8, y = 46, label = player_df_15$shot_quality_avg) +
geom_text(data = player_df_15, x = -8, y = 44, label = player_df_15$ts_pct) +
geom_text(data = player_df_15, x = -8, y = 42, label = player_df_15$usage) +
geom_text(data = player_df_15, x = -19, y = 46, label = "Avg. Shot Quality = ") +
geom_text(data = player_df_15, x = -19, y = 44, label = "True Shooting % = ") +
geom_text(data = player_df_15, x = -19, y = 42, label = "Usage = ") +
geom_text(data = player_df_15, x = -11, y = 33, label = "Points per Attempt = ") +
geom_text(data = player_df_15, x = -11, y = 31, label = "Attempts = ")
pushViewport(viewport(x = unit(0.9, "npc"), y = unit(0.8, "npc")))
print(grid.draw(playerImg_player_15), newpage=FALSE)
## NULL
player_df_15 %>%
mutate('% of 2s Assisted' = assisted2s_pct,
'% of 3s Assisted' = assisted3s_pct,
'Rim or 3 Frequency' = at_rim_fg3a_frequency,
'Rim Frequency' = at_rim_frequency,
'% of Rim Assisted' = at_rim_pct_assisted,
'Short Mid Range Frequency' = short_mid_range_frequency,
'% of Short Mid Range Assisted' = short_mid_range_pct_assisted,
'Long Mid Range Frequency' = long_mid_range_frequency,
'% of Long Mid Range Assisted' = long_mid_range_pct_assisted,
'Corner 3 Frequency' = corner3frequency,
'% of Corner 3s Assisted' = corner3pct_assisted,
'Arc 3 Frequency' = arc3frequency,
'% of Arc 3s Assisted' = arc3pct_assisted) %>%
select('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted') %>%
mutate_at(vars('% of 2s Assisted',
'% of 3s Assisted',
'Rim or 3 Frequency',
'Rim Frequency',
'% of Rim Assisted',
'Short Mid Range Frequency',
'% of Short Mid Range Assisted',
'Long Mid Range Frequency',
'% of Long Mid Range Assisted',
'Corner 3 Frequency',
'% of Corner 3s Assisted',
'Arc 3 Frequency',
'% of Arc 3s Assisted'), funs(round(.,2))) %>%
t() %>%
as.data.frame() %>%
rename( "2022-2023" = "V1") %>%
reactable( theme = espn(),
pagination = FALSE)