您可以使用scale_fill_gradientn 在比例尺上选择颜色接近的颜色,或者,如果您想要一个通用的解决方案而不需要所有的摆弄(并且不介意非等距比例尺),您可以实现的最佳分离是只是将rank 用作转换。
为了清楚地显示这一点,让我们使用您提供的示例制作一个栅格:
df <- expand.grid(x = 1:10, y = 1:10)
z <- c(100, 1, 2, 1.4, 0.5, -2, -90, 0.3, 2.3)
set.seed(69)
df$z <- sample(z, 100, replace = TRUE)
library(ggplot2)
ggplot(df, aes(x, y, fill = z)) +
geom_raster() +
scale_fill_viridis_c()
尽管我们有 9 个不同的关卡,但我们只能看到 3 个不同的填充。
比较一下:
ggplot(df, aes(x, y, fill = rank(z))) +
geom_raster() +
scale_fill_viridis_c(breaks = quantile(rank(df$z)),
labels = quantile(df$z),
name = "z")
这给出了一个平滑的渐变条但奇怪的标签。你可以做相反的事情(有正常的标签,但有一个跳跃的颜色条),如下所示:
scale_fill_viridis_opt <- function(x)
{
x <- sort(unique(x))
x <- (x[-1] + x[-length(x)])/2
y <- (x - min(x))/diff(range(x))
scale_fill_gradientn(values = y, colours = viridis::viridis(length(x)))
}
ggplot(df, aes(x, y, fill = z)) +
geom_raster() +
scale_fill_viridis_opt(df$z)
或者,如果您想尝试一种转换来防止这些问题,您可以尝试一个有符号的第 n 个根,您可以在其中调整 n 以适合您的数据。然后,您的标签和颜色间隔很好,但标签的物理意义较小。在这里,我们得到一个有符号立方根的合理平衡:
signed_nth_root <- function(x, n = 2) {
sign(x) * abs(x)^(1/n)
}
ggplot(df, aes(x, y, fill = signed_nth_root(z, 3))) +
geom_raster() +
scale_fill_viridis_c()
由reprex package (v0.3.0) 于 2020 年 8 月 4 日创建