ggplot2 可以在一个图例中分别控制点大小和线条大小(线宽)吗? [英] Can ggplot2 control point size and line size (lineweight) separately in one legend?

查看:19
本文介绍了ggplot2 可以在一个图例中分别控制点大小和线条大小(线宽)吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个使用 ggplot2 绘制数据点组和连接每个组均值的线的示例,使用相同的 aes 映射 shape对于 linetype:

p <- ggplot(mtcars, aes(gear, mpg, shape = factor(cyl), linetype = factor(cyl))) +geom_point(大小 = 2) +stat_summary(fun.y = mean, geom = "line", size = 1) +scale_shape_manual(values = c(1, 4, 19))

问题是图例中的点符号相对于线符号显得太小而无法看到:

尝试.

p2 <- p + guides(shape = guide_legend(override.aes = list(size = 4, linetype = 0)))

相反,(在图形本身中保留小点符号)我想要一个图例,带有两个大点符号,如最后一张图像em> 细线符号,如第一张图片所示.有没有办法做到这一点?

解决方案

独立设置这些属性似乎确实很困难.我只能想出一个技巧.如果您的实际数据有很大不同,则可能需要进行调整.但是我所做的是使用 override.aes 来设置点的大小.然后我进入并构建绘图,然后手动更改实际低级网格对象中的线宽设置.这是代码

pp<-ggplot(mtcars, aes(gear, mpg, shape = factor(cyl), linetype = factor(cyl))) +geom_point(大小 = 3) +stat_summary(fun.y = mean, geom = "line", size = 1) +scale_shape_manual(values = c(1, 4, 19)) +指南(形状=guide_legend(覆盖.aes=列表(大小=5)))构建 <- 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]],函数(x){x$gp$lwd<-2;X})grid.draw(gt)

神奇数字8"是 gt$grobs[[8]]$name=="guide-box" 所以我知道我正在处理这个传奇.我在网格图形和 gtables 方面还不是最好的,所以也许有人可以提出更优雅的方法.

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?

解决方案

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.

这篇关于ggplot2 可以在一个图例中分别控制点大小和线条大小(线宽)吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆