22
votes

I am trying to make the legend key fill for a ggplot transparent. I followed the instructions on one of Hadley's ggplot2 guides for changing the legend key fill, but for some reason when I set the fill to transparent it fills with gray. Even when I set the legend key fill to white, it still appears gray in the final plot.

Here is an example:

library(ggplot2)

data1 = c(0,10, 11, 23, 33, 40, 41, 50, 59, 68, 76, 88, 90, 99)
data2 = c(2, 8, 10, 22, 39, 47, 49, 55, 62, 70, 76, 86, 88, 95)

df = data.frame(data1, data2)

(plot = ggplot() +
  geom_smooth(data=df, aes(data1, data2,colour="sample1"))+
  geom_abline(intercept=0, slope=1,linetype="dashed", color = "black")+
  scale_x_continuous(expand=c(0,0), limits=c(0,100)) + 
  scale_y_continuous(expand=c(0,0), limits=c(0,100))+
  theme_classic()+
  labs(y="data2", x="data1", 
       title="sample 1 data1 vs data2") +
  theme(plot.title = element_text(size=18, face="bold"),
        legend.key = element_rect(colour = "transparent", fill = "white"),
        legend.justification = c(1,0), legend.position = c(1,0))+
  scale_color_discrete(name="Sample") )

Example_plot

If I set theme(legend.key = element_rect(colour = "transparent", fill = "red")) I get the following plot: red_fill

So it appears that I can change the legend key fill, but just not to the color white or transparent.

Does anyone know what I am doing wrong, or if there is just no way to make the legend key fill transparent/white ?

EDIT: Setting theme(legend.key = element_rect(fill = alpha("white", 0.0))) Does not fix the problem.

See here:

library(ggplot2)
library(scales)

data1 = c(0,10, 11, 23, 33, 40, 41, 50, 59, 68, 76, 88, 90, 99)
data2 = c(2, 8, 10, 22, 39, 47, 49, 55, 62, 70, 76, 86, 88, 95)

df = data.frame(data1, data2)

(plot = ggplot() +
  geom_smooth(data=df, aes(data1, data2,colour="sample1"))+
  theme_classic()+
  labs(y="data2", x="data1", 
       title="sample 1 data1 vs data2") +
  theme(plot.title = element_text(size=18, face="bold"),
        legend.key = element_rect(colour = "transparent", fill = alpha("red", 0)),
        legend.justification = c(1,0), legend.position = c(1,0))+
  scale_color_discrete(name="Sample") )

EDIT2: If I use geom_line() instead of geom_smooth I am able to set the legend key fill to NA, so it must be because the line in geom_smooth has a gray area for the confidence interval around it, therefore the legend key mirrors that look.

(plot = ggplot() +
  geom_smooth(data=df, aes(data1, data2,colour="sample1"))+
  geom_abline(intercept=0, slope=1,linetype="dashed", color = "black")+
  scale_x_continuous(expand=c(0,0), limits=c(0,100)) + 
  scale_y_continuous(expand=c(0,0), limits=c(0,100))+
  theme_classic()+
  labs(y="data2", x="data1", 
       title="sample 1 data1 vs data2") +
  theme(plot.title = element_text(size=18, face="bold"),
        legend.key = element_rect(colour = NA, fill = NA),
        legend.justification = c(1,0), legend.position = c(1,0))+
  scale_color_discrete(name="Sample") )

geom_line

5
setting legend.key = element_rect(fill = NA) gave the same result as before. the key fill is still gray.Reilstein
@VermillionAzure In my edit I explained why the solution in the link you provided does not work in this scenario.Reilstein
if you add se = FALSE to your geom_smooth() expression your code works. so what you see in your legend it's the confidence bandMLavoie
I just realized that myself. I realized that if I use geom_line() instead of geom_smooth() then I am able to set the fill to NA. I suppose I can live with not having the confidence band, but its too bad I can't have both! Thanks for your insight. EDIT: Ahh but using geom_line() will not work on my actual data set, because it is not smoothed, so I will use your solution to set se=FALSE insteadReilstein

5 Answers

17
votes

I was going crazy with this behavior as well, so here is a working solution for your example:

plot + guides(color=guide_legend(override.aes=list(fill=NA)))

Check this thread for more information.

15
votes

You could trick it if you want. Add a second geom_smooth(). The first with a confidence band and you don't show the legend. With the second one you remove the band but show the legend.

df$Color <- "Red"
df1 <- df
(plot = ggplot() +
  geom_smooth(data=df, aes(data1, data2,colour=Color), se = TRUE, show.legend = FALSE) + 
  geom_smooth(data=df1, aes(data1, data2,colour=Color), se=FALSE) +
  geom_abline(intercept=0, slope=1,linetype="dashed", color = "black")+
  scale_x_continuous(expand=c(0,0), limits=c(0,100)) + 
  scale_y_continuous(expand=c(0,0), limits=c(0,100))+
  theme_classic()+
  labs(y="data2", x="data1", 
       title="sample 1 data1 vs data2") +
  theme(plot.title = element_text(size=18, face="bold"),
        legend.key = element_rect(colour = "transparent", fill = "white"),
        legend.justification = c(1,0), legend.position = c(1,0))+
  scale_color_discrete(name="Sample"))

enter image description here

9
votes

This answer seems to be the simplest solution, setting legend.key = element_blank() in the theme() definition.

7
votes

Additionally to legend.key = element_blank() you can put legend.background=element_blank() within theme(), to make the text transparent as well

This will also make the default white background transparent when using gg_themes

2
votes

To make use of the transparency levels, one can use:

For the entire legend:

theme(legend.background=element_rect(fill = alpha("white", 0.5)))

alpha("white", 0) being completely transparent like element_blank(), and alpha("white", 1) having no transparency.

Now, for the key - if key and background have different transparencies:

theme(legend.background=element_rect(fill = alpha("white", 0)),
      legend.key=element_rect(fill = alpha("white", .5)))

Note: background transparency overrules the one for the key, i.e. background alpha must be smaller than key alpha.