Наложение нескольких графиков geom_raster с разными градиентами

Я хотел бы построить с gglot"s geom_raster 2D-график с 2 различными градиентами, но я не знаю, есть ли быстрое и элегантное решение для этого, и я застрял.

Эффект, который я хотел бы видеть, это наложение нескольких geom_rasterпо существу. Кроме того, мне нужно решение, которое масштабируется до N различных градиентов; позвольте мне привести пример с N=2 градиентами, которым легче следовать.

Сначала я создаю сетку из 100 и 100 позиций X и Y

# 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')

Но теперь представьте, что у меня есть другое значение для каждой точки сетки

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

Теперь, как мне построить сетку, где каждая позиция "(x,y)" окрашена с наложением:

  • 1 "белый к красному" градиент со значением, заданным как val
  • 1 "белый в синий" градиент со значением, заданным как second_val

По сути, в большинстве приложений val а также second_val будет две 2D функции плотности, и я хотел бы, чтобы каждый градиент представлял значение плотности. Мне нужны два разных цвета, чтобы увидеть различное распределение значений.

Я видел этот похожий вопрос, но не знаю, как использовать этот ответ в моем случае.

0 ответов

@ Ответ Аксемана на мой вопрос, на который вы ссылались, относится точно также и к вашему вопросу.

Обратите внимание, что 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. Вы можете построить один позже как растр и наложить второй с аннотацией. Я добавил прозрачность (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))
Другие вопросы по тегам