简体   繁体   中英

ggplot2 - fill area between line and 0

I'm trying to fill the area between a line and 0 but this doesn't work as the fill area "overflows" the line:

library(ggplot2)

# Create some dummy data
x <- c(1, 2, 3, 4, 5)
y <- c(1, -2, 3, -4, 5)

# Create a data frame with the x and y values
df <- data.frame(x, y)

# Create the line chart
ggplot(df, aes(x, y)) +
  geom_line() +
  # Fill the area above the line with a semi-transparent red color
  # when y is more than 0
    geom_ribbon(data=df, aes(ymin=0, ymax=ifelse(y >= 0, y, 0)), fill = "red", alpha=0.5)

在此处输入图像描述

Any ideas on how to make this work?

This solution creates a helper dataframe with added rows for every point the line crosses the x axis. Including these points in your ribbon will make it align correctly with the line.

library(ggplot2)
library(dplyr)
library(purrr)

x_cross <- df %>%
  transmute(
    x = pmap_dbl(
      list(x, lag(x), y, lag(y)), 
      possibly(
        \(x, xlag, y, ylag) approx(c(ylag, y), c(xlag, x), xout = 0)[[2]],
        NA_real_
      )
    ),
    y = 0
  ) %>% 
  filter(!is.na(x)) %>%
  bind_rows(df) %>%
  mutate(y = pmax(y, 0))

ggplot(df, aes(x, y)) +
  geom_line() +
  geom_ribbon(data = x_cross, aes(x, y, ymin = 0, ymax = y), fill = "red", alpha = 0.5)

Another option to achieve the desired result would be ggh4x::stat_difference . Note that in general stat_difference will color the areas above and below a reference line. Hence, an alpha set via stat_differnce will be applied to both areas even if we chose a "transparent" fill color for one. To fix that we have to set the transparency directly via scale_fill_manual using eg scales::alpha .

library(ggplot2)
library(ggh4x)

ggplot(df, aes(x, y)) +
  stat_difference(aes(ymin = 0, ymax = y)) +
  geom_line(aes(y = y)) +
  scale_fill_manual(
    values = c(alpha("red", .5), "transparent"), 
  guide = "none")

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM