ggplot2可以在一个图例中分别控制点大小和线条大小(线宽)吗?

时间:2014-07-29 02:25:29

标签: r graph ggplot2 legend

使用ggplot2绘制数据点组和连接每个组的均值的数据组的示例,使用aesshape的{​​{1}}进行映射:< / p>

linetype

问题是相对于线符号,图例中的点符号看起来有点太小而无法看到:

p

尝试enlarge point size in legend也会扩大线宽,因此在这里没用。

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))

p1

如果线宽与p1 <- p + guides(shape = guide_legend(override.aes = list(size = 4))) 不同,那就太好了。 我尝试添加

size

只是发出警告。

+ guides(linetype = guide_legend(override.aes = list(size = 1)))

如果我将> Warning message: In guide_merge.legend(init, x[[i]]) : Duplicated override.aes is ignored. linetype移出aes并转移到ggplot(),似乎没有任何区别。如果我只想要点符号,我可以消除图例this way中的线条。

stat_summary()

p2

相反,(在图表中保留小点符号)我希望一个图例与两个大点符号,如同最后一个图像第一张图像中的细线符号。有没有办法做到这一点?

4 个答案:

答案 0 :(得分:8)

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

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)

幻数&#34; 8&#34;是gt$grobs[[8]]$name=="guide-box"所以我知道我在做传奇。我还不是最好的网格图形和gtables,所以也许有人可能会建议一种更优雅的方式。

答案 1 :(得分:3)

使用grid函数grid.force(),ggplot中的所有grob对grid's编辑功能都可见,包括图例键。因此,可以应用grid.gedit,并且可以使用一行代码实现对绘图的所需编辑。此外,我增加了图例键的宽度,以便线段的不同线型清晰。

library(ggplot2)
library(grid)
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)) +
  theme(legend.key.width = unit(1, "cm"))

p

grid.ls(grid.force())    # To get the names of all the grobs in the ggplot

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

enter image description here

保存修改后的情节

  g <- grid.grab()
  ggsave(plot=g, file="test.pdf")

答案 2 :(得分:1)

确保单独图例的一种方法是给它们不同的名称(或其他不同的名称,以防止它们被组合在一起)。

以下是基于您提供的代码的示例:

    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(name="Name 1", values = c(1, 4, 19))+
      scale_linetype_discrete(name="Name2")
    p

答案 3 :(得分:1)

我明白你的意思了。我认为,这是一个适合您所寻找的解决方案。它使两个传说分开,但将它们并排放置。形状的标签和标题被省略,因此最右边的标签对应于形状和线型。

我将此作为单独的答案发布,因为我认为这两种方法对未来的读者都有效。

   p2 <- ggplot(mtcars, aes(gear, mpg, shape = factor(cyl), 
                 linetype = factor(cyl))) + 
     geom_point(size = 2) +
     stat_summary(fun.y = mean, geom = "line", size = 1) +
     # blank labels for the shapes
     scale_shape_manual(name="", values = c(1, 4, 19), 
                        labels=rep("", length(factor(mtcars$cyl))))+
     scale_linetype_discrete(name="Cylinders")+
     # legends arranged horizontally
     theme(legend.box = "horizontal")+
     # ensure that shapes are to the left of the lines
     guides(shape = guide_legend(order = 1), 
            linetype = guide_legend(order = 2))
   p2