基于值的曲线下填充区域

时间:2013-07-31 00:48:26

标签: r plot ggplot2

我们正试图用ggplot2制作一个区域图,其中x轴上方的正面区域是一种颜色而负面区域是另一种颜色。

鉴于此数据集,我想在轴的每一侧用阴影区域绘制不同颜色的区域图。

我可以看到一种方法将数据集分成两个子集,一个是正值,其中所有负值都是零,另一个是负值,所有正值都是零,然后将它们分别绘制在同一个轴上,但它看起来像那里这将是一种更像ggplot的方式。

this question发布的解决方案未能提供准确的结果(见下文)。

示例数据准确显示为条形图

Raw data

由此代码生成:

# create some fake data with zero-crossings
yvals=c(2,2,-1,2,2,2,0,-1,-2,2,-2)
test = data.frame(x=seq(1,length(yvals)),y=yvals)

# generate the bar plot
ggplot(data=test,aes(x=x,y=y)) 
    + geom_bar(data=test[test$y>0,],aes(y=y), fill="blue",stat="identity", width=.5) 
    + geom_bar(data=test[test$y<0,],aes(y=y), fill="red",stat="identity", width=.5)

RLE方法不是通用

the other question上提出的RLE方法在应用于我们的数据集时会产生与过零相关的工件:

Ribbon RLE plot

由以下代码生成(不使用):

# set up grouping function
rle.grp <- function(x) {
   xx <- rle(x)
   xx$values = seq_along(xx$values)
   inverse.rle(xx) }

# generate ribbon plot
ggplot(test, aes(x=x,y=y,group = factor(rle.grp(sign(y))))) + 
    geom_ribbon(aes(ymax = pmax(0,y),ymin = pmin(0,y),
   fill = factor(sign(y), levels = c(-1,0,1), labels = c('-','0','+')))) 
   + scale_fill_brewer(name = 'sign', palette = 'RdBu')

请参阅@baptiste和Kohske建议的以下最终答案。

2 个答案:

答案 0 :(得分:10)

Per @ baptiste的评论(自删除后)我会说这是最好的答案。它基于Kohske的this post。它在零交叉处向数据集添加新的x-y对,并生成以下图:

# create some fake data with zero-crossings
yvals = c(2,2,-1,2,2,2,0,-1,-2,2,-2)
d = data.frame(x=seq(1,length(yvals)),y=yvals)

rx <- do.call("rbind",
   sapply(1:(nrow(d)-1), function(i){
   f <- lm(x~y, d[i:(i+1),])
   if (f$qr$rank < 2) return(NULL)
   r <- predict(f, newdata=data.frame(y=0))
   if(d[i,]$x < r & r < d[i+1,]$x)
      return(data.frame(x=r,y=0))
    else return(NULL)
 }))
 d2 <- rbind(d,rx)
 ggplot(d2,aes(x,y)) + geom_area(data=subset(d2, y<=0), fill="pink") 
     + geom_area(data=subset(d2, y>=0), fill="lightblue") + geom_point()

生成以下输出: example plot

答案 1 :(得分:0)

我使用以下易于理解的逻辑进行了非常相似的绘图。我为正值和负值创建了以下两个对象。请注意,其中有一个“非常小的数字”,以避免那些从一个点到另一个点的跳跃而不经过零。

pos <- mutate(df, y = ifelse(ROI >= 0, y, 0.0001))
neg <- mutate(df, y = ifelse(ROI < 0, y, -0.0001))

然后,只需将geom_area添加到您的ggplot对象中即可:

ggplot(..., aes(y = y)) + 
  geom_area(data = pos, fill = "#3DA4AB") +
  geom_area(data = neg, fill = "tomato")

希望它对您有用! ;)