有简单的方法可以做到这一点,如事先截取你的数据,或者使用cut
创建适当的标签离散箱。
require(dplyr)
df %>% mutate(z2 = ifelse(z > 50, 50, ifelse(z < -20, -20, z))) %>%
ggplot(aes(x, y, fill = z2)) + geom_tile() +
scale_fill_gradient2(low = cm.colors(20)[1], high = cm.colors(20)[20])
df %>% mutate(z2 = cut(z, c(-Inf, seq(-20, 50, by = 10), Inf)),
z3 = as.numeric(z2)-3) %>%
{ggplot(., aes(x, y, fill = z3)) + geom_tile() +
scale_fill_gradient2(low = cm.colors(20)[1], high = cm.colors(20)[20],
breaks = unique(.$z3), labels = unique(.$z2))}
但我想过这个任务之前,觉得不满意这一点。预截断不会留下漂亮的标签,并且cut
选项总是很烦琐(特别是必须调整cut
中的seq
的参数并找出如何重新接收分档)。所以我试图定义一个可重用的转换,它可以为你截断和重新标记。
我还没有完全调试这个,我要出城,所以希望你或其他回答者可以采取一些措施。主要的问题似乎是边缘情况下的碰撞,所以有时候这些限制在视觉上重叠了预期的中断,以及一些格式化的意外行为。我只是使用一些虚拟数据来创建你想要的范围-100到150来测试它。
require(scales)
trim_tails <- function(range = c(-Inf, Inf)) trans_new("trim_tails",
transform = function(x) {
force(range)
desired_breaks <- extended_breaks(n = 7)(x[x >= range[1] & x <= range[2]])
break_increment <- diff(desired_breaks)[1]
x[x < range[1]] <- range[1] - break_increment
x[x > range[2]] <- range[2] + break_increment
x
},
inverse = function(x) x,
breaks = function(x) {
force(range)
extended_breaks(n = 7)(x)
},
format = function(x) {
force(range)
x[1] <- paste("<", range[1])
x[length(x)] <- paste(">", range[2])
x
})
ggplot(df, aes(x, y, fill = z)) + geom_tile() +
guides(fill = guide_colorbar(label.hjust = 1)) +
scale_fill_gradient2(low = cm.colors(20)[1], high = cm.colors(20)[20],
trans = trim_tails(range = c(-20,50)))
用盒装的传说,而不是一个彩条同样适用,只是用... + guides(fill = guide_legend(label.hjust = 1, reverse = T)) + ...
大,完全充实响应布赖恩。谢谢你。我现在不需要它,但我可以看到这个转换非常方便。 – SeldomSeenSlim