在ggplot2对象中的现有图层下插入图层

时间:2013-11-27 17:54:22

标签: r ggplot2 layer

鉴于现有的绘图对象,是否可以在现有图层中添加 UNDERNEATH 图层?

例如,在下图中,是否可以将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. 

Example Output


加分问题:如果现有图中有多个图层,是否可以指明插入新图层的具体位置(相对于现有图层)?


样本数据

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

3 个答案:

答案 0 :(得分:34)

感谢@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)
    }

答案 1 :(得分:0)

Ricardo' answer上扩展,我使用以下代码段:

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()

然后箱形图将放置在这些点的下方。

答案 2 :(得分:-4)

如ggplot文档here所示,您可以设置骨架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)) 

我认为这也回答了你的奖金问题:)