【问题标题】:ggplot custom legend instead of defaultggplot 自定义图例而不是默认图例
【发布时间】:2020-07-28 14:54:37
【问题描述】:

我已经搜索并尝试了一堆建议,以便能够在分组散点图 ggplot 中显示自定义图例而不是默认图例。我试过thisthis 并关注this 等等。

例如,假设我有一个像这样的df

df = data.frame(id = c("A", "A", "B", "C", "C", "C"), 
                value = c(1,2,1,2,3,4), 
                ref = c(1.5, 1.5, 1, 2,2,2), 
                min = c(0.5, 0.5, 1,2,2,2))

我想将每个idvalues 显示为圆点,但也将每个idreference 值和minimum 值显示为不同形状的点,如下所示:

p = ggplot(data = df) +
  geom_point(aes(x = id, y = value, color = factor(id)), shape = 19, size = 6) +
  geom_point(aes(x = id, y = ref, color = factor(id)), shape = 0, size = 8) +
  geom_point(aes(x = id, y = min, color = factor(id)), shape = 2, size = 8) +
  xlab("") +
  ylab("Value")
#print(p) 

现在一切都很好,但我的图例并没有为情节的解释添加任何内容,因为 X 轴和颜色足以理解它。我知道我可以通过theme(legend.position = "none") 删除图例。 相反,我想说明每个点的实际 形状 代表什么(例如,实心圆点 = value、三角形 = min、正方形 = ref)。

尝试通过scale_fill_manual 手动设置比例值以及类似的东西

override.shape = shapes$shape
override.linetype = shapes$pch
guides(colour = guide_legend(override.aes = list(shape = override.shape, linetype = override.linetype)))...
....

我也尝试使用上面粘贴的链接之一中建议的内容制作辅助图,但不显示它:

shapes  = data.frame(shape = c("value", "reference", "minimum"), pch = c(19,0,2), col = c("gray", "gray", "gray"))
p2 = ggplot(shapes, aes(shape, pch)) + geom_point()  
#print(p2)

g_legend <- function(a.gplot){
  tmp <- ggplot_gtable(ggplot_build(a.gplot))
  leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
  legend <- tmp$grobs[[leg]]
  return(legend)
}
legend <- g_legend(p2)
library(gridExtra)
pp <- arrangeGrob(p1 ,legend,
                  widths=c(5/4, 1/4),
                  ncol = 2)

然后我得到错误:

> legend <- g_legend(p2)
Error in tmp$grobs[[leg]] : 
  attempt to select less than one element in get1index

我没有找到一个可行的解决方案.. 所以是的.. 任何关于我如何只能显示与不同点形状相关的图例的建议都将受到欢迎。 谢谢

【问题讨论】:

  • 只需将形状和大小添加到您正在映射的美学中,以及颜色。还是我错过了更复杂的东西?
  • 感谢您的评论。添加形状geom_point(aes(x = id, y = value, color = factor(id), shape = 19), size = 6)(大小在此上下文中并不重要)会导致此错误:Error: A continuous variable can not be mapped to shape。如果它有所作为,形状不是数据框的一部分,但也许我应该在那里添加它!?
  • 您需要将其映射到某个变量,例如区分第一个 geom_point 调用和第二个调用的任何变量。但这指向了一个更大的问题,即 ggplot 通常用于长形数据,在这种数据中,您不会重复调用相同的几何图形来更改某些视觉元素。也许看看几个教程,看看如何重塑数据
  • 嗯,这就是为什么我试图创建一个不同的图而不显示它,只是为了从更简单的 df 生成图例。因为这三组点(值、参考、最小值)来自 df 中的三个不同列。嗯是的。以为我可以禁用“默认”图例并“缝合”一个新图例:/
  • 它们位于不同列的事实是您想要重塑数据的原因,因此有一列值和一列表示它们的含义(值、参考或最小值)。这是一个例子datascience.stackexchange.com/q/66590/50633

标签: r ggplot2 customization legend


【解决方案1】:

您可以使用scale_shape_manual 手动构建形状图例:

library(ggplot2)

ggplot(data = df) +
  geom_point(aes(x = id, y = value, color = factor(id), shape = 'value'), size = 6) +
  geom_point(aes(x = id, y = ref, color = factor(id), shape = 'ref'), size = 8) +
  geom_point(aes(x = id, y = min, color = factor(id), shape = 'min'), size = 8) +
  scale_shape_manual(values = c('value' = 19, 'ref' = 0, 'min' = 2)) +
  xlab("") +
  ylab("Value")

reprex package (v0.3.0) 于 2020-04-15 创建

但更好的方法是将df 重塑为长格式,并将每个aes 映射到一个变量:

library(dplyr)
library(tidyr)

df %>% 
  pivot_longer(-id) %>% 
  ggplot() +
  geom_point(aes(x = id, y = value, color = factor(id), shape = name, size = name)) +
  scale_shape_manual(values = c('value' = 19, 'ref' = 0, 'min' = 2)) +
  scale_size_manual(values = c('value' = 6, 'ref' = 8, 'min' = 8)) + 
  xlab("") +
  ylab("Value")

reprex package (v0.3.0) 于 2020-04-15 创建

要删除颜色的图例,请使用guide_none()

library(tidyr)
library(ggplot2)
df %>% 
  pivot_longer(-id) %>% 
  ggplot() +
  geom_point(aes(x = id, y = value, color = factor(id), shape = name, size = name)) +
  scale_shape_manual(values = c('value' = 19, 'ref' = 0, 'min' = 2)) +
  scale_size_manual(values = c('value' = 6, 'ref' = 8, 'min' = 8)) + 
  guides(color = guide_none()) +
  xlab("") +
  ylab("Value")

reprex package (v0.3.0) 于 2020-04-16 创建

数据:

df = data.frame(id = c("A", "A", "B", "C", "C", "C"), 
                value = c(1,2,1,2,3,4), 
                ref = c(1.5, 1.5, 1, 2,2,2), 
                min = c(0.5, 0.5, 1,2,2,2))

【讨论】:

  • 感谢您的建议。会试一试,然后回来找你。我坚持拥有所有不同颜色的“默认”图例,并且只保留一个形状
  • 我已经尝试了您的第一个建议,但从未显示“形状”图例。也许绘图区域没有足够的地方。我的数据有十多个不同的ids,所以也许这就是原因:/
  • 有没有办法删除第一个图例,只保留手动创建的图例?我正在尝试按照建议重塑数据,但是当我在真实数据上运行时进入Error: No common type for 'name' &lt;character&gt; and 'value' &lt;double&gt;,而this 没有修复它。
  • 已编辑删除颜色指南的说明。为了解决重塑问题,我们需要您的真实数据(我想您共享的数据只是一个玩具示例)如果您无法解决,我建议您打开一个新问题
  • 是的,这是一个玩具示例。由于保密原因无法共享真实数据,但会尝试对其进行修复和重塑。如果不是,正如您所建议的,我将为此单独提出一个新问题。感谢您的快速反馈。我认为这个答案是 DA 一个 :] 再次感谢!
【解决方案2】:

你可以先使用tidyr整理你的数据,然后将aes shape映射到新变量

library(tidyr)
df2 <- pivot_longer(df, -id)

ggplot(data = df2) +
  geom_point(aes(x = id, y = value, shape = name), size = 6) +
  xlab("") +
  ylab("Value")

【讨论】:

  • +1 因为你的方法有效,但我选择了另一个答案是为了完整性,因为它实际上解决了问题的 custom 图例部分,而不仅仅是重塑数据。谢谢你的时间
猜你喜欢
  • 2021-02-02
  • 2014-08-26
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 2021-08-14
  • 2018-09-15
  • 1970-01-01
相关资源
最近更新 更多