Can ggplot2 control point size and line size (lineweight) separately in one legend?

ggplot2, graph, legend, r

Solution

It sure does seem to be difficult to set those properties independently. I was only kind of able to come up with a hack. If your real data is much different it will likely have to be adjusted. But what i did was used the `override.aes` to set the size of the point. Then I went in and built the plot, and then manually changed the line width settings in the actual low-level grid objects. Here's the code

pp<-ggplot(mtcars, aes(gear, mpg, shape = factor(cyl), linetype = factor(cyl))) + 
  geom_point(size = 3) +
  stat_summary(fun.y = mean, geom = "line", size = 1) +
  scale_shape_manual(values = c(1, 4, 19)) +
  guides(shape=guide_legend(override.aes=list(size=5)))

build <- ggplot_build(pp)
gt <- ggplot_gtable(build)

segs <- grepl("geom_path.segments", sapply(gt$grobs[[8]][[1]][[1]]$grobs, '[[', "name"))
gt$grobs[[8]][[1]][[1]]$grobs[segs]<-lapply(gt$grobs[[8]][[1]][[1]]$grobs[segs], 
    function(x) {x$gp$lwd<-2; x})
grid.draw(gt)

The magic number "8" was where `gt$grobs[[8]]$name=="guide-box"` so i knew I was working the legend. I'm not the best with grid graphics and gtables yet, so perhaps someone might be able to suggest a more elegant way.

Problem

An example using `ggplot2` to graph groups of data points and lines connecting the means for each group, mapped with the same `aes` for `shape` and for `linetype`: ``` p <- ggplot(mtcars, aes(gear, mpg, shape = factor(cyl), linetype = factor(cyl))) + geom_point(size = 2) + stat_summary(fun.y = mean, geom = "line", size = 1) + scale_shape_manual(values = c(1, 4, 19)) ``` Problem is that point symbols in the legend appear a bit too small to see, relative to the line symbols: Trying to enlarge point size in legend also enlarges lineweight, so that is not useful here. ``` p1 <- p + guides(shape = guide_legend(override.aes = list(size = 4))) ``` It would be nice if lineweight were a distinct aesthetic from `size`. I tried adding ``` + guides(linetype = guide_legend(override.aes = list(size = 1))) ``` which just gives a warning. ``` > Warning message: In guide_merge.legend(init, x[[i]]) : Duplicated override.aes is ignored. ``` It seems to make no difference either if I move the `linetype` `aes` out of `ggplot()` and into `stat_summary()`. If I wanted only the point symbols, I could eliminate lines from the legend this way. ``` p2 <- p + guides(shape = guide_legend(override.aes = list(size = 4, linetype = 0))) ``` Instead, (keeping small point symbols in the graph itself) I want one single legend with both big point symbols as in this last image and thin line symbols as in the first image. Is there a way to do this?

Original source

Related problems