5

I am using facet_grid() to plot multiple plot divided per groups of data. For each plot, I want to add in the corner the highest value of the Y axis. I've tried several hacks but it never gives me the expected results. This answer partially helps me but the value I want to add will constantly be changing, therefore I don't see how I can apply it.

Here is a minimal example, I'd like to add the red numbers on the graph below:

library(ggplot2)

data <- data.frame('group'=rep(c('A','B'),each=4),'hour'=rep(c(1,2,3,4),2),'value'=c(5,4,2,3,6,7,4,5))

ggplot(data,aes(x = hour, y = value)) +
  geom_line() +
  geom_point() +
  theme(aspect.ratio=1) +
  scale_x_continuous(name ="hours", limits=c(1,4)) +
  scale_y_continuous(limits=c(1,10),breaks = seq(1, 10, by = 2))+
  facet_grid( ~ group)

enter image description here

Thanks for your help!

Community
  • 1
  • 1
Pierre Dudek
  • 252
  • 4
  • 11
  • 1
    Calculate the maximum per group outside ggplot2, e.g., using `aggregate`. – Roland Dec 29 '16 at 10:10
  • 1
    ... or do it inside the geom_text call, like `geom_text(aes(label=value, y=Inf, x=Inf), aggregate(value~group,data,max), hjust=2, vjust=2, color="red", fontface=2)`. – lukeA Dec 29 '16 at 10:21

2 Answers2

3
library(dplyr)
data2 <- data %>% group_by(group) %>% summarise(Max = max(value))

ggplot(data,aes(x = hour, y = value)) +
  geom_line() +
  geom_point() +
  geom_text(aes(label = Max), x = Inf, y = Inf, data2, 
            hjust = 2, vjust = 2, col = 'red') +
  theme(aspect.ratio=1) +
  scale_x_continuous(name ="hours", limits=c(1,4)) +
  scale_y_continuous(limits=c(1,10),breaks = seq(1, 10, by = 2))+
  facet_grid( ~ group)

enter image description here

Axeman
  • 32,068
  • 8
  • 81
  • 94
  • 1
    @RichardTelford: `data2` is only used for the `geom_text`, the points and lines still use `data`. – Axeman Dec 29 '16 at 10:36
  • sorry - I thought your solution was identical to mine - but I used `mutate` rather than `summarise` and then used the same data throughout. – Richard Telford Dec 29 '16 at 10:38
  • 1
    @RichardTelford I think that will overplot the number several times, which can end up looking a bit weird. – Axeman Dec 29 '16 at 10:39
2

This does the trick. If you always have fixed ranges you can position the text manually.

library(ggplot2)

data <- data.frame('group'=rep(c('A','B'),each=4),'hour'=rep(c(1,2,3,4),2),'value'=c(5,4,2,3,6,7,4,5))

ggplot(data,aes(x = hour, y = value)) +
    geom_line() +
    geom_point() +
    geom_text(
        aes(x, y, label=lab),
        data = data.frame(
            x=Inf,
            y=Inf,
            lab=tapply(data$value, data$group, max),
            group=unique(data$group)
        ),
        vjust="inward",
        hjust = "inward"
    ) +
    theme(aspect.ratio=1) +
    scale_x_continuous(name ="hours", limits=c(1,4)) +
    scale_y_continuous(limits=c(1,10),breaks = seq(1, 10, by = 2))+
    facet_grid( ~ group)
hugovdberg
  • 1,461
  • 13
  • 24