Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove the space between legend keys in ggplot2

Tags:

r

legend

ggplot2

NOTE: I have updated this post following discussion with Mike, as my question might be indicative a bug in ggplot. Basically, previously I was able to create a bar plot using ggplot without space between the legend keys (Figure 2 is an example output of that, as is Link 2). Now, however, ggplot seems to be automatically adding space between the legend keys ...

Original post
I would like to create a barplot with a legend. An example of what I am doing would be the following:

b <- c("A","A","A","B","B","B", "A","A","A","B","B","B", "A","A","A","B","B","B")
c <- c(11,22,33,99,88,77, 44,55,66,61,62,63, 83,85, 87, 84,86, 88)

dft <- data.frame(b,c)

ggplot(dft, aes(b,c, fill=b))+
  stat_summary(fun.y=mean, geom="bar", position="dodge", colour="black", size=.2)+
  scale_fill_manual(values=c("grey", "white"))+
  theme(legend.key = element_rect(colour = 'black', size=.01)) 
ggsave("T3.jpg")

The problem I have with this is that ggplot seems to automatically create space in between the two legend keys.

Figure 1

enter image description here

Is there a way to remove this space between the legend keys. See Figure 2 below for an example of what I would like to do.

Figure 2

enter image description here

A similar question has already been asked see Link 1, where the aim was to create more space between the legend keys, but unfortunately none of the answers helped me in resolving my question (i.e., to remove the space between the legend keys).

I also came across a link where the bar plots suggest that it seems to be possible to remove the space between the legend keys: Link 2. When adapting the script to my example, however, exactly the same problem arose (space between legend keys).

How come the bar plots at this link show no space, whereas when I try to replicate this space is added between the legend keys? I should perhaps also add that I have recently updated ggplot. Could this have to do with that?

dft2<-ddply(dft,.(b),plyr::summarize, meanc = mean(c))

ggplot(data=dft2, aes(x=b, y=meanc, fill=b)) + 
   geom_bar(stat="identity",position=position_dodge(), colour="black", size=.3) +
   scale_fill_manual(values=c("grey", "white")) +
   theme(legend.key = element_rect(colour = 'black', size=.01)) 
ggsave("T2.jpg")

Any suggestions for how to resolve this would be most welcome. Btw, adding more space could also be a potential solution for me, but as can be seen by the previous post (Link 1), this may not be easy to implement in ggplot.


Start edit

For the sake of completeness, I am pasting in my original ggplot script that used to generate a legend without space between the legend keys (Figure 2 was created with this script - the bars etc. have been omitted from Figure 2, as this question is concerned with the legend only):

For the summarySE function, see Link 3:

slc <- summarySE(sl, measurevar="EStroop.ART", groupvars=c("Etarget","Econgruency"), na.rm=T)

ggplot(data=slc, aes(x=Etarget, y=EStroop.ART, fill=Econgruency))+ 
  geom_bar()+
  geom_bar(stat="identity", position=position_dodge(), colour="black",     show_guide=FALSE, size=0.15)+
  geom_errorbar(aes(ymin=EStroop.ART-ci, ymax=EStroop.ART+ci),
                width=0.2, # Width of the error bars
                position=position_dodge(.9), size=0.15)+
  labs(x="Target", y="Adjusted Reaction Time (milliseconds)")+ #set other    titles 
  scale_fill_manual(values=c("grey", "white"))+
  theme(axis.title.x = element_text(face="bold", vjust=0.1, size =6),
        axis.title.y = element_text(face="bold", vjust=1.0, size =6),
        axis.text.x = element_text(size = 5, colour="black"),
        axis.text.y = element_text(size = 5, colour="black"),
        legend.key = element_rect(colour = 'black', size=.2), # to change border of the legend box
        legend.text=element_text(size = 4),
        legend.title=element_blank(),
        panel.grid.major = element_line(size=.20),
        panel.grid.minor = element_line(size=.1),
        axis.ticks=element_line(size=.2),
        axis.line=element_line(colour="black", size=0.15),
        legend.key.size = unit(.3, "cm"))+ # size of legend box
  coord_cartesian(ylim=c(500,700)) # to "zoom" in on the graph 
ggsave("ES_cong.tiff", width=86, height=60, units='mm', dpi=1200)  

End edit

like image 742
Tiberius Avatar asked Jan 07 '16 13:01

Tiberius


People also ask

How do I change the legend text in ggplot2?

You can use the following syntax to change the legend labels in ggplot2: p + scale_fill_discrete(labels=c('label1', 'label2', 'label3', ...))

How do I get rid of the legend in ggplot2?

Example 1: Remove All Legends in ggplot2 We simply had to specify legend. position = “none” within the theme options to get rid of both legends.

How do I change the size of a legend key in R?

To change the Size of Legend, we have to add guides() and guide_legend() functions to the geom_point() function. Inside guides() function, we take parameter color, which calls guide_legend() guide function as value. Inside guide_legend() function, we take an argument called override.


1 Answers

This can be resolved with the rectangle_key_glyph() function from the cowplot package. It has an option to set the exact padding you want, which can be positive or negative.

By default, there is no gap. This causes the two lines around the boxes to be drawn side-by-side, which means they appear thicker. This may not be what you want.

library(ggplot2)
library(cowplot)

b <- c(
  "A", "A", "A", "B", "B", "B", "A", "A", "A",
  "B", "B", "B", "A", "A", "A", "B", "B", "B"
)
c <- c(
  11, 22, 33, 99, 88, 77, 44, 55, 66,
  61, 62, 63, 83, 85, 87, 84, 86, 88
)

dft <- data.frame(b, c)

ggplot(dft, aes(b, c, fill = b))+
  stat_summary(
    fun = mean, geom = "bar", position = "dodge", 
    colour = "black", size = 0.2,
    key_glyph = rectangle_key_glyph(
      colour = "black"
    )
  ) +
  scale_fill_manual(values = c("grey", "white")) +
  theme(legend.key = element_blank()) 

My preferred solution is to make the gap bigger, so it's clearly there.

ggplot(dft, aes(b, c, fill = b))+
  stat_summary(
    fun = mean, geom = "bar", position = "dodge", 
    colour = "black", size = 0.2,
    key_glyph = rectangle_key_glyph(
      colour = "black",
      padding = margin(3, 3, 3, 3)
    )
  ) +
  scale_fill_manual(values = c("grey", "white")) +
  theme(legend.key = element_blank())

But you can also use negative padding to have the lines lie exactly on top of each other in the middle. Here done with size = 2 to exaggerate the effect.

ggplot(dft, aes(b, c, fill = b))+
  stat_summary(
    fun = mean, geom = "bar", position = "dodge", 
    colour = "black", size = 2,
    key_glyph = rectangle_key_glyph(
      colour = "black",
      padding = margin(-2, -2, -2, -2)
    )
  ) +
  scale_fill_manual(values = c("grey", "white")) +
  theme(legend.key = element_blank())

Note that in all these cases, I've set legend.key = element_blank(). We don't want anything to be drawn underneath our legend key. This is particularly important when you use a positive padding.

like image 133
Claus Wilke Avatar answered Sep 18 '22 09:09

Claus Wilke