EN VI

How to plot geom_bar with written rates?

2024-03-09 23:00:19
How to plot geom_bar with written rates

I'm struggling with how to plot above the bars the rate of made shots by total shots ("Made" + "Missed"). Total shots must be grouped by period and shot type (1pt, 2pt, or 3pt). I'm using a basketball data.

Here is my dataframe and my plot until now. I just need the rate amount written above the bars.

#my data frame
dat_ = structure(list(period = c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 
                          2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), 
               type.shoot = c("1pt", "1pt", "1pt", "1pt", "2pt", "2pt", 
                              "2pt", "2pt", "3pt", "3pt", "3pt", "3pt", "1pt", "1pt", "1pt", 
                              "1pt", "2pt", "2pt", "2pt", "2pt", "3pt", "3pt", "3pt", "3pt"
               ), result = c("made", "made", "made", "made", "made", "made", 
                             "made", "made", "made", "made", "made", "made", "missed", 
                             "missed", "missed", "missed", "missed", "missed", "missed", 
                             "missed", "missed", "missed", "missed", "missed"), Freq = c(9802, 
                                                                                         12043, 12478, 13583, 20407, 19810, 19359, 17903, 8544, 8063, 
                                                                                         8278, 7450, 2756, 3351, 3309, 3898, 16946, 16331, 15735, 
                                                                                         15202, 14550, 14549, 14133, 14113)), row.names = c(NA, -24L
                                                                                         ), class = "data.frame")
#The ggplot until now
ggplot(dat_) + 
  geom_bar(aes(x = period, y = Freq, fill =result, group = 1), 
               alpha = .8,color="transparent", stat = "identity")+
  scale_fill_manual("",c("Made", "Missed"), values = c("deepskyblue", "indianred1" ))+
  facet_wrap(~type.shoot)

enter image description here

I tried to use annotate() geom_text(), without success, since I could not reach the rate. Any hint on how can I do that?

Solution:

You can create a second dataframe with your ratio for the labels and the summed frequencies for the y position:

library(ggplot2)
library(dplyr)
library(tidyr)

dat_ = structure(list(period = c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 
                                 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), 
                      type.shoot = c("1pt", "1pt", "1pt", "1pt", "2pt", "2pt", 
                                     "2pt", "2pt", "3pt", "3pt", "3pt", "3pt", "1pt", "1pt", "1pt", 
                                     "1pt", "2pt", "2pt", "2pt", "2pt", "3pt", "3pt", "3pt", "3pt"
                      ), result = c("made", "made", "made", "made", "made", "made", 
                                    "made", "made", "made", "made", "made", "made", "missed", 
                                    "missed", "missed", "missed", "missed", "missed", "missed", 
                                    "missed", "missed", "missed", "missed", "missed"), Freq = c(9802, 
                                                                                                12043, 12478, 13583, 20407, 19810, 19359, 17903, 8544, 8063, 
                                                                                                8278, 7450, 2756, 3351, 3309, 3898, 16946, 16331, 15735, 
                                                                                                15202, 14550, 14549, 14133, 14113)), row.names = c(NA, -24L
                                                                                                ), class = "data.frame")
ratio <- dat_ |> 
  pivot_wider(id_cols = c(period, type.shoot), names_from = result, values_from = Freq) |> 
  mutate(ratio = made / (made + missed)) |> 
  mutate(total = made + missed)

#The ggplot until now
ggplot(dat_) + 
  geom_col(aes(x = period, y = Freq, fill =result, group = 1), 
           alpha = .8,color="transparent")+
  scale_fill_manual("",c("Made", "Missed"), values = c("deepskyblue", "indianred1" ))+
  geom_text(aes(x = period, y = total, label = round(ratio, 2)), data = ratio, vjust = -0.5) +
  facet_wrap(~type.shoot)

Created on 2024-03-09 with reprex v2.1.0

BTW, geom_col is a wrapper for geom_bar(stat = "identity").

Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login