0
votes

I have following code

d <- data.frame(a = c("a", "b", "a", "b"), b = c("c", "c", "d", "d"), y = c(4, 5, 3, 2))
ggplot(data = d, aes(x = a, y = y, fill = b)) +
   geom_col(position = position_dodge(0.9)) +
   annotate("segment", x = "a", xend = "a", y = 5, yend = 4, arrow = arrow())

What I'm getting is following:

enter image description here

What I want is to have an arrow point to a concrete bar. And potentially I want to have multiple arrows. For example like this:

enter image description here

The problem is that I don't know how to address concrete bar on the x-axis, i.e. which are the x-values for individual dodged bars.

2

2 Answers

3
votes

You can refer to the position of a and b by a number, starting from 1. Here, a will be 1, and b will be 2. The number corresponds to the position of the level (see levels(d$a)).

To put multiple annotations, you can either add multiple annotate elements, or you can use vectors for x/xend/y/yend positions.

So in your case, the following should work just fine:

dodge <- 0.9
ggplot(data = d, aes(x = a, y = y, fill = b)) +
  geom_col(position = position_dodge(dodge)) +
  annotate("segment", x = 1,       xend = 1 - dodge/4, y = 5, yend = 4, arrow = arrow()) +
  annotate("segment", x = 1 + dodge/4, xend = 1 + dodge/4, y = 4, yend = 3, arrow = arrow())

Or using vectors:

dodge <- 0.9
ggplot(data = d, aes(x = a, y = y, fill = b)) +
  geom_col(position = position_dodge(dodge)) +
  annotate("segment", x     = c(1, 1 + dodge/4),
                      xend  = c(1 - dodge/4, 1 + dodge/4),
                      y     = c(5, 4),
                      yend  = c(4, 3), arrow = arrow())

Of course you could use a data.frame for the data of the annotate element, as you would do for any geom_* elements.

Rplot showing annotations with two arrows

3
votes
data.frame(a=c("a", "b", "a", "b"), b=c("c", "c", "d", "d"), y=c(4, 5, 3, 2)) %>%
  ggplot(aes(x=a, y=y, fill=b)) +
  geom_col(position=position_dodge(0.9)) +
  annotate("segment", x=1, xend=.7, y = 5, yend=4.1, arrow=arrow()) +
  annotate("segment", x=1.2, xend=1.2, y = 4, yend=3.1, arrow=arrow())

enter image description here