Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding line type to legend in ggplot2

Tags:

r

legend

ggplot2

How do I make the line types used by geom_hline or geom_abline show up in the legend of a ggplot plot?

For example:

require (ggplot2)

# some data
dummy <- data.frame (category1 =  rep (1:5, 8), category2 = rep (1:4, each = 10), 
    category3 = rep (factor (1:2), 2), expected = 10 ^ rep (4:7, each = 10),
    value = 10 ^rnorm(40, 5))

# faceted plot
baseplot <-ggplot (dummy ) +
    geom_point (aes (category1, value, color = category3))+
    scale_y_log10 () + 
    facet_wrap (~category2)

# add a dotted line for expected value
p1 <-baseplot + geom_hline ( aes ( yintercept = expected), linetype = 2)

I tried a couple approaches to making the dotted line show up in the legend, but they give me the same thing as p1

p1a < -p1+scale_linetype_discrete (labels = "expected")+
    guides ( linetype= guide_legend ("", labels ="expected"))
p1b <- baseplot + geom_hline (aes (yintercept = expected, linetype = "expected")) +
    scale_linetype_manual (labels= "expected", values = 2)
p1a
p1b

How about multiple lines/line types?

Let's say I also wanted to plot groupwise and overall geometric means

require (reshape)
require (plyr)

# calculate geometric means, keep them in their own data frame
geometric_mean <- function (x)  exp ( mean (log (x)))
dummy $GM_overall <- geometric_mean (dummy $value)
extra <- ddply(dummy, c( "GM_overall", "expected","category2"), summarize,
    GM_group = geometric_mean (value))
extra_long <- melt (GM_group_long, id.vars = "category2")

I expected this approach to show linetype in the legend based on this post, but no such luck

p2=baseplot + geom_hline ( aes ( yintercept = value , linetype = variable), extra)
p2

Here's another case where I would want to do something similar with abline

It would be nice to be able to label the line as 1:1

dummy$value2 <- dummy $value * runif(40, 0.5, 2)
ggplot (dummy)+coord_fixed() +    
    geom_point (aes (value, value2, color = category3))+
    geom_abline (yintercept =0, slope =1) 

I'm using R 3.0.0, ggplot 0.9.3.1

like image 845
janattack Avatar asked Sep 17 '25 09:09

janattack


1 Answers

You run through several examples, but this simple case should get you most of the way there:

dummy <- data.frame (category1 =  rep (1:5, 8), category2 = rep (1:4, each = 10), 
    category3 = rep (factor (1:2), 2), expected = 10 ^ rep (4:7, each = 10),
    value = 10 ^rnorm(40, 5))

# faceted plot
baseplot <- ggplot(dummy) +
    geom_point(aes(category1, value, color = category3))+
    scale_y_log10() + 
    facet_wrap(~category2)

# add a dotted line for expected value
baseplot + geom_hline(aes(yintercept = expected,linetype = "expected"),show_guide = TRUE)

The key in most cases, I think, is adding show_guide = TRUE. It is FALSE by default for this geom, which may or may not be intuitive. (I can see the rationale.)

Note how, in this "one line type" case, I "tricked" ggplot into creating a legend by mapping linetype to the character "expected", which causes a new column to be created behind the scenes. Multiple line types should work as expected with the usual methods of creating columns and mapping them to linetype.

like image 196
joran Avatar answered Sep 20 '25 03:09

joran