我正在绘制整个研究区域中多达三种可选物种丰度的叶绿素。此玩具代码的行为符合预期,并且几乎满足我的要求:
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'))
产生这个:
修改后的版本会正确绘制真实地图,并适当地混合RGB以显示每个地图单位的物种比例。但是考虑到混合,实际数据不一定包含breaks
中列出的特定值,在这种情况下,该物种的图例中不会出现任何条目。如果您将示例的最后一行更改为
labels=c('red','blue','green'), breaks=c('#FF0000','#0000FF','#00FF00'))
您将获得与所示相同的图例,仅显示“红色”和“蓝色”,因为其中没有绿色。可以搜索每个max(Species)的数据并将其分配给图例,但是对于仅以低比例出现的物种而言,这并不是很好的图例关键字。对于图例来说,需要的是显示存在实体的 idea ,而不是它们经证实的存在-即使只检测到一种物种,图例中也要显示三种颜色。
我认为scale_fill_manual()
或override.aes
的论点可能对我有帮助,但我无法进行任何组合。
编辑:
第四集-新的死角
(感谢@ r2evans修复我遗漏的软件包。)
我以为我可以通过在处理管道中将另外的列突变为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)
但这会产生错误:Error in check_breaks_labels(breaks, labels) : object 'spCLR' not found
。 这似乎很奇怪,因为 [重新编辑-我看到标签和中断都不希望查看df $任何东西。无论如何。] spCLR
实际上在管道修改的df中,并且在提供给ggplot函数的所有值中,spCODE
是原始df中唯一的一个值-因此,如果存在
我认为(正确吗?)有某种方法可以使这一功能生效[?],但仍然无法使图例在其中显示“红色”,“蓝色”和“绿色”我的玩具示例(这是我最初的问题的实质所在),因为其中仍然没有实际的绿色数据。因此,重申一下,有没有办法强迫ggplot2图例显示您要谈论的内容,而不仅仅是显示数据中存在的内容?
答案 0 :(得分:1)
我从热图用例假设,您在图表中不需要其他颜色映射。在这种情况下,可能的解决方法是不使用填充比例,并使用颜色美学映射创建不可见的geom图层,以生成所需的图例:
ggplot(sq2, aes(x=X, y=Y)) +
geom_tile(aes(fill = CLR)) + # move fill mapping here so new point layer doesn't inherit it
scale_fill_identity() + # scale_*_identity has guide set to FALSE by default
# add invisible layer with colour (not fill) mapping, within x/y coordinates within
# same range as geom_tile layer above
geom_point(data = . %>%
slice(1:3) %>%
# optional: list colours in the desired label order
mutate(col = forcats::fct_inorder(c("red", "blue", "green"))),
aes(colour = col),
alpha = 0) +
# add colour scale with alpha set to 1 (overriding alpha = 0 above),
# also make the shape square & larger to mimic the default legend keys
# associated with fill scale
scale_color_manual(name = "Species",
values = c("red" = '#FF0000', "blue" = '#0000FF', "green" = '#00FF00'),
guide = guide_legend(override.aes = list(alpha = 1, shape = 15, size = 5)))
答案 1 :(得分:0)
我后来发现我的问题与this几乎是重复的。那里接受的答案(来自@joran)对此不起作用,但是第二个答案(来自@Axeman)起作用。所以我要走的路是最后一行应该是
labels=c('red','blue','green'), limits=c('#FF0000','#0000FF','#00FF00'))
调用limits()
而不是breaks()
,现在我的示例和实际版本可以按需工作。
我不得不说,我花了很多时间在ggplot2 reference中进行挖掘,而从未怀疑过limit()是breaks()的正确替代品-在该参考页中有明确提及而limits()没有出现。 ?limits()页面的信息不多,我找不到任何能说明两者之间区别的东西:何时而不是那样。