r - ggplot2 - 在两个geom_abline图层之间创建阴影区域

tsa*_*lis 14 r ggplot2

关于在ggplot2中使用阴影区域的帖子一些 ,但我认为没有完全回答我的问题.我有两个斜坡用于跨越多个条件的线,我想遮蔽它们之间的区域.这是示例数据:

dat <- data.frame(cond1=c("a","a","b","b"),
              cond2=c("c","d","c","d"),
              x=c(1,5),
              y=c(1,5),
              sl=c(1,1.2,0.9,1.1),
              int=c(0,0.1,0.1,0),
              slopeU=c(1.1,1.3,1.2,1.2),
              slopeL=c(.9,1,0.7,1))
Run Code Online (Sandbox Code Playgroud)

这里,sl是来自单独拟合程序的平均斜率参数,slopeU并且slopeL表示每个条件中斜率估计的上下置信区域.拦截被限制为相同.以下代码使用一些分面绘制每个条件的最佳拟合线:

p <- ggplot(dat,aes(x=x,y=y,colour=cond1))
p <- p + facet_grid(. ~ cond2)
p <- p + geom_blank()
p <- p + geom_abline(aes(intercept=int,slope=sl,colour=cond1),data=dat)
p
Run Code Online (Sandbox Code Playgroud)

我想补充由定义的行intercept=int, slope=slopeUintercept=int, slope=slopeL(例如,在对小区和阴影它们之间的区域alpha=.5中的相应COND1颜色).

我认识到,通过一些操作,我可以创建一个数据框,指定这些线的值至少两个x值,然后绘制相应的geom_ribbon或geom_polygon来创建阴影区域,但是我想找到一个更优雅的解决方案.或者是从斜坡手动指定一些坐标并截取唯一的方法?如何最好地创建所需的数据框(需要比原始框架具有更多的行,以考虑条件和x,y对的所有组合).

jor*_*ran 10

就个人而言,我认为创建数据框架和使用geom_ribbon 优雅的解决方案,但显然意见在这个分数上会有所不同.

但如果你充分利用plyrggplot,事情会变得非常光滑.由于您的斜率和截距都可以很好地存储在数据框中,我们可以使用plyr和自定义函数来完成所有工作:

dat <- data.frame(cond1=c("a","a","b","b"),
          cond2=c("c","d","c","d"),
          x=c(1,5),
          y=c(1,5),
          sl=c(1,1.2,0.9,1.1),
          int=c(0,0.1,0.1,0),
          slopeU=c(1.1,1.3,1.2,1.2),
          slopeL=c(.9,1,0.7,1))

genRibbon <- function(param,xrng){
    #xrng is a vector of min/max x vals in original data
    r <- abs(diff(xrng))
    #adj for plot region expansion
    x <- seq(xrng[1] - 0.05*r,xrng[2] + 0.05*r,length.out = 3)
    #create data frame
    res <- data.frame(cond1 = param$cond1,
                      cond2 = param$cond2,
                      x = x,
                      y = param$int + param$sl * x,
                      ymin = param$int + param$slopeL * x,
                      ymax = param$int + param$slopeU * x)
    #Toss the min/max x vals just to be safe; needed them 
    # only to get the corresponding y vals
    res$x[which.min(res$x)] <- -Inf
    res$x[which.max(res$x)] <- Inf
    #Return the correspondinng geom_ribbon
    geom_ribbon(data = res,aes(x = x,y=y, ymin = ymin,ymax = ymax,
                               fill = cond1,colour = NULL),
                alpha = 0.5)
}

ribs <- dlply(dat,.(cond1,cond2),genRibbon,xrng = c(1,5))
Run Code Online (Sandbox Code Playgroud)

这里额外的浮油是我完全丢弃生成的数据帧并返回一个geom_ribbon对象列表.然后他们可以简单地添加到我们的情节:

p + ribs + 
    guides(fill = guide_legend(override.aes = list(alpha = 0.1)))
Run Code Online (Sandbox Code Playgroud)

我超越了alpha传说中的美学,因为你第一次看不到传说中的对角线.

在此输入图像描述

我会警告你,那里生成情节的最后一行也会引发很多关于无效因子水平的警告,而且老实说我不确定为什么.但情节看起来不错.