Sam
Sam

Reputation: 381

Add geom_hline legend to existing geom bar legend

I want to add a legend under the existing legend that represents the dashed line, such that the dashed line could be labeled "avg tx effect" and be placed under study 3.

enter image description here

library(ggplot2)
library(ggthemes)

#dput(df)

df=structure(list(study = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("study1", "study2", 
"study3"), class = "factor"), d = c(-0.205, 0.1075, 0.3525, -0.37, 
0.3, 0.42, -0.28, 0.09, 0.59, 0.11, -0.05, 0.25, 0, 0.25, 0.49
), Outcome = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 
5L, 5L, 5L), Outcome2 = structure(c(1L, 1L, 1L, 4L, 4L, 4L, 7L, 
7L, 7L, 10L, 10L, 10L, 13L, 13L, 13L), .Label = c("1", "1", "1", 
"2", "2", "2", "3", "3", "3", "4", "4", "4", "5", "5", "5"), class = "factor")), .Names = c("study", 
"d", "Outcome", "Outcome2"), row.names = c(NA, -15L), class = "data.frame")

ggplot(df, aes(x=Outcome2, y=d, fill=study)) + 
   geom_bar(position=position_dodge(), aes(x=Outcome2),stat="identity",
             colour="black", # Use black outlines,
             size=.3) +      # Thinner lines
    xlab("Outcome") +
    ylab("Cohen's D Effect Size") +
    scale_fill_grey(name="Study", 
                   labels=c("study1","study2", "study3"))+
        theme_bw()+
    geom_hline(yintercept=.15,linetype=2)   

Upvotes: 3

Views: 3113

Answers (2)

Henrik
Henrik

Reputation: 67828

A general feature of ggplot is that to generate a legend, you need to map your aesthetics (e.g. linetype) to a variable in the data, instead of setting it to constant. In the case of geom_hline, this may be achieved by putting the intercept in a separate data frame. Also note show_guide = TRUE.

Then customize the legend using scale_linetype_manual. The black lines in the fill legend are removed using override.aes.

Here's a stripped down version of your code to show only the most necessary steps:

df2 <- data.frame(yi = 0.15)

ggplot(data = df, aes(x = Outcome2, y = d, fill = study)) + 
  geom_bar(position = "dodge", stat = "identity") +
  geom_hline(data = df2, aes(yintercept = yi, linetype = factor(yi)), show_guide = TRUE) +
  scale_linetype_manual(name = "avg tx effect", values = "dashed", labels = "") +
  guides(fill = guide_legend(override.aes = list(linetype = "blank")))

enter image description here

Upvotes: 8

User7598
User7598

Reputation: 1678

As @Gregor suggested, you could use a direct label for this line by adding annotate() as shown below:

ggplot(df, aes(x=Outcome2, y=d, fill=study)) + 
   geom_bar(position=position_dodge(), aes(x=Outcome2),stat="identity",
             colour="black", # Use black outlines,
             size=.3) +      # Thinner lines
    xlab("Outcome") +
    ylab("Cohen's D Effect Size") +
    scale_fill_grey(name="Study", 
                   labels=c("study1","study2", "study3"))+
        theme_bw()+
    geom_hline(yintercept=.15,linetype=2) +annotate("text",x=.7,y=.17,size=3,label=c('avg tx ef')) 

enter image description here

If space is an issue you can use the wrapper described here to wrap the text. Just run wrapper <- function(x, ...) paste(strwrap(x, ...), collapse = "\n") then add +annotate("text",x=.7,y=.18,size=3,label=wrapper('avg tx effect',10)). Which produces:

enter image description here

Upvotes: 2

Related Questions