【问题标题】:How to create better gradients in ggplot?如何在 ggplot 中创建更好的渐变?
【发布时间】:2020-08-04 14:52:45
【问题描述】:

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

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

这意味着当我附加渐变时 - 无论是连续的还是分箱的 - 几乎不可能分辨出较小百分比值之间的差异。有没有办法影响梯度,以便在例如1% 和 2% 更明显?

【问题讨论】:

  • 您可以使用转换。对数转换很常见,它们将大值压缩在一起,同时在小值之间增加空间——但它们仅适用于正数据。对于具有混合符号的数据,带符号的平方根可能很好。本质上,使用x_ssqrt = sign(x) * sqrt(abs(x)) 作为颜色变量。 (或者,更稳健地,定义转换对象as explained here

标签: r ggplot2 gradient linear-gradients


【解决方案1】:

您可以使用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 日创建

【讨论】:

    猜你喜欢
    • 2013-04-24
    • 1970-01-01
    • 2011-05-04
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-02
    相关资源
    最近更新 更多