如何合并图例与多个 scale_identity (ggplot2)?

How to merge legends with multiple scale_identity (ggplot2)?

我正在尝试绘制一系列线图。单位(姓名)有重复的观察(x,y)。因为在我的真实数据集中,我的单位(~35)多于可行的颜色或形状,所以我想先循环颜色,然后循环形状(即蓝色圆圈、红色圆圈、蓝色三角形、红色三角形等)。

library(tidyverse)

df <- data.frame(name = c('a','a','b','b','c','c'), 
                 x = c(1,5,1,3,3,4), 
                 y = c(1,3,2,1,3,2))

df %>% 
  ggplot(aes(x = x, y = y, color = name, shape = name)) + 
  geom_line() + 
  geom_point() + 
  scale_color_manual(values = c('blue', 'red', 'blue')) + 
  scale_shape_manual(values = c(16,16,17))

为了避免混淆,我希望多个地块的单元具有相同的美感。然而,由于不同的绘图包含不同的单位组合,ggplot2 中的基本缩放方法为绘图中的每个单元分配了不同的美学。例如。在上图中,'c' 是一个蓝色三角形,在下图中,'c' 是一个红色圆圈:

df %>% 
  filter(name %in% c('a','c')) %>% 
  ggplot(aes(x = x, y = y, color = name, shape = name)) + 
  geom_line() + 
  geom_point() + 
  scale_color_manual(values = c('blue', 'red', 'blue')) + 
  scale_shape_manual(values = c(16,16,17))

我知道我可以为每个情节中的每个单元手动定义美学,但这很乏味且容易出错。解决问题的最简单和最安全的方法似乎是使用 scale_identity,我的数据框中的列包含美学价值:

df <- df %>% 
  mutate(colors = c('blue','blue','red','red','blue','blue'), 
         shapes = c(16,16,16,16,17,17))

df %>% 
  ggplot(aes(x = x, y = y, color = colors, shape = shapes, group = name)) + 
  geom_line() + 
  geom_point() + 
  scale_color_identity(guide = 'legend') + 
  scale_shape_identity(guide = 'legend') +
  labs(color = 'name', shape = 'name')

这种方法在各个地块上产生一致的美感,并且可扩展到许多单位。但我希望将传说合并,就像第一个情节一样。具体来说,我想要每个显示 color/shape 交集的单元的键,以及与名称对应的每个键的标签。有办法吗?

我认为 scale_color_manual 是去这里的方式,因为它的多功能性。您对重复性和可维护性的担忧是有道理的,但解决方案是保留一个单独的美学映射数据框:

library(tidyverse)

df <- data.frame(name = c('a','a','b','b','c','c'), 
                 x = c(1,5,1,3,3,4), 
                 y = c(1,3,2,1,3,2))

scale_map <- data.frame(name = c("a", "b", "c"),
                        color = c("blue", "red", "blue"),
                        shape = c(16, 16, 17))

df %>% 
  ggplot(aes(x = x, y = y, color = name, shape = name)) + 
  geom_line() + 
  geom_point(size = 3) + 
  scale_color_manual(values = scale_map$color, labels = scale_map$name,
                     name = "name") + 
  scale_shape_manual(values = scale_map$shape, labels = scale_map$name,
                     name = "name")

reprex package (v2.0.1)

于 2022-04-15 创建

我不确定这个答案,但它似乎带来了所需的输出。请告诉我。


df %>% 
  ggplot(aes(x = x, y = y)) + 
  geom_line(aes(color = name)) + 
  geom_point(aes(shape = name, color = name)) + 
  scale_color_manual(values = c('blue', 'red', 'blue')) + 
  scale_shape_manual(values = c(16,16,17))