如何在 ggplot 中创建更好的渐变?

How to create better gradients in ggplot?

我正在尝试为热图创建百分比梯度比例。我有一些极端的例子 - 像这样的百分比向量。

x = c(100, 1, 2, 1.4, 0.5, -2, -90, 0.3, 2.3)

这意味着当我附加渐变时——无论是连续渐变还是合并渐变——几乎不可能区分较小的百分比值。有没有一种方法可以影响梯度以区分例如1% 和 2% 更明显?

您可以选择在 scale_fill_gradientn 范围内接近的颜色,或者,如果您想要一个通用的解决方案而无需任何摆弄(并且不介意 non-isometric 范围),您可以实现的最佳分离是简单地使用 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-08-04 创建