用不同的梯度覆盖多个geom_raster图

时间:2018-10-27 15:00:49

标签: r ggplot2 gradients geom-raster

我想用gglot的{​​{1}}绘制具有2个不同梯度的2D图表,但是我不知道是否有快速而优雅的解决方案,所以我陷入了困境。

我想看到的效果实质上是多个geom_raster的叠加。另外,我需要一个可以缩放到N个不同梯度的解决方案。让我举一个N = 2的渐变示例,更容易理解。

我首先创建一个100 x 100的位置X和Y的网格

geom_raster

然后我为每个网格点计算一个值;想象像这样的愚蠢

# the domain are 100 points on each axis
domain = seq(0, 100, 1) 

# the grid with the data
grid = expand.grid(domain, domain, stringsAsFactors = FALSE)
colnames(grid) = c('x', 'y')

我知道如何使用自定义的白色到红色渐变绘制此图

grid$val = apply(grid, 1, function(w) { w['x'] * w['y'] }

但是现在想象一下,每个网格点还有另一个值

ggplot(grid, aes(x = x, y = y)) +
  geom_raster(aes(fill = val), interpolate = TRUE) +
  scale_fill_gradient(
      low = "white", 
      high = "red", aesthetics = 'fill')

现在,我该如何绘制一个网格,其中每个位置“(x,y)”都用以下颜色覆盖:

  • 1个“白色到红色”的渐变,其值由grid$second_val = apply(grid, 1, function(w) { w['x'] * w['y'] + runif(1) }
  • 给出
  • 1个“白色到蓝色”的渐变,其值由val
  • 给出

基本上,在大多数应用中,second_valval将是两个2D密度函数,我希望每个梯度都代表密度值。我需要两种不同的颜色来查看值的不同分布。

我看过这个similar question,但不知道如何使用该答案。

1 个答案:

答案 0 :(得分:0)

您链接到的

@Axeman对我的问题的答案直接适用于您的问题。

请注意,scales::color_ramp()使用0到1之间的值,因此在绘制之前将val和second_val归一化在0到1之间

grid$val_norm <- (grid$val-min(grid$val))/diff(range(grid$val))
grid$second_val_norm <- (grid$second_val-min(grid$second_val))/diff(range(grid$second_val))

现在使用@Axeman's answer进行绘图。您可以稍后将其中一个绘制为栅格,并在第二个上覆盖注释。我添加了透明度(alpha=.5),否则您将只能看到第二层。

ggplot(grid, aes(x = x, y = y)) +
  geom_raster(aes(fill=val)) + 
  scale_fill_gradient(low = "white", high = "red", aesthetics = 'fill') + 
  annotate(geom="raster", x=grid$x, y=grid$y, alpha=.5,
           fill = scales::colour_ramp(c("transparent","blue"))(grid$second_val_norm))

或者,您可以使用annotate()绘制两个图层。

# plot using annotate()
ggplot(grid, aes(x = x, y = y)) +
  annotate(geom="raster", x=grid$x, y=grid$y, alpha=.5,
           fill = scales::colour_ramp(c("transparent","red"))(grid$val_norm)) +
  annotate(geom="raster", x=grid$x, y=grid$y, alpha=.5,
           fill = scales::colour_ramp(c("transparent","blue"))(grid$second_val_norm))