Вставить слой под существующими слоями в объекте ggplot2

Учитывая существующий объект графика, возможно ли добавить слой ПОД существующим слоем?

Пример, на графике ниже, можно ли добавить geom_boxplot() в P такой, что коробочный участок появляется под geom_point()?

## Starting from: 
library(ggplot2)
P <- ggplot(data=dat, aes(x=id, y=val)) + geom_point()

## This adds boxplot, but obscures some of the points
P + geom_boxplot()

Ожидаемый результат:

# Which is essentially
ggplot(data=dat, aes(x=id, y=val)) + geom_boxplot() + geom_point()
## However, this involves re-coding all of P (after the point insertion of the new layer).
##   which is what I am hoping to avoid. 

Пример вывода


Дополнительный вопрос: если на существующем графике несколько слоев, можно ли указать, куда конкретно вставить новый слой (относительно существующих слоев)?


ПРИМЕР ДАННЫХ

set.seed(1)
N <- 100
id <- c("A", "B")
dat <- data.frame(id=sample(id, N, TRUE), val=rnorm(N))

2 ответа

Решение

Спасибо @baptiste за указание мне в правильном направлении. Чтобы вставить слой под все остальные слои, просто измените layers элемент сюжета объекта.

## For example:
P$layers <- c(geom_boxplot(), P$layers)

Ответ на бонусный вопрос:

Эта удобная маленькая функция вставляет слой на назначенный z-уровень:

insertLayer <- function(P, after=0, ...) {
  #  P     : Plot object
  # after  : Position where to insert new layers, relative to existing layers
  #  ...   : additional layers, separated by commas (,) instead of plus sign (+)

      if (after < 0)
        after <- after + length(P$layers)

      if (!length(P$layers))
        P$layers <- list(...)
      else 
        P$layers <- append(P$layers, list(...), after)

      return(P)
    }

Расширяя ответ Рикардо, я использую следующий фрагмент:

library(ggplot2)

`-.gg` <- function(plot, layer) {
    if (missing(layer)) {
        stop("Cannot use `-.gg()` with a single argument. Did you accidentally put - on a new line?")
    }
    if (!is.ggplot(plot)) {
        stop('Need a plot on the left side')
    }
    plot$layers = c(layer, plot$layers)
    plot
}

Поскольку это позволяет:

P <- ggplot(data=dat, aes(x=id, y=val)) + geom_point()

P - geom_boxplot()

И коробчатая диаграмма будет размещена под точками.

Как показано здесь в документации по ggplot, вы можете настроить каркасный объект ggplot и добавить слои. Порядок, в котором вы указываете слои, - это порядок, в котором они будут отображаться на вашем графике.

Это даст ожидаемый результат:

ggplot() +
  geom_boxplot(data = dat, aes(x=id, y=val)) +
  geom_point(data = dat, aes(x=id, y=val)) 

Это получит ваш неправильный вывод:

ggplot() +
  geom_point(data = dat, aes(x=id, y=val)) +
  geom_boxplot(data = dat, aes(x=id, y=val)) 

Я думаю, что это отвечает и на ваш бонусный вопрос:)

Другие вопросы по тегам