可以强制非出现元素显示在 ggplot 图例中吗?

uhC*_*lem 6 r legend heatmap ggplot2

我正在绘制一个研究区域内最多三种可选物种丰度的叶绿素。这个玩具代码的行为符合预期,几乎达到了我想要的效果:

library(dplyr)
library(ggplot2)
square <- expand.grid(X=0:10, Y=0:10)
sq2 <- square[rep(row.names(square), 2),] %>%
  arrange(X,Y) %>%
  mutate(SPEC = rep(c('red','blue'),len=n())) %>%
  mutate(POP = ifelse(SPEC %in% 'red', X, Y)) %>%
  group_by(X,Y) %>% 
  mutate(CLR = rgb(X/10,0,Y/10)) %>% ungroup()

ggplot(sq2, aes(x=X, y=Y, fill=CLR)) + geom_tile() +
  scale_fill_identity("Species", guide="legend",
    labels=c('red','blue'), breaks=c('#FF0000','#0000FF'))
Run Code Online (Sandbox Code Playgroud)

产生这个:

X=红色; Y=蓝色; 绘制为渐变平铺

修改后的版本正确绘制了真实地图,适当混合 RGB 以显示每个地图单元的物种比例。但考虑到这种混合,真实数据不一定包括 中列出的具体值breaks,在这种情况下,该物种的图例中不会出现任何条目。如果将示例的最后一行更改为

labels=c('red','blue','green'), breaks=c('#FF0000','#0000FF','#00FF00'))
Run Code Online (Sandbox Code Playgroud)

您会得到与所示相同的图例,仅显示“红色”和“蓝色”,因为其中没有绿色。搜索每个最大值(物种)的数据并将其分配给图例是可能的,但不会为仅以低比例出现的物种提供良好的图例键。图例需要显示存在的实体的概念,而不是它们被证明的存在——图例中的三种颜色,即使只检测到一种物种。

我认为这个scale_fill_manual()override.aes论证可能对我有帮助,但我无法使任何组合发挥作用。

编辑:
第四集——新的死胡同

(感谢 @r2evans 修复了我遗漏的包。)我想我也许可以通过将另一列突变到处理管道中的 df 中来欺骗图例,spCLR该管道被称为代表每个代码的颜色(“#FF0000”,例如)条目的物种(冗余信息,但很好)。现在我的真实版本中的绘图调用如下:

df %>% [everything] %>%
    ggplot(aes(x = X, y = Y, height = WIDTH, width = WIDTH, fill = CLR)) +
      geom_tile() +
      scale_fill_identity("Species", guide="legend",
        labels=spCODE, breaks=spCLR)
Run Code Online (Sandbox Code Playgroud)

但这给出了错误:Error in check_breaks_labels(breaks, labels) : object 'spCLR' not found这看起来很奇怪,因为spCLR确实在管道修改的 df 中,并且提供给 ggplot 函数的所有值中spCODE是原始 df 中唯一存在的值 - 所以如果存在某种范围问题,我不明白。[重新编辑——我发现标签和中断都不想查看 df$anything。反正。]

我假设(正确吗?)有某种方法可以使这个工作[?],但它仍然不会使图例在我的玩具示例中显示“红色”,“蓝色”和“绿色” - 这是我原来的问题实际上是——因为其中仍然没有实际的绿色数据。因此,重申一下,是否有任何方法可以强制 ggplot2 图例显示您想要讨论的内容,而不仅仅是数据中存在的内容?

uhC*_*lem 4

我后来发现我的问题几乎与此重复。那里接受的答案(来自@joran)不适用于此,但第二个答案(来自@Axeman)则适用。所以我去这里的方法是最后一行应该是

labels=c('red','blue','green'), limits=c('#FF0000','#0000FF','#00FF00'))
Run Code Online (Sandbox Code Playgroud)

调用limits()而不是breaks(),现在我的示例和我的真实版本可以按需要工作。

我不得不说,我花了很多时间在 ggplot2参考资料中进行挖掘,但从未怀疑过 limit() 是 Breaks() 的正确替代方案——在参考页面中明确提到了这一点,而 limit() 没有出现。?limits() 页面信息很少,我找不到任何可以说明两者之间区别的内容:当这个而不是那个。