012: Minutes Minutiae

gt tables
scatterplot
Published

January 18, 2023

Load data and manipulate

Code
bc <- read_csv("bench_cont.csv")

# pivot longer if we wanted to use continuity
# bc_long <- bc %>%
#       pivot_longer(cols=-c('Season', 'B_Rank', 'C_Rank'),
#                              names_to='type',
#                              values_to='value')

# career minutes
min_car <- read_csv("minutes_career.csv") %>%
  filter(Minutes > 2999 | Player %in% c("Caleb Love", "RJ Davis"))

# current players
cps <-
  c("Caleb Love",
    "Pete Nance*",
    "RJ Davis",
    "Leaky Black",
    "Armando Bacot")

schedule <-
  get_team_schedule(season = "2022-23", team.name = "North Carolina")
================================================================================
Code
# Get play by play for all games played so far in season
play_by_play <- get_play_by_play(schedule$Game_ID[15:19])


lineups <- get_lineups(play_by_play_data = play_by_play)

unc <-  lineups %>%
  filter(Team == "North Carolina") %>%
  mutate(
    P1 = case_when(
      # very inefficient, but hey, it happened
      P1 == "CALEB.LOVE" ~ "Caleb Love",
      P1 == "ARMANDO.BACOT" ~ "Armando Bacot",
      P1 == "DMARCO.DUNN" ~ "D'Marco Dunn",
      P1 == "DONTREZ.STYLES" ~ "Dontrez Styles",
      P1 == "JALEN.WASHINGTON" ~ "Jalen Washington"
    ),
    P2 = case_when(
      P2 == "CALEB.LOVE" ~ "Caleb Love",
      P2 == "DMARCO.DUNN" ~ "D'Marco Dunn",
      P2 == "DONTREZ.STYLES" ~ "Dontrez Styles",
      P2 == "JALEN.WASHINGTON" ~ "Jalen Washington",
      P2 == "JUSTIN.MCKOY" ~ "Justin McKoy",
      P2 == "LEAKY.BLACK" ~ "Leaky Black"
    ),
    P3 = case_when(
      P3 == "DMARCO.DUNN" ~ "D'Marco Dunn",
      P3 == "DONTREZ.STYLES" ~ "Dontrez Styles",
      P3 == "JALEN.WASHINGTON" ~ "Jalen Washington",
      P3 == "JUSTIN.MCKOY" ~ "Justin McKoy",
      P3 == "LEAKY.BLACK" ~ "Leaky Black",
      P3 == "PUFF.JOHNSON" ~ "Puff Johnson",
      P3 == "PETE.NANCE" ~ "Pete Nance"
    ),
    P4 = case_when(
      P4 == "RJ.DAVIS" ~ "RJ Davis",
      P4 == "SETH.TRIMBLE" ~ "Seth Trimble",
      P4 == "JALEN.WASHINGTON" ~ "Jalen Washington",
      P4 == "JUSTIN.MCKOY" ~ "Justin McKoy",
      P4 == "LEAKY.BLACK" ~ "Leaky Black",
      P4 == "PUFF.JOHNSON" ~ "Puff Johnson",
      P4 == "PETE.NANCE" ~ "Pete Nance"
    ),
    P5 = case_when(
      P5 == "RJ.DAVIS" ~ "RJ Davis",
      P5 == "SETH.TRIMBLE" ~ "Seth Trimble",
      P5 == "PUFF.JOHNSON" ~ "Puff Johnson",
      P5 == "TYLER.NICKEL" ~ "Tyler Nickel",
      P5 == "PETE.NANCE" ~ "Pete Nance"
    )
  )


# clean last five
unc_lineups_last_five <- unc %>%
  mutate(Mins = round(Mins, 1)) %>%
  select(c(P1:P5, Mins)) %>%
  arrange(-Mins) %>% # fix empty minutes
  mutate(Mins = ifelse(Mins == 0.0, 0.2, Mins)) %>%
  rename("~Minutes" = Mins)

Set the themes for the plot

Code
# theme
  theme_me <- function () {
    theme_minimal(base_size = 10, base_family = "RobotoCondensed-Regular") %+replace%
      theme (
        plot.title = element_text(
          hjust = 0.5,
          size = 24,
          face = "bold"
        ),
        plot.subtitle = element_text(
          hjust = 0.5,
          size = 10,
          lineheight = 0.25,
          vjust = -0.5
        ),
        plot.caption = element_text(
          hjust = 1,
          size = 6,
          lineheight = 0.35,
          margin = margin(t = 20)
        ),
        panel.grid.minor = element_blank(),
        plot.background = element_rect(fill = "floral white", color = "floral white")
      )
  }

Make the bench minutes plot

Code
bc_plot <- bc  %>%
  ggplot(aes(x = Season, y = Bench)) +
  geom_line(color = "#f08080") +
  geom_point(
    color = 'black',
    fill = "#c4ced4",
    shape = 21,
    size = 4.5,
    alpha = .75,
    aes(color = type)
  ) +
  theme_me() +
  geom_text(
    aes(label = sprintf("%0.1f", round(Bench, digits = 1))),
    color = "#13294B",
    size = 3.5,
    fontface = "bold",
    vjust = 2.5
  ) +
  scale_y_continuous(breaks = seq(18, 38, 4), limits = c(18, 38)) +
  scale_x_continuous(breaks = seq(2008, 2023, 1),
                     limits = c(2008, 2023)) +
  geom_hline(yintercept = 25, linetype = 'dashed') +
  geom_vline(xintercept = 2021.5, linetype = 'dashed') +
  labs(
    x = "",
    y = "",
    title = "<span style='color:#56a0d3;'>North Carolina</span> is playing the bench  \n<span style='color:#f08080;'>*fewer minutes*</span> over the past two seasons",
    caption = "@dadgumboxscores | January 19, 2023 | data via kenpom.com as of January 19"
  ) +
  theme(plot.title = element_textbox_simple(),
        legend.position = "none") +
  annotate(
    "label",
    x = 2015.5,
    y = 22,
    label = "D-I Rankings  \n19.8...(348 out of 358)  \n20.7.....(355 out of 363)",
    family = "Chalkboard Bold",
    size = 3.5,
    color = "#56a0d3",
    fill = "floral white"
  ) +
  annotate(
    geom = "curve",
    color = "#56a0d3",
    x = 2015.5,
    y = 20,
    xend = 2021.7,
    yend = 18.5,
    curvature = .3,
    arrow = arrow(length = unit(2, "mm"))
  ) +
  annotate(
    "label",
    x = 2013,
    y = 34,
    label = "% of minutes from bench",
    family = "Chalkboard Bold",
    size = 3.5,
    color = "#f08080",
    fill = "floral white"
  )
# save it
ggsave(
  "bench.png",
  bc_plot,
  w = 7.5,
  h = 5.5,
  dpi = 300,
  type = 'cairo'
)

bc_plot

Make the career minutes plot

Code
car_plot <- min_car %>%
  ggplot(aes(x = Games, y = Minutes, label = Player)) +
  geom_text_repel(color = ifelse(min_car$Player %in% cps, "#56a0d3", "#444444")) +
  geom_point(color = ifelse(min_car$Player %in% cps, "#56a0d3", "floral white")) +
  theme_me() +
  scale_x_continuous(breaks = seq(80, 160, 20), limits = c(80, 160)) +
  scale_y_continuous(breaks = seq(2500, 4750, 250),
                     limits = c(2500, 4750)) +
  geom_hline(yintercept = 3000, linetype = 'dashed') +
  geom_vline(xintercept = 100, linetype = 'dashed') +
  labs(
    x = "Career games",
    y = "Career minutes",
    title = "North Carolina's <span style='color:#56a0d3;'>starting five</span>  \nhas lots of collegiate experience",
    caption = "@dadgumboxscores | January 19, 2023 | data via goheels.com as of January 19"
  ) +
  theme(plot.title = element_textbox_simple(),
        legend.position = "none") +
  annotate(
    "label",
    x = 87,
    y = 3650,
    label = "RJ Davis and Caleb Love \n*should* eclipse 3,000  \ncareer minutes this season",
    family = "Chalkboard Bold",
    size = 3.5,
    color = "#56a0d3",
    fontface = "bold",
    fill = "floral white"
  ) +
  annotate(
    "label",
    x = 120,
    y = 2750,
    label = "~2500 of Pete Nance's \ncareer collegiate minutes  \nwere at Northwestern",
    family = "Chalkboard Bold",
    size = 3.5,
    color = "#56a0d3",
    fontface = 'bold',
    fill = "floral white"
  ) +
  annotate(
    "label",
    x = 152,
    y = 3875,
    label = "Leaky Black (141 career games)  \n*should* pass Deon Thompson \n(152 career games) this season",
    family = "Chalkboard Bold",
    size = 3.5,
    color = "#56a0d3",
    fontface = 'bold',
    fill = "floral white"
  )

# save it
ggsave(
  "career.png",
  car_plot,
  w = 10.5,
  h = 10.5,
  dpi = 300,
  type = 'cairo'
)

car_plot

Make the lineup tables

Code
# last five gt
top <- unc_lineups_last_five %>%
  filter(`~Minutes` > 4.9) %>%
  mutate(row_number = 1:n()) %>%
  relocate(row_number, .before = P1) %>%
  gt() %>%
  cols_label(
    # rename columns
    row_number = "",
    P1 = "",
    P2 = "",
    P3 = "",
    P4 = "",
    P5 = ""
  ) %>%
  data_color(
    columns = c(`~Minutes`),
    colors = scales::col_numeric(
      c(
        "#0a4c6a",
                 "#73bfe2",
                 "#cfe8f3",
                 "#fff2cf",
                 "#fdd870",
                 "#fdbf11",
                 "#ca5800"
      ),
      domain = range(5:33)
    )
  ) %>%
  gt_theme_538() %>%
  tab_header(title = md("North Carolina's most used lineups over past _five_ games")) %>%
  tab_source_note(source_note = "@dadgumboxscores | January 19, 2023 | data via stats.ncaa.org") %>%
  tab_options (source_notes.font.size = px(10),
               table.font.size = px(10),)

# save image
gtsave_extra(top,
             "top_l.png",
             vwidth = 650,
             vheight = 650)

# all other lineups
bot <- unc_lineups_last_five %>%
  filter(`~Minutes` < 5.0) %>%
  mutate(row_number = 1:n()) %>%
  relocate(row_number, .before = P1) %>%
  gt() %>%
  cols_label(
    # rename columns
    row_number = "",
    P1 = "",
    P2 = "",
    P3 = "",
    P4 = "",
    P5 = ""
  ) %>%
  data_color(
    columns = c(`~Minutes`),
    colors = scales::col_numeric(
      c(
        "#0a4c6a",
                 "#73bfe2",
                 "#cfe8f3",
                 "#fff2cf",
                 "#fdd870",
                 "#fdbf11",
                 "#ca5800"
      ),
      domain = range(0:5)
    )
  ) %>%
  gt_theme_dot_matrix() %>%
  tab_header(title = md("North Carolina's _infrequent_ lineups over past _five_ games")) %>%
  tab_source_note(source_note = "@dadgumboxscores | January 19, 2023 | data via stats.ncaa.org") %>%
  tab_options (
    source_notes.font.size = px(10),
    row.striping.background_color = '#d0e4f3',
    table.font.size = px(10),
    column_labels.text_transform = 'capitalize'
  )

gtsave_extra(bot,
             "bot_l.png",
             vwidth = 650,
             vheight = 650)

top
North Carolina's most used lineups over past five games
~Minutes
1 Armando Bacot Caleb Love Leaky Black RJ Davis Seth Trimble 32.5
2 Armando Bacot Caleb Love Leaky Black Pete Nance RJ Davis 21.7
3 Armando Bacot Caleb Love Leaky Black Puff Johnson RJ Davis 12.8
4 Caleb Love D'Marco Dunn Jalen Washington Puff Johnson RJ Davis 10.9
5 Armando Bacot Caleb Love D'Marco Dunn Puff Johnson RJ Davis 9.6
6 Armando Bacot Caleb Love Justin McKoy Leaky Black RJ Davis 8.3
7 Caleb Love Jalen Washington Leaky Black RJ Davis Seth Trimble 6.7
8 Armando Bacot D'Marco Dunn Leaky Black Puff Johnson RJ Davis 6.3
9 Caleb Love D'Marco Dunn Jalen Washington Leaky Black Puff Johnson 5.5
10 Caleb Love D'Marco Dunn Justin McKoy Leaky Black RJ Davis 5.4
11 Armando Bacot Caleb Love D'Marco Dunn Leaky Black Pete Nance 5.3
12 Armando Bacot Caleb Love D'Marco Dunn Leaky Black Puff Johnson 5.0
13 Caleb Love D'Marco Dunn Dontrez Styles Jalen Washington RJ Davis 5.0
@dadgumboxscores | January 19, 2023 | data via stats.ncaa.org
Code
bot
North Carolina's infrequent lineups over past five games
~Minutes
1 Caleb Love Justin McKoy Leaky Black RJ Davis Seth Trimble 4.4
2 Armando Bacot Caleb Love D'Marco Dunn RJ Davis Seth Trimble 4.3
3 Caleb Love D'Marco Dunn Jalen Washington Leaky Black RJ Davis 4.0
4 Caleb Love Leaky Black Pete Nance RJ Davis Tyler Nickel 3.7
5 Caleb Love Jalen Washington Leaky Black Puff Johnson RJ Davis 3.6
6 D'Marco Dunn Jalen Washington Leaky Black Puff Johnson RJ Davis 3.6
7 Armando Bacot Caleb Love D'Marco Dunn Puff Johnson Seth Trimble 3.4
8 Armando Bacot D'Marco Dunn Jalen Washington Puff Johnson RJ Davis 2.7
9 Armando Bacot Caleb Love Jalen Washington Leaky Black RJ Davis 2.6
10 Armando Bacot Caleb Love Justin McKoy RJ Davis Seth Trimble 2.6
11 Armando Bacot Caleb Love Justin McKoy Leaky Black Seth Trimble 2.5
12 Armando Bacot Leaky Black Puff Johnson RJ Davis Seth Trimble 2.4
13 Caleb Love Jalen Washington Justin McKoy Seth Trimble Tyler Nickel 2.4
14 D'Marco Dunn Dontrez Styles Jalen Washington Seth Trimble Tyler Nickel 2.4
15 Caleb Love Justin McKoy Leaky Black Puff Johnson Seth Trimble 2.3
16 Armando Bacot Caleb Love D'Marco Dunn Leaky Black RJ Davis 2.2
17 Armando Bacot Caleb Love Leaky Black Puff Johnson Seth Trimble 1.7
18 Armando Bacot Justin McKoy Puff Johnson RJ Davis Seth Trimble 1.5
19 Caleb Love Leaky Black Pete Nance Puff Johnson RJ Davis 1.4
20 Caleb Love Jalen Washington Puff Johnson RJ Davis Seth Trimble 1.2
21 Caleb Love D'Marco Dunn Justin McKoy Leaky Black Tyler Nickel 1.1
22 D'Marco Dunn Dontrez Styles Jalen Washington Justin McKoy Tyler Nickel 1.1
23 Jalen Washington Justin McKoy Puff Johnson RJ Davis Seth Trimble 1.1
24 Armando Bacot Caleb Love Puff Johnson RJ Davis Seth Trimble 0.9
25 Dontrez Styles Jalen Washington Puff Johnson RJ Davis Seth Trimble 0.9
26 Armando Bacot Caleb Love D'Marco Dunn Jalen Washington RJ Davis 0.7
27 Armando Bacot D'Marco Dunn Puff Johnson RJ Davis Seth Trimble 0.7
28 Caleb Love D'Marco Dunn Jalen Washington Justin McKoy RJ Davis 0.5
29 Caleb Love Justin McKoy Leaky Black Seth Trimble Tyler Nickel 0.5
30 Caleb Love Jalen Washington Justin McKoy RJ Davis Tyler Nickel 0.2
31 Armando Bacot Caleb Love D'Marco Dunn Justin McKoy RJ Davis 0.2
@dadgumboxscores | January 19, 2023 | data via stats.ncaa.org