【问题标题】:ggplot2: making symbols in legend match symbols in plotggplot2:使图例中的符号匹配图中的符号
【发布时间】:2012-12-09 05:35:55
【问题描述】:

我正在尝试绘制一个大多数数据点正常绘制的图,但一组数据点具有不同大小的符号。我希望图例显示相同:大多数点正常显示,但用不同大小的符号绘制的例外。下面是一小段代码:

library(ggplot2)
x = c(1,2,1,2,3)
y = c(1,2,3,4,3)
vendor = c("x", "x", "y", "y", "z")
df = data.frame(x,y,vendor)

p <- ggplot(df) +
     aes_string(x="x", y="y", color="vendor") +
     geom_point(size=3, data=subset(df, vendor!="z")) +
     geom_point(size=5, data=subset(df, vendor=="z"))
ggsave("foo.pdf")

问题在于,在生成的图例中,所有 点都是用较大的 (size=5) 符号绘制的,而不仅仅是带有供应商 z 的那些。我希望供应商 z 用图例中较大的点绘制,而其他供应商用 size=3 绘制。

(奖励问题:我真正想要的是一个更大的粗轮廓符号:我想要一个甜甜圈而不是圆圈。我意识到shape=2 会画一个轮廓圆圈,但它很薄。我宁愿有一个更粗的轮廓圆圈。我想对三角形做同样的事情。有什么简单的方法吗?)

也许我应用错了,但遵循以下建议:

ggplot2: Making changes to symbols in the legend

添加“指南”行没有帮助:

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

即相同的输出,图例中的所有三个供应商都有size=5 符号。

已编辑:很棒的答案,我很快就实现了。现在我添加了几行:

library(ggplot2)
x = c(1,2,1,2,3)
y = c(1,2,3,4,3)
vendor = c("x", "x", "y", "y", "z")
df = data.frame(x,y,vendor)

df$vendor_z <- df$vendor=="z"     # create a new column 

ggplot(df) +
  aes_string(x = "x", y = "y", color = "vendor", size = "vendor_z") +
  geom_point() +
  geom_line(size=1.5) +   # this is the only difference
  scale_size_manual(values = c(3, 5), guide = FALSE) 
  guides(colour = guide_legend(override.aes = list(size = c(3, 3, 5))))

ggsave("foo.pdf")

现在所有点的图例大小又回到了 3,包括供应商 z 的点。有关如何解决此问题的任何想法?

【问题讨论】:

  • 顺便说一句,我是一个完全的 R n00b,所以请随时批评我的代码并帮助我改进它!

标签: r ggplot2 legend


【解决方案1】:

大小不适用于图例,因为sizeaes_string 之外。此外,如果您创建一个额外的列来指示是否为vendor == "z",使用ggplot 会更容易。

这是第 1 部分的解决方案:

df$vendor_z <- df$vendor=="z"     # create a new column 

ggplot(df) +
  aes_string(x = "x", y = "y", color = "vendor", size = "vendor_z") +
  geom_point() +
  scale_size_manual(values = c(3, 5), guide = FALSE) + 
  guides(colour = guide_legend(override.aes = list(size = c(3, 3, 5))))

注意vendor_zaes_string 的参数。这将告诉ggplotsize 特性创建一个图例。在函数scale_size_manual 中,设置了size 的值。此外,guide = FALSE 避免了仅用于size 的第二个图例。最后,size 值应用于color 图例。

第 2 部分:一个“甜甜圈”符号

ggplot 中不能修改圆圈的线条大小。这是一个解决方法:

ggplot(df) +
  aes_string(x = "x", y = "y", color = "vendor", size = "vendor_z") +
  geom_point() +
  geom_point(data = df[df$vendor_z, ], aes(x = x, y = y),
             size = 3, shape = 21, fill = "white", show_guide = FALSE) +
  scale_size_manual(values = c(3, 5), guide = FALSE) + 
  guides(colour = guide_legend(override.aes = list(size = c(3, 3, 5))))

在这里,使用geom_point 和数据子集 (df[df$vendor_z, ]) 绘制单个点。我选择了size3,因为这是较小圆圈的值。 shape 21 是一个可以指定fill 颜色的圆圈。最后,show_guide = FALSE 避免了图例特征被新的shape 覆盖。

编辑:第 3 部分:添加行

您可以使用参数 show_guide = FALSE 隐藏 geom_line 的图例:

ggplot(df) +
  aes_string(x = "x", y = "y", color = "vendor", size = "vendor_z") +
  geom_point() +
  geom_line(size=1.5, show_guide = FALSE) +   # this is the only difference
  scale_size_manual(values = c(3, 5), guide = FALSE) +
  guides(colour = guide_legend(override.aes = list(size = c(3, 3, 5))))

【讨论】:

  • 谢谢斯文!多么棒的答案。我在问题中添加了一些内容,询问如何使用 geom_line 进行这项工作。
  • 在甜甜圈上……有什么方法可以让甜甜圈也出现在图例中?好技巧,在蓝色圆圈上画白色。
  • @jowens 我用一个包括行的解决方案来扩展答案。在图例中为三分之一的符号绘制蓝色圆圈顶部的白色将很困难,并且可能涉及 ggplot 之外的黑客攻击。如果我能找到答案,我会告诉你的。
  • 一个非常周到和友善的回答,并愉快地接受了。如果有人想插话,我想看看:1)我确实关心传说中的台词;在我的完整图表中,我有实线和虚线; 2) 如果我不必硬编码 size=c(3,3,5),它在代码中似乎更通用,因为如果我添加另一个供应商的数据,我必须手动更改它; 3)我在这里真正要做的是表明供应商 z 是供应商 y 的一个例外情况,所以我希望 z 看起来大多像 y 但略有不同,并且不连接到 y 的线路。
  • 如果有人想看看我正在尝试解决的实际问题,我在tinyurl.com/dyhcxh7 发布了一个简短的自述文件,其中包含源代码和生成的图表。
猜你喜欢
  • 2021-01-09
  • 1970-01-01
  • 2013-12-25
  • 2013-10-27
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
相关资源
最近更新 更多