Space between gpplot2 horizontal legend elements

It really seems something like theme(legend.text = element_text(margin = margin(r = 2, unit = 'in'))) would be the right way to accomplish the task, but that doesn't do anything at all.

Instead, (and not for the first time) I fall back on the Microsoft Word style of alignment-hacking, i.e. just add spaces:

ggplot(mtcars, aes(factor(cyl), fill=factor(paste(cyl, '                    ')))) + 
    geom_bar() +
    coord_flip() +
    theme(legend.position = 'top') +
    guides(fill = guide_legend(title=NULL))

plot with spaced legend

Because there's spaces on the 8 as well, it's a little off-center, but if you just paste them onto the previous labels you can nudge them around as you like.

Apologies for any nightmares caused to graphic designers.


This is a hack, but...

Let's add some empty factor levels in cyl between the real levels. Then we'll make sure they're included in the plot (using drop=FALSE) for spacing in the legend, but will set their colors and labels to empty values so that you can't see them in the legend. I found that I also needed to include override.aes=list(color="white") in order to avoid the blank legend key boxes still being ever-so-slightly visible in the legend.

mtcars$cyl = factor(mtcars$cyl, levels=c(4, 11:15, 6, 16:20, 8))
cols = hcl(seq(15,375,length.out=4)[1:3], 100, 65)

ggplot(mtcars, aes(cyl, fill=cyl)) + 
  geom_bar() +
  coord_flip() +
  scale_fill_manual(values=c(cols[1], rep("white",5), cols[2], rep("white",5), cols[3]), 
                    labels=c(4, rep("",5), 6, rep("",5), 8), drop=FALSE) +
  theme(legend.position = 'top') +
  guides(fill = guide_legend(title=NULL, nrow=1, override.aes=list(color="white"))) 

enter image description here


This is another hack but one that I prefer, as it adds additional white space at the end of each label according to its number of characters. Replace fill = factor(cyl) with

fill = sprintf("%-20s", factor(cyl)).

This pads all strings in the vector with white characters on the right to reach 20 characters total. This is perfect if you have text labels of different lengths. You can change 20 to whatever number you want, or remove the negative sign to add spaces to the left instead of the right. In general sprintf() is a good function to explore and use for formatting text and numbers as desired.


The issue mentioned by alistaire and Tyler Rinker was solved. Now we can adjust the margins of the element_text`.

ggplot(mtcars, aes(factor(cyl), fill = factor(cyl))) +
  geom_bar() +
  coord_flip() +
  theme(
    legend.position = 'top',
    legend.title = element_blank(),
    legend.text = element_text(margin = margin(r = 2, unit = 'cm'))
  )

enter image description here

Tags:

R

Ggplot2