Adding floating custom labels to ggplot to categories

Viewed 46

I have data as follows:

library(tidyverse)
library(ggplot)

dat <- structure(list(group_size = structure(c(
  6L, 3L, 3L, 4L, 1L, 2L,
  2L, 1L, 3L, 6L, 2L, 6L, 2L, 2L, 1L, 1L, 4L, 1L, 3L, 2L
), .Label = c(
  "(0,50]",
  "(50,100]", "(100,150]", "(150,200]", "(200,250]", "(250,3e+03]"
), class = "factor"), amount = c(
  409, 101, 103, 198, 40, 63,
  69, 49, 126, 304, 91, 401, 96, 63, 36, 1, 177, 7, 112, 61
), group_sum = c(
  1114,
  442, 442, 375, 133, 443, 443, 133, 442, 1114, 443, 1114, 443,
  443, 133, 133, 375, 133, 442, 443
), count = c(
  3L, 4L, 4L, 2L,
  5L, 6L, 6L, 5L, 4L, 3L, 6L, 3L, 6L, 6L, 5L, 5L, 2L, 5L, 4L, 6L
)), row.names = c(NA, -20L), class = c("data.table", "data.frame"))

dat %>%
  as_tibble() %>%
  ggplot(aes(x = group_size)) +
  geom_col(aes(y = group_sum), position = "identity", color = "red", fill = "transparent") +
  geom_label(
    data = dat %>% distinct(group_size, .keep_all = TRUE),
    mapping = aes(y = group_sum, label = group_sum),
    color = "red"
  ) +
  geom_col(aes(y = count * 10), position = "identity", color = "blue", fill = "transparent") +
  geom_label(
    data = dat %>% distinct(count, .keep_all = TRUE),
    mapping = aes(y = count * 10, label = count),
    color = "blue"
  ) +
  scale_y_continuous(sec.axis = sec_axis(trans = ~ . / 10, name = "Count"))

In addition, I have a number of values:

situation_A <- 40   # Belongs to the first category
situation_B <- 120  # Belongs to the third category
situation_C <- 75   # Belongs to the second category
situation_D <- 155  # Belongs to the fourth category
situation_E <- 125  # Belongs to the third category

What I would like to do is to add these situations to their respective categories as in the picture below, is their an easy way to do this?

enter image description here

1 Answers

I suppose the easiest way to do this is to create a little data frame from your labels:

  lab_df <- stack(data.frame(situation_A, situation_B, situation_C, 
                             situation_D, situation_E))
  lab_df$values <- cut(lab_df$values, c(0, 50, 100, 150, 200, 250, 3000))
  lab_df$y <- c(300, 600, 600, 600, 750) # Manually choose y position

So then you only need add a single geom_label call to your plot code:

  dat %>%
    as_tibble() %>%
    ggplot(aes(x = group_size)) +
    geom_col(aes(y = group_sum), position = "identity", color = "red", 
             fill = "transparent") +
    geom_label(
      data = dat %>% distinct(group_size, .keep_all = TRUE),
      mapping = aes(y = group_sum, label = group_sum),
      color = "red"
    ) +
    geom_col(aes(y = count * 10), position = "identity", color = "blue", 
             fill = "transparent") +
    geom_label(
      data = dat %>% distinct(count, .keep_all = TRUE),
      mapping = aes(y = count * 10, label = count),
      color = "blue"
    ) +
    geom_label(data = lab_df, aes(x = values, y = y, label = ind),
               label.padding = unit(4, "mm")
               ) +
  scale_y_continuous(sec.axis = sec_axis(trans = ~ . / 10, name = "Count")) 

enter image description here

Related