2

How would I create a label that accounts for two points? In this example I am interested in making a label that is the sum of the the "6" and the "8" bars and has a line pointing to each of them. Currently I have:

library(tidyverse)
library(ggrepel)

mtcars %>% 
  group_by(cyl) %>% 
  summarise(mpg = median(mpg)) %>% 
  ggplot(aes(factor(cyl), mpg, label = mpg)) +
  geom_bar(stat = "identity") +
  geom_text_repel()

separate_labels

The label would be loosely equivalent to code below and would go somewhere above and between the 6 and the 8 bars with lines pointing to each of the bars.

label <- mtcars %>% 
  group_by(cyl) %>% 
  summarise(mpg = median(mpg)) %>% 
  filter(cyl >= 6) %>% 
  summarise (mpg = sum(mpg))
John-Henry
  • 1,556
  • 8
  • 20
  • 1
    I don't know a "built-in" way to do this, but perhaps you could use `annotate("text"...)` and `annotate("segment"...)` to get there. – Jon Spring Oct 21 '19 at 18:34
  • Offhand do you know if segment can be written in a generalized way as a function of the height of the bars? – John-Henry Oct 21 '19 at 18:55

1 Answers1

1

Based on @JonSpring's comment, the generalized answer I wrote is:

df <- 
mtcars %>% 
  group_by(cyl) %>% 
  summarise(mpg = median(mpg)) 

eight <- df %>% filter(cyl == 8) %>% pull(mpg)
six <- df %>% filter(cyl == 6) %>% pull(mpg)
upper <- max(c(six, eight))
total <- sum(six, eight)

df %>% 
  ggplot(aes(factor(cyl), mpg)) +
    geom_bar(stat = "identity") +
    annotate("segment", x = 2, xend = 2.5, y = six, yend = upper + 10) +
    annotate("segment", x = 3, xend = 2.5, y = eight, yend = upper + 10) +
    annotate("label", x = 2.5, y = upper + 10, label = total)

enter image description here

John-Henry
  • 1,556
  • 8
  • 20