Search code examples
rggplot2legendreshape2data-manipulation

Combining my two `geom_abline` in ggplot2 to get legend


I have the plot below, using this code (see below for data), but as I'm struggling to get group in the aes call to get a meaningful legend for (the black and the blue line). I am trying to combine the two geom_abline's in some way.

# install.packages("ggplot2", dependencies = TRUE)
library(ggplot2)
p1 <- ggplot(dfn, aes(x, y)) +
     geom_jitter(position = position_jitter(width = .05, height = 0)) + 
     scale_x_continuous(breaks=c(0,1), labels=c("0", "1")) +
     geom_abline(aes(intercept = in.a, slope = sl.a)) +
     geom_abline(aes(intercept = in.b, slope = sl.b), colour="blue") +    
     facet_wrap(~ group, ncol = 2)
p1

facet_wrap

## data
dfn <- data.frame(
x = sample(c(0,1), 91, replace = TRUE),
y = rnorm(91, mean = 1, sd = 2),
in.a = rep(1.31, 91),
sl.a = rep(-0.61, 91),
in.b = c(0.62, 0.62, 0.62, 0.62, 0.90, 0.90, 0.90, 0.90, 
0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 
0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 
0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 
0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 
0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 
0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 0.90, 
1.41, 1.41, 1.41, 1.68, 1.68, 1.68, 1.68, 1.68, 
1.68, 1.68, 1.29, 1.29, 1.29, 1.29, 1.49, 1.49, 
1.49, 1.85, 1.85, 1.85, 1.85, 1.85, 1.85, 1.85, 
1.85, 1.85, 1.85, 1.85, 1.85, 1.85, 1.85, 2.08, 
2.08, 2.08, 2.08), sl.b = 
c(0.18, 0.18, 0.18, 0.18, -1.20, -1.20, -1.20, 
-1.20, -1.20, -1.20, -1.20, -1.20, -1.20, -1.20, 
-1.20, -1.20, -1.20, -1.20, -1.20, -1.20, -1.20, 
-1.20, -1.20, -1.20, -1.20, -1.20, -1.20, -1.20, 
-1.20, -1.20, -1.20, -1.20, -1.20, -1.20, -1.20, 
-1.20, -1.20, -1.20, -1.20, -1.20, -1.20, -1.20, 
-1.20, -1.20, -1.20, -1.20, -1.20, -1.20, -1.20, 
-1.20, -1.20, -1.20, -1.20, -1.20, -1.20, -1.20, 
-0.54, -0.54, -0.54, -0.97, -0.97, -0.97, -0.97, 
-0.97, -0.97, -0.97, -0.22, -0.22, -0.22, -0.22, 
0.06, 0.06, 0.06, 0.35, 0.35, 0.35, 0.35, 
0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 
0.35, 0.35, 0.35, -0.93, -0.93, -0.93, -0.93
),
group = c(1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 
7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L)
)

Solution

  • So I'd do something like this if you're using reshape2:

    library(reshape2)
    #Starting point
    ab_dat <- unique(dfn[,-(1:2)])
    
    #Melt the slopes and intercepts separately and then join
    ab_dat1 <- melt(ab_dat,
                    id.vars = c('group'),
                    measure.vars = c('in.a','in.b'),
                    variable.name = 'color_grp',
                    value.name = 'intercept')
    ab_dat1$color_grp <- gsub("in.","",ab_dat1$color_grp,fixed = TRUE)
    
    ab_dat2 <- melt(ab_dat,
                    id.vars = c('group'),
                    measure.vars = c('sl.a','sl.b'),
                    variable.name = 'color_grp',
                    value.name = 'slope')
    ab_dat2$color_grp <- gsub("sl.","",ab_dat1$color_grp,fixed = TRUE)
    
    ab_dat3 <- merge(ab_dat1,ab_dat2)
    
    library(ggplot2)
    p1 <- ggplot() +
        facet_wrap(~ group, ncol = 2) +
        geom_jitter(data = dfn, aes(x, y),
                    position = position_jitter(width = .05, height = 0)) + 
        scale_x_continuous(breaks=c(0,1), labels=c("0", "1")) +
        geom_abline(data = ab_dat3,
                    aes(intercept = intercept, slope = slope,color = color_grp))
    p1