【问题标题】:ggplot make range of color scale a subset of the range of the dataggplot 使色标范围成为数据范围的子集
【发布时间】:2018-08-13 21:13:31
【问题描述】:

我正在尝试使用geom_raster 修改热图的比例,以使颜色变化发生在数据的子集上,并且该子集之外的任何内容都不会变得或多或少的色彩。

library(tidyverse)
library(viridis)
library(reshape2)

q <- letters[1:5]
w <- rev(letters)[1:5]
x1 <- rnorm(5, 0, 1)
x2 <- rnorm(5, 0, 1)
x3 <- rnorm(5, 0, 1)
x4 <- rnorm(5, 0, 1)
x5 <- rnorm(5, 10, 1)

test.df <- melt(data.frame(q,w,x1,x2,x3,x4,x5))

ggplot(test.df, aes(q,variable,fill=value))+geom_raster()+scale_fill_viridis()

如果你运行它,你会得到这个热图:

顶行“占用”了一些颜色范围。由于绝大多数数据在 -2 和 2 之间,我想让它使色阶变化发生在该范围内,而超出该范围的任何东西都只是黄色或紫色。对我来说,任何超过 2 的东西都应该是“非常高”,而任何低于 -2 的东西都应该是“非常低”,但 -2 和 2 之间的数字是我想看到的。

我不认为cut 是我想要的,因为我需要提供一堆颜色,并且我不想删除任何数据或将任何数据更改为某个最大值或类似的值.在scale_viridis 命令中设置限制有助于但会删除限制之外的数据。

【问题讨论】:

    标签: r ggplot2 heatmap geom-raster


    【解决方案1】:

    您可以使用dplyr::case_when 等函数截断端点处的值。然后,如果需要,您可以相应地在图例上设置标签。请注意,我手动输入了标签以执行"&lt;= -2""&gt;= 2";不确定这是否足够,或者您是否需要更动态的东西。

    library(tidyverse)
    library(viridis)
    library(reshape2)
    
    set.seed(1234)
    q <- letters[1:5]
    w <- rev(letters)[1:5]
    x1 <- rnorm(5, 0, 1)
    x2 <- rnorm(5, 0, 1)
    x3 <- rnorm(5, 0, 1)
    x4 <- rnorm(5, 0, 1)
    x5 <- rnorm(5, 10, 1)
    
    test.df <- melt(data.frame(q,w,x1,x2,x3,x4,x5)) %>%
      mutate(val_trimmed = case_when(
        value > 2 ~ 2,
        value < -2 ~ -2,
        T ~ value
      )) 
    
    ggplot(test.df, aes(x = q, y = variable, fill = val_trimmed)) +
      geom_raster() +
      scale_fill_viridis(labels = c("<= -2", "-1", "0", "1", ">= 2"), breaks = -2:2) +
      labs(caption = "Note: values truncated above 2 and below -2")
    

    reprex package (v0.2.0) 于 2018 年 8 月 13 日创建。

    【讨论】:

    • 这个确实有效,但我很好奇为什么另一个似乎没有。
    • 我将数据设置为仅介于 -2 和 2 之间,然后相应地设置填充的中断。低于 -2 的值设置为 -2,正值 2 也是如此。这是为了说明数据的广泛传播
    【解决方案2】:

    您可以使用scale_fill_gradientn 来完全控制您的颜色渐变。下面的代码将为[-2, 2] 分配不同的颜色,但在这些值之外保持边缘颜色一致。请尝试使用set.seed 在您的问题中设置种子以实现可重复性。

    ggplot(test.df, aes(q, variable, fill = value)) + 
      geom_raster() + 
      scale_fill_gradientn(
        colours = c("blue", "blue", "red", "red"),
        values = c(-999, -2, 2, 999)
      )
    

    只需增加颜色和值的数量即可扩展颜色渐变。

    【讨论】:

    • 这似乎应该可以工作,但大多数情况下它只是将我的热图变成了紫色。 link 上图是我的实际数据,第二个是相同的代码,但添加了你的 scale_gradient_n() 代码。
    • 您是否使用 OP 的数据运行此程序?填充的色调几乎没有任何区别,所有的瓷砖基本上都是一样的红粉色
    【解决方案3】:

    如果值仅在一端超出范围(您的数据看起来就是这种情况,您的值大于 2,但不小于 -2),您可以将超过最大值的值更改为 NA in您的数据框,然后使用scale_fill_viridis() 中的na.value = 选项将所有NA 值设置为某种颜色。

    #change values greater than 2 to NA
    test.df$value <- ifelse(test.df$value <= 2, test.df$value, NA)
    
    ggplot(test.df, aes(q, variable, fill = value)) +
      geom_raster() +
      scale_fill_viridis(na.value = "yellow", #make NAs (values > 2) yellow
                         limits = c(-2,2), #define limits of scale
                         labels = c(as.character(-2:1), ">= 2"), breaks = -2:2)
    

    此解决方案不如其他答案灵活,因为如果您的值超出范围的上限和下限,它将不起作用,但如果您只在规模的一端有异常值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-12
      • 2021-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多