ggplot使色标范围成为数据范围的子集

时间:2018-08-13 21:13:31

标签: r ggplot2 heatmap geom-raster

我正在尝试使用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()

运行该命令,将获得以下热图:

heatmap

第一行正在“拖拉”某些颜色范围。由于绝大多数数据都在-2到2之间,因此我想使其在该范围内发生色标变化,而色域之外的任何颜色仅为黄色或紫色。对我来说,大于2的任何值都应该是“非常高”,小于-2的任何值都应该是“非常低”,但是-2和2之间的数字是我想要看到的。

我不想要cut是因为我需要提供多种颜色,并且我不想删除任何数据或将任何超出某个值的数据更改为最大值或任何值。像那样。在scale_viridis命令中设置限制会有所帮助,但会删除超出限制的数据。

3 个答案:

答案 0 :(得分:3)

您可以使用诸如dplyr::case_when之类的函数来截断端点上的值。然后,您可以根据需要在图例上设置标签。请注意,我手动键入标签是为了进行"<= -2"">= 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-08-13创建。

答案 1 :(得分: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)
  )

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

答案 2 :(得分:1)

如果值仅在一端超出比例(看起来像是数据,则您的值大于2,但不小于-2),则可以将超出最大值的值更改为{{1} },然后使用<item name="windowMinWidthMajor">100%</item> <item name="windowMinWidthMinor">100%</item> <item name="android:windowBackground">@null</item> <item name="android:windowIsFloating">true</item> <item name="android:background">#ffffff</item> 中的NA选项将所有NA值设置为特定颜色。

na.value =

enter image description here

此解决方案不如其他答案灵活,因为如果您的值超出了刻度上限和下限的范围,则该解决方案将不起作用,但如果仅在尺度的一端有离群值。