如果我在trans="log"
中使用scale_fill_viridis
或其他连续比例,如何在图例上添加NA或“ 0”标签
> d1
persona num.de.puntos puntos
1 p1 1 3
2 p1 2 4
3 p1 3 0
4 p1 4 4
5 p1 5 2
6 p2 1 2
7 p2 2 3
8 p2 3 0
9 p2 4 0
10 p2 5 4
11 p3 1 0
12 p3 2 1
13 p3 3 0
14 p3 4 5
15 p3 5 8
p <- ggplot(d1, aes(persona, num.de.puntos, fill = puntos)) +
scale_fill_viridis(trans="log", option ="D", direction=1, na.value = "gray50",
breaks=c(0,1,5,8),
name="Number of people",
guide=guide_legend(label.position = "bottom",
title.position = 'top',
nrow=1,
label.theme = element_text(size = 6,
face = "bold",
color = "black"),
title.theme = element_text(size = 6,
face = "bold",
color = "black"))) +
geom_tile(colour="grey", show.legend = TRUE)
p
我想要
答案 0 :(得分:1)
注意:以下代码在R 3.5.1和ggplot2 3.1.0中运行。您可能使用的是ggplot2软件包的旧版本,因为您的代码使用scale_fill_viridis
而不是scale_fill_viridis_c
。
TL; DR解决方案:
我非常确定这不是正统的,但是假设您的图名为p
,设置为:
p$scales$scales[[1]]$is_discrete <- function() TRUE
将获得图例中的NA值,而无需更改任何现有的填充美学映射。
演示:
p <- ggplot(d1, aes(persona, num.de.puntos, fill = puntos)) +
scale_fill_viridis_c(trans="log", option ="D", direction=1,
na.value = "gray50", # optional, change NA colour here
breaks = c(0, 1, 5, 8),
labels = c("NA label", "1", "5", "8"), # optional, change NA label here
name="Number of people",
guide=guide_legend(label.position = "bottom",
title.position = 'top',
nrow=1,
label.theme = element_text(size = 6,
face = "bold",
color = "black"),
title.theme = element_text(size = 6,
face = "bold",
color = "black"))) +
geom_tile(colour = "grey", show.legend = TRUE)
p # no NA mapping
p$scales$scales[[1]]$is_discrete <- function() TRUE
p # has NA mapping
说明:
我通过将p
转换为grob对象(通过ggplotGrob
)并在影响绘图过程中图例生成部分的函数上运行debug()
来深入研究绘图机制。
在通过ggplot2:::ggplot_gtable.ggplot_built
,ggplot2:::build_guides
和ggplot2:::guides_train
进行调试之后,我进入了ggplot2:::guide_train.legend
,这是ggplot2
包中未导出的函数:>
> ggplot2:::guide_train.legend
function (guide, scale, aesthetic = NULL)
{
breaks <- scale$get_breaks()
if (length(breaks) == 0 || all(is.na(breaks))) {
return()
}
key <- as.data.frame(setNames(list(scale$map(breaks)), aesthetic %||%
scale$aesthetics[1]), stringsAsFactors = FALSE)
key$.label <- scale$get_labels(breaks)
if (!scale$is_discrete()) {
limits <- scale$get_limits()
noob <- !is.na(breaks) & limits[1] <= breaks & breaks <=
limits[2]
key <- key[noob, , drop = FALSE]
}
if (guide$reverse)
key <- key[nrow(key):1, ]
guide$key <- key
guide$hash <- with(guide, digest::digest(list(title, key$.label,
direction, name)))
guide
}
在key$.label <- scale$get_labels(breaks)
步骤之前,我一直看到key
看起来像这样:
> key
fill .label
1 gray50 NA label
2 #440154 1
3 #72CC59 5
4 #FDE725 8
但是scale$is_discrete()
是FALSE
,所以!scale$is_discrete()
是TRUE
,并且在下一步中,key
中与NA值对应的行将被删除,因为对数转换后填充刻度的中断中有一个NA值:
> scale$get_breaks()
[1] NA 0.000000 1.609438 2.079442
因此,如果我们可以让scale$is_discrete()
的评估结果为TRUE
而不是FALSE
,则将跳过此步骤,最后得到包括NA值的完整图例