Setup

knitr::opts_chunk$set(echo = TRUE)

# Load your package when you want to use it:
pacman::p_load(tidyverse, ggfittext)

# Changing default theme to theme_test()
theme_set(theme_test())
theme_update(
  plot.title = element_text(hjust = 0.5,
                            size = 14)
)

# Reading in the drives2 data set
drives <- read.csv("drives2.csv")

We’ll be focusing, initially, on the drives_end column, which describes how an NFL drive ended:

# First we'll reorder the end groups:
drives <- 
  drives |> 
  mutate(
    drive_end = factor(
      drive_end,  
      levels = c("Turnover", "Punt", "Field Goal", "Touchdown"),
      ordered = T
    )
  )

# The code below creates a summarized data set with the counts and proportions for drive_end
end_sum <- 
  drives |>
  count(drive_end, name = "counts") |> 
  mutate(
    .by = drive_end, 
    prop = counts/sum(counts)
  )

end_sum  

Adding text to a single bar chart:

You can combine geom_col() and geom_bar_text() to add the the proportions below the top of the bars.

Have the y-axis show the counts and add the proportions (rounded to 3 decimal places) above the bars using geom_bar_text() in the ggfittext package. Include contract = T, fontface = "bold"

ggplot(
  data = end_sum, 
  mapping = aes(
    x = drive_end,
    y = counts,
    # Converting the props to a percent
    label = round(prop, digits = 3) |> scales::percent()
  )
) + 
  
  # Adding the bars for the bar chart
  geom_col(
    fill = "#013369",
    color = "#D50A0A"
  ) +
  
  
  geom_bar_text(
    contrast = T,
    fontface = "bold",
  ) + 
  
  scale_y_continuous(
    expand = c(0, 0, 0.05, 0)
  )

We can add a second instance of geom_bar_text() to also place the labels below the y-axis in each bar. Then we wouldn’t need an x or y-axis!

ggplot(
  data = end_sum, 
  mapping = aes(
    x = drive_end,
    y = counts,
    # Rounding the proportions to 3 digits and converting to a %
    label = round(prop, digits = 3) |> scales::percent()
  )
) + 
  
  # Adding the bars and using the NFL logo colors
  geom_col(
    fill = "#013369",
    color = "#D50A0A"
  ) +
  
  # Adding the percentages to the bottom right
  geom_bar_text(
    contrast = T,
    fontface = "bold",
    place = "bottomright"
  ) + 
  
  # Adding the number of drives on the top right
  geom_bar_text(
    mapping = aes(label = paste("n =", counts)),
    contrast = T,
    fontface = "bold",
    place = "topright"
  ) + 
  
  # Adding how the drive ends to the middle left
  geom_bar_text(
    mapping = aes(label = drive_end),
    contrast = T,
    fontface = "bold",
    place = "left"
  ) + 
  
  # Removing the labels for x,y then adding a title
  labs(
    y = NULL,
    x = NULL,
    title = "How an NFL Drive Ends"
  ) +
  
  scale_y_continuous(
    expand = c(0, 0, 0.05, 0)
  ) + 
  
  # Flipping the x and y axes
  coord_flip() +
  
  # removing the labels for the x-axis
  theme(
    # Removing the labels for the axis tick marks
    axis.text = element_blank(),
    # Removing the axis tick marks
    axis.ticks = element_blank()
  )

A pretty basic graph that displays all the relevant information!

Adding text for two variables:

The data set below will create the summarized data set for calculating the conditional proportion of how a drive ends based on how it began:

drive_start_end <- 
  drives |>
  # Counting how many drives start and end combo
  count(
    drive_start, 
    drive_end, 
    name = "counts"
  ) |> 
  # Calculating the conditional proportions
  mutate(
    .by = drive_start,
    prop = counts/sum(counts)
  )

drive_start_end

The code below will create the conditional bar chart without any text:

# Creating a blank graph
gg_drives <- 
  ggplot(
    data = drive_start_end,
    mapping = aes(
      x = drive_start,
      y = prop,
      
      # using fct_rev(drive_end) will make sure the good outcomes are at the top
      fill = fct_rev(drive_end)
    )    
  ) + 
  

  # Change the order of the color so good = yellow, bad = purple
  scale_fill_viridis_d(
    direction = -1
  ) +
  
  scale_y_continuous(
    labels = scales::label_percent(),
    expand = c(0, 0, 0.05, 0)
  ) +
  
  labs(
    x = "How a drive begins",
    y = NULL,
    fill = "Drive \nResult"
  )

# Adding geom_col() to the blank graph
gg_drives +
  geom_col(
    color = "black"
  )

Next, add geom_col() and geom_bar_text() to the graph to add the number of drives in the category combination in the middle of each segment. geom_bar_text() should have the following arguments

Text on side-by-side bar charts

Add the needed geoms with the appropriate arguments to form a side-by-side bar chart that can be seen in Brightspace.