4

This is question that's been asked many times, I know, but I still can't figure out a good answer. I would like to get a pretty legend that shows manually-added lines in a separate legend on the plot. Here's what I've figured out so far:

library(ggplot2)
data(mtcars)

ggplot(mtcars, aes(x=disp, y=mpg, color=factor(am))) +
   theme_bw() + 
   geom_point() + 
   geom_smooth(method = 'lm', se=FALSE) + 
   geom_abline(aes(intercept=40, slope = (-1/10))) +
   geom_abline(aes(intercept=25, slope = (-1/30)))

gives:

enter image description here

which has manually-added lines, but no legend entry for them.

Attempt 1

Just adding show.legend=TRUE isn't very helpful:

ggplot(mtcars, aes(x=disp, y=mpg, color=factor(am))) +
    theme_bw() + 
    geom_point() + 
    geom_smooth(method = 'lm', se=FALSE) + 
    geom_abline(aes(intercept=40, slope = (-1/10)), show.legend = TRUE) +
    geom_abline(aes(intercept=25, slope = (-1/30)), show.legend = TRUE)  

enter image description here

Attempt 2

Adding an artificial fill for each additional line isn't very helpful, either:

ggplot(mtcars, aes(x=disp, y=mpg, color=factor(am))) +
   theme_bw() + 
   geom_point() + 
   geom_smooth(method = 'lm', se=FALSE) + 
   geom_abline(aes(intercept=40, slope = (-1/10), fill='Comparison Line 1')) +
   geom_abline(aes(intercept=25, slope = (-1/30), fill='Comparison Line 2'))  

it just gives a warning and returns the original plot:

Warning: Ignoring unknown aesthetics: fill
Warning: Ignoring unknown aesthetics: fill

enter image description here

Attempt 3

Adding both show.legend=TRUE and a fake aes fill gets close, but the result is very ugly:

ggplot(mtcars, aes(x=disp, y=mpg, color=factor(am))) +
   theme_bw() + 
   geom_point() + 
   geom_smooth(method = 'lm', se=FALSE) + 
   geom_abline(aes(intercept=40, slope = (-1/10), fill='Comparison Line 1'), show.legend = TRUE) +
   geom_abline(aes(intercept=25, slope = (-1/30), fill='Comparison Line 2'), show.legend = TRUE)

enter image description here

Finally, my question:
How do I get rid of the diagonal lines in the color legend (titled "factor(am)"), and how do I get normal-looking lines next to the items in the fill legend (titled "fill")?

pogibas
  • 27,303
  • 19
  • 84
  • 117
filups21
  • 1,611
  • 1
  • 19
  • 22

1 Answers1

2

You were very close!
Add dummy variable that is relevant to geom_abline for example size to aes(). And scale size back using scale_size_manual.

library(ggplot2)
ggplot(mtcars, aes(x=disp, y=mpg, color=factor(am))) +
   theme_bw() + 
   geom_point() + 
   geom_smooth(method = 'lm', se=FALSE) + 
   geom_abline(aes(intercept=40, slope = (-1/10), size='Comparison Line 1')) +
   geom_abline(aes(intercept=25, slope = (-1/30), size='Comparison Line 2')) +
   scale_size_manual(values = c(0.3, 0.3))

enter image description here

PS.: Fill that you were using is unknown aesthetics for the abline (as ggplot2 warns you: Warning: Ignoring unknown aesthetics: fill).

pogibas
  • 27,303
  • 19
  • 84
  • 117
  • This looks great as long as the 2 lines look the same, but when the 2 lines are different size, type, or color, the legend doesn't reflect those differences: `ggplot(mtcars, aes(x=disp, y=mpg, color=factor(am))) + theme_bw() + geom_point() + geom_smooth(method = 'lm', se=FALSE) + geom_abline(aes(intercept=40, slope = (-1/10), size='Comparison Line 1'), alpha = .5) + geom_abline(aes(intercept=25, slope = (-1/30), size='Comparison Line 2'),color='red', linetype=2) + scale_size_manual(values = c(1, 0.3))` – filups21 Nov 04 '17 at 15:29
  • 1
    And, to answer my own question, I need to add in `guide=guide_legend(override.aes = list(linetype=c(1,2), color=c('black', 'red')))` to the scale_xxx_manual() function: `scale_size_manual(values = c(1, 0.3), guide=guide_legend(override.aes = list(linetype=c(1,2), color=c('black', 'red'))))` – filups21 Nov 04 '17 at 15:47