96

How should I change the size of symbols in legends? I checked the document of theme but found no answer.

Here is an example:

library(ggplot2);library(grid)
set.seed(1000)
x <- 1:6
mu <- sin(x)
observed <- mu + rnorm(length(x), 0, 0.5*sd(mu))
data <- data.frame(
  t=rep(x, 2), 
  value=c(mu, observed) - min(mu, observed) + 0.5, 
  class = rep(c("mu", "observed"), each=length(x)))
mu <- data$value[1:length(x)]
observed <- data$value[1:length(x) + length(x)]
mu.min <- mu - 3 * 0.5 * sd(mu)
mu.max <- mu + 3 * 0.5 * sd(mu)
g <- ggplot(data=data)
g <- g + geom_point(aes(x=value, y=t, shape=class, size=24)) + scale_size(guide="none")
g <- g + scale_shape(name="", labels=expression(paste(S[u](t), ", the observation at time ", t), paste(mu[u](t), ", the mean of ", tilde(S)[u](t), "          ")))
stat_function.color <- gray(0.5)
g <- g + geom_segment(aes(y=1:6, yend=1:6, x=mu.min, xend=mu.max, linetype="2", alpha = 1), color=stat_function.color) + scale_alpha(guide="none") + scale_linetype(name= "", labels=expression(paste("probability density function (pdf) of ", tilde(S)[u], " at time ", t)))
for(i in 1:length(x)) {
  g <- g + stat_function(fun=function(x, i) {
    ifelse( x <= mu.max[i] & x >= mu.min[i], dnorm(x, mu[i], sd(mu)) + i, NA)
    }, color=stat_function.color, args=list(i=i))
}
background.color <- gray(0.75)
g <- g + theme(
  axis.text=element_blank(),
  title=element_text(size=rel(1.5)),
  legend.text=element_text(size=rel(1.5)),
  legend.position="top",
  legend.direction="vertical",
#   legend.key.size = unit(2, "cm"),
  panel.background=element_rect(fill=background.color), 
  panel.grid.major=element_line(color=background.color),
  panel.grid.minor=element_line(color=background.color)
  ) + coord_flip()
plot(g)
Richard Erickson
  • 2,568
  • 8
  • 26
  • 39
wush978
  • 3,114
  • 2
  • 19
  • 23
  • 2
    see http://stackoverflow.com/questions/16356052/control-ggplot2-legend-look-without-affecting-the-plot – PatrickT Dec 23 '14 at 12:05

5 Answers5

114

You should use:

theme(legend.key.size = unit(3,"line"))
Jaap
  • 81,064
  • 34
  • 182
  • 193
Duc_Hokie2017
  • 1,189
  • 1
  • 7
  • 2
  • 5
    IMHO that is the more appropriate answer since it uses `theme` which was mentioned in the question. – Josef Eisl Feb 16 '17 at 18:04
  • 52
    This code increases the area around the symbol, not the symbol itself. The guides code is more appropriate. – LListhewaytobe Aug 18 '17 at 20:22
  • 1
    I couldn't make it work for small values, e.g. ``unit(0.1, "line")`` – PatrickT Jun 01 '18 at 15:24
  • 8
    but this is the code that actually achieves what most of us probably came to this page looking to do... – theforestecologist Jun 17 '18 at 17:28
  • 3
    This worked for me. Whereas, the accepted answer did not. – jdmartin86 Jan 04 '19 at 13:19
  • For some reason I can increase its size with `legend.key.size` but I can't find a way to decrease the squared figures' sizes smaller than default, using `theme()` – Bernardo Oct 31 '19 at 15:24
  • neither solution alone worked for me, but both together worked. reason: increasing guide size hides line type, so I also needed to increase the area around the symbol. – mkln Dec 02 '21 at 18:35
  • 1
    Note: In trying to reduce the size of the legend key, I discovered two things. 1) `legend.key.size` changes the X and Y dimensions of they key together. If you want a rectangle, not a square you need to use `legend.key.height` and `legend.key.width`. 2) if you set `legend.key.size` smaller than the font size, it appears to set the height to the font size and the width to whatever you set. @PatrickT if you want something smaller than 1 line, try `unit(1, "pt")` instead. – ESELIA Feb 07 '22 at 15:07
103

You can make these kinds of changes manually using the override.aes argument to guide_legend():

g <- g + guides(shape = guide_legend(override.aes = list(size = 5)))
print(g)
Jaap
  • 81,064
  • 34
  • 182
  • 193
Marius
  • 58,213
  • 16
  • 107
  • 105
  • @Ibo: are you sure? Your example code looks like it would work if you had a color scale in the legend, my example was for a shape scale, like in the original question. AFAIK this still works if you have a shape scale that you are modifying. At this point I would prefer Duc_Hokie's suggestion to use the theme options, however. – Marius Jul 18 '18 at 23:23
57

Marius's answer did not work for me as of R version 3.2.2. You can still call guide_legend() with the same override.aes argument but you will need to specify color instead of shape in the wrapper function.

So if you're running a later version of R, try this instead:

g + guides(color = guide_legend(override.aes = list(size=5)))

EDIT

As pointed out by @Ibo in the comment, this may have been due to the color scale in the ggplot object. If the ggplot object contains a color scale, the mapping of size (size=5) has to be set on the color instead.

Matteo
  • 2,774
  • 1
  • 6
  • 22
onlyphantom
  • 8,606
  • 4
  • 44
  • 58
  • 6
    I think the reason it did not work for you was because you had a color scale in your plot and not a shape scale. Marius's answer changes the size of the shapes in a legend for shape. Your line of code changes the size of shape of the legend for a color scale – Ibo Jul 19 '18 at 00:38
12

If you want to change the sizes of 2 components of a legend independently, it gets trickier, but it can be done by manually editing the individual components of the plot using the grid package.

Example based on this SO answer:

set.seed(1)
dat <- data.frame(x = runif(n = 100),
                  x2 = factor(rep(c('first', 'second'), each = 50)))
set.seed(1)
dat$y = 5 + 1.8 * as.numeric(dat$x2) + .3 * dat$x + rnorm(100)

# basic plot
g <- ggplot(data = dat,
       aes(x = x, y = y, color = x2))+
   theme_bw()+
   geom_point()+
   geom_smooth(method = 'lm')

enter image description here

# make the size of the points & lines in the legend larger
g + guides(color = guide_legend(override.aes = list(size = 2)))

enter image description here

# Make JUST the legend points larger without changing the size of the legend lines:
# To get a list of the names of all the grobs in the ggplot
g
grid::grid.ls(grid::grid.force())

# Set the size of the point in the legend to 2 mm
grid::grid.gedit("key-[-0-9]-1-1", size = unit(4, "mm"))

# save the modified plot to an object
g2 <- grid::grid.grab()
ggsave(g2, filename = 'g2.png')

enter image description here

filups21
  • 1,611
  • 1
  • 19
  • 22
8

As of 12/1/2022, in ggplot2 version 3.4.0, the argument:

guides(shape = guide_legend(override.aes = list(size = 5)))

no longer works....instead, replace "size = 5" with "linewidth = 5"

Andrew
  • 99
  • 1
  • 4
  • It's true, it does not work anymore and I was confused why running some old script led to smaller legend symbols. Many thanks. – Alireza Amani Dec 11 '22 at 16:23
  • size has been deprecated to linewidth in geom_line(). It still works in geom_line but wont generate desired result in legend argument as pointed out by Andrew. See https://www.tidyverse.org/blog/2022/08/ggplot2-3-4-0-size-to-linewidth/ – Dan Tarr Mar 16 '23 at 19:27