0
votes

How to adjust the height of each geom_line depending on the facet group (y-lims differ depending on the group, see image below)?

I tried to build a custom data.frame which contains heights for each condition but this is not accepted by geom_line.

I have this little working example:

carData <- mtcars
carData$cyl <- factor(carData$cyl)
maxval <- max(carData$mpg)
maxval <- maxval * 1.1
lowval <- maxval - maxval * 0.02
txtval <- maxval * 1.04
llev <- "4"
rlev <- "6"
lpos <- which(levels(carData$cyl) == llev)
rpos <- which(levels(carData$cyl) == rlev)
mpos <- (lpos + rpos) / 2

df1 <- data.frame(a = c(lpos,lpos,rpos,rpos), b = c(lowval, maxval, maxval, lowval))

p <- ggplot(carData, aes(cyl, mpg)) 
p <- p + geom_boxplot()
p <- p + geom_line(data = df1, aes(x = a, y = b)) + annotate("text", x = mpos, y = txtval, label = "3.0")
p <- p + facet_wrap( ~ gear,ncol=2,scales="free")

enter image description here

1
You say that you have tried a data.frame with different levels for different facets, but df1 doesn't have that. Can you actually show the one with the different levels? - Axeman

1 Answers

3
votes

You need to capture the variable you are using to facet with, in your summary data.frame. We could capture group wise maxima and use them for the y positions of the geom_segment() and geom_text:

library(tidyverse)

# get the max for each gear facet
df2 <- carData %>% group_by(gear) %>%
    summarise(ypos = max(mpg)*1.1) %>%
    mutate(x = lpos, xend = rpos) # use your factor level locators

p <- ggplot(carData, aes(cyl, mpg)) +
    geom_boxplot() +
    geom_segment(data = df2, aes(y = ypos, yend = ypos, x = x, xend = xend)) +
    geom_text(data = df2, aes(y = ypos*1.02, x = mean(c(x, xend))), label = "3.0") +
    facet_wrap( ~ gear,ncol=2, scales="free")

# if you want the end ticks
p +  geom_segment(data = df2, aes(y = ypos, yend = ypos * .99, x = x, xend = x)) +
     geom_segment(data = df2, aes(y = ypos, yend = ypos *.99, x = xend, xend = xend))

enter image description here