简体   繁体   English

为热图上的连续发散色标设置中点

[英]Setting Midpoint for continuous diverging color scale on a heatmap

I need to adjust the midpoint location for a heatmap via ggplot2.我需要通过 ggplot2 调整热图的中点位置。 I've googled around and have seen scale_fill_gradient2 be a great fit but the colors don't seem to match up to what I'm looking for.我四处搜索,发现scale_fill_gradient2非常合适,但 colors 似乎与我正在寻找的不匹配。 I know z needs a range from 0 to 1. Example dataset generation below:我知道 z 需要一个从 0 到 1 的范围。下面的示例数据集生成:

library(ggplot2)
library(tibble)
library(RColorBrewer)

set.seed(5)
df <- as_tibble(expand.grid(x = -5:5, y = 0:5, z = NA))
df$z <- runif(length(df$z), min = 0, max = 1)

I tried plotting with the scale_fill_gradient2 but the blue color isn't coming as "dark" as I'd like.我尝试使用scale_fill_gradient2进行绘图,但蓝色并没有像我想要的那样“暗”。

ggplot(df, aes(x = x, y = y)) + 
  geom_tile(aes(fill = z)) + 
  scale_fill_gradient2(
    low = 'red', mid = 'white', high = 'blue',
    midpoint = 0.7, guide = 'colourbar', aesthetics = 'fill'
  ) + 
  scale_x_continuous(expand = c(0, 0), breaks = unique(df$x)) + 
  scale_y_continuous(expand = c(0, 0), breaks = unique(df$y))

版本 1

Therefore, I'm using scale_fill_distiller with the color palette 'RdBu' which comes out with the color scale I need but the ranges and the midpoints aren't right.因此,我将scale_fill_distiller与调色板“RdBu”一起使用,它提供了我需要的色标,但范围和中点不正确。

ggplot(df, aes(x = x, y = y)) + 
  geom_tile(aes(fill = z)) +
  scale_fill_distiller(palette = 'RdBu') + 
  scale_x_continuous(expand = c(0, 0), breaks = unique(df$x)) +
  scale_y_continuous(expand = c(0, 0), breaks = unique(df$y))

版本 2

Is there a way to get the 2nd color scale but with the option to set midpoint range as the first?有没有办法获得第二个色阶,但可以选择将中点范围设置为第一个?

The color scales provided by the colorspace package will generally allow you much more fine-grained control.色彩空间 package 提供的色阶通常允许您进行更细粒度的控制。 First, you can use the same colorscale but set the mid-point.首先,您可以使用相同的色阶但设置中间点。

library(ggplot2)
library(tibble)
library(colorspace)

set.seed(5)
df <- as_tibble(expand.grid(x = -5:5, y = 0:5, z = NA))
df$z <- runif(length(df$z), min = 0, max = 1)

ggplot(df, aes(x = x, y = y)) + 
  geom_tile(aes(fill = z)) + 
  scale_fill_continuous_divergingx(palette = 'RdBu', mid = 0.7) + 
  scale_x_continuous(expand = c(0, 0), breaks = unique(df$x)) + 
  scale_y_continuous(expand = c(0, 0), breaks = unique(df$y))

However, as you see, this creates the same problem as before, because you'd have to be further away from the midpoint to get darker blues.但是,如您所见,这会产生与以前相同的问题,因为您必须远离中点才能获得更深的蓝色。 Fortunately, the divergingx color scales allow you to manipulate either branch independently, and so we can create a scale that turns to dark blue much faster.幸运的是,divergingx 色阶允许您独立操作任一分支,因此我们可以创建一个更快地变为深蓝色的色阶。 You can play around with l3 , p3 , and p4 until you get the result you want.你可以玩弄l3p3p4 ,直到你得到你想要的结果。

ggplot(df, aes(x = x, y = y)) + 
  geom_tile(aes(fill = z)) + 
  scale_fill_continuous_divergingx(palette = 'RdBu', mid = 0.7, l3 = 0, p3 = .8, p4 = .6) + 
  scale_x_continuous(expand = c(0, 0), breaks = unique(df$x)) + 
  scale_y_continuous(expand = c(0, 0), breaks = unique(df$y))

Created on 2019-11-05 by the reprex package (v0.3.0)reprex package (v0.3.0) 于 2019 年 11 月 5 日创建

Claus' answer is great (and I'm a fan of his work), but I'd like to add that you can retain control within vanilla ggplot as well if you use the scale_fill_gradientn() function:克劳斯的回答很棒(我是他工作的粉丝),但我想补充一点,如果您使用scale_fill_gradientn() function,您也可以在香草 ggplot 中保留控制权:

library(ggplot2)
library(tibble)

set.seed(5)
df <- as_tibble(expand.grid(x = -5:5, y = 0:5, z = NA))
df$z <- runif(length(df$z), min = 0, max = 1)

ggplot(df, aes(x = x, y = y)) + 
  geom_tile(aes(fill = z)) + 
  scale_fill_gradientn(
    colours = c("red", "white", "blue"),
    values = c(0, 0.7, 1)
  ) + 
  scale_x_continuous(expand = c(0, 0), breaks = unique(df$x)) + 
  scale_y_continuous(expand = c(0, 0), breaks = unique(df$y))

在此处输入图像描述

A notable downside is that you'd have to provide the values argument in rescaled space, so between 0-1.一个显着的缺点是您必须在重新缩放的空间中提供values参数,因此介于 0-1 之间。 Consider if your fill values range from 0-10 instead and want the midpoint on 0.7, you'd have to provide values = c(0, 0.07, 1) .考虑如果您的填充值范围为 0-10,并且希望中点为 0.7,则您必须提供values = c(0, 0.07, 1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM