geom_ribbon 中 y-lim 上方的颜色区域

Colour area above y-lim in geom_ribbon

如何将 y=0 和数据点之间的区域涂成绿色?目前它正在为整个 y [0:1]

着色
Variable <- c(1,2,3,4,5,6,7)
    value <- c(-0.26, -0.10,0.98,0.52, 0.31, -0.63, -0.70)
    df <- data.frame(Variable, value)
    
ggplot(df, aes(x = Variable, y = value)) +
  geom_ribbon(aes(ymin=pmin(value,1), ymax=0), fill="red", col="red", alpha=0.5) +
  geom_ribbon(aes(ymin=0, ymax=pmax(df$value,1)), fill="green", col="green", alpha=0.5) +
  geom_hline(aes(yintercept=0), color="black") + 
  theme_bw() +
  geom_point()

据我所知,在 ggplot2 中确实没有直接的方法可以做到这一点。如果你不想要透明度,那么在背景中画一个矩形然后在上面画丝带就很容易了。

ggplot(df, aes(x = Variable, y = value)) +
  geom_rect(aes(xmin=min(Variable), xmax=max(Variable), ymin=0, ymax=1), fill="green") + 
  geom_ribbon(aes(ymin=pmin(value,1), ymax=0), fill="red", col="red") +
  geom_hline(aes(yintercept=0), color="black") + 
  theme_bw(base_size = 16) +
  geom_point()

但是如果您需要透明度,您将需要计算该区域的边界,这是混乱的,因为线与轴相交的点不在您的数据中,您需要计算这些区域。这是一个函数,用于查找区域与轴交叉的位置并跟踪顶点

crosses <- function(x, y) {
  outx <- x[1]
  outy <- max(y[1],0)
  for(i in 2:length(x)) {
    if (sign(y[i-1]) != sign(y[i])) {
      outx <- c(outx, -y[i-1]*(x[i]-x[i-1])/(y[i]-y[i-1])+x[i-1])
      outy <- c(outy, 0)
    }
    if (y[i]>0) {
      outx <- c(outx, x[i])
      outy <- c(outy, y[i])
    } 
  }
  if (y[length(y)]<0) {
    outx <- c(outx, x[length(x)])
    outy <- c(outy, 0)
  }
  data.frame(x=outx, y=outy)
}

基本上它只是做了一些 two-point line formula 的事情来计算交集。

然后使用它为顶部色带创建一个新的点数据框

top_ribbon <- with(df, crosses(Variable, value))

绘制它

ggplot(df, aes(x = Variable, y = value)) +
  geom_ribbon(aes(ymin=pmin(value,1), ymax=0), fill="red", col="red", alpha=0.5) +
  geom_ribbon(aes(ymin=y, ymax=1, x=x), fill="green", col="green", alpha=0.5, data=top_ribbon) +
  geom_hline(aes(yintercept=0), color="black") + 
  theme_bw(base_size = 16) +
  geom_point()

我找到了 3 年前的相关-post How can I fill the space between values(geom_line) and an intercept with ggplot2? Different Colors for values over and under intercept

为此我 运行 以下代码:

ggplot(df, aes(x=Variable,y=value)) +
geom_ribbon(aes(ymin=pmin(df$value,0), ymax=0), fill="blue", col="blue", alpha=0.5) +
geom_ribbon(aes(ymin=0, ymax=pmax(df$value,0)), fill="green", col="green", alpha=0.5) +
geom_line(aes(y=0))

并且是这样工作的:尽管注意这些区域在相交处有点奇怪!