如何在 ggplots 中保持配色方案,同时删除每个图中未使用的级别?

How can I maintain a color scheme across ggplots, while dropping unused levels in each plot?

我想比较一个图中的一些 sub-groups 数据和另一个图中的一些 sub-groups 数据。如果我用所有 sub-groups 绘制一个图,这个数字是压倒性的,每个单独的比较都变得困难。我认为如果给定的子组在所有图中的颜色都相同,那么 reader 会更有意义。

这里有两件我试过的东西,它们几乎都能奏效,但都不太奏效。他们离 MWE 已经很近了!

错误,因为图例中显示了所有三个级别

library(tidyverse)

# compare first and second species
ggplot(data = iris %>% filter(Species != 'virginica'),
       mapping = aes(x = Sepal.Length,
                     y = Sepal.Width,
                     color = Species)) +
  geom_point() +
  scale_color_discrete(drop = FALSE)


# compare second and third species
ggplot(data = iris %>% filter(Species != 'setosa'),
       mapping = aes(x = Sepal.Length,
                     y = Sepal.Width,
                     color = Species)) +
  geom_point() +
  scale_color_discrete(drop = FALSE)

请注意,un-plotted级别仍然出现在图例中(与 drop = FALSE 的想法一致)。

错误,因为第二个图没有保持第一个图

建立的species-color映射
# compare first and second species
ggplot(data = iris %>% filter(Species != 'virginica'),
       mapping = aes(x = Sepal.Length,
                     y = Sepal.Width,
                     color = Species)) +
  geom_point() +
  scale_color_manual(values = c('red', 'forestgreen', 'blue'),
                     breaks = unique(iris$Species))


# compare second and third species
ggplot(data = iris %>% filter(Species != 'setosa'),
       mapping = aes(x = Sepal.Length,
                     y = Sepal.Width,
                     color = Species)) +
  geom_point() +
  scale_color_manual(values = c('red', 'forestgreen', 'blue'),
                     breaks = unique(iris$Species))

请注意,在左图中 setosa = 红色和 virginica = 绿色,但在右图中映射发生了变化。

最有效的方法是为每个级别(物种)设置一个命名的颜色变量,并在每个图中使用它。

在这里,您可以使用与上面相同的颜色,但通过向变量添加名称,可以确保它们始终正确匹配:

irisColors <-
  setNames( c('red', 'forestgreen', 'blue')
            , levels(iris$Species)  )

给予

setosa     versicolor     virginica 
 "red"  "forestgreen"        "blue"

然后您可以使用它来设置颜色:

首先是所有颜色:

ggplot(data = iris,
       mapping = aes(x = Sepal.Length,
                     y = Sepal.Width,
                     color = Species)) +
  geom_point() +
  scale_color_manual(values = irisColors)

那么你问题的每个子集:

ggplot(data = iris %>% filter(Species != 'virginica'),
       mapping = aes(x = Sepal.Length,
                     y = Sepal.Width,
                     color = Species)) +
  geom_point() +
  scale_color_manual(values = irisColors)

ggplot(data = iris %>% filter(Species != 'setosa'),
       mapping = aes(x = Sepal.Length,
                     y = Sepal.Width,
                     color = Species)) +
  geom_point() +
  scale_color_manual(values = irisColors)