简体   繁体   中英

In ggplot2,specify values to use for geom_smooth() confidence interval (similar to geom_errorbar)

I am plotting temperature values over the course of a year using geom_smooth() . I have daily min, max, and mean temperatures, and I would like to display the mean as a line, and then the min and max like you would display a confidence interval. There is a se = T argument to geom_smooth() , and I am wondering how I can supply variables to use as the "confidence interval." I know you can do this with box plots with geom_errorbar() , and I'm hoping there is a similar version for line plots.

I would like my plot to look like the results of this, but using the max and min values to display the confidence interval.

mean <- runif(365, min = 10, max = 25)
max <- runif(365, min = 26, max = 35)
min <- runif(365, min = 0, max = 9)

temp <- data.frame(day = 1:365, mean = mean)

ggplot(data = temp, aes(x = day, y = mean)) +
  geom_smooth()

EDIT: I am adding two years of data, and would like each year to have its own geom_smooth line and its own geom_ribbon. As the code is now, each year has its own geom_smooth line but there is a single geom_ribbon for all years.


mean1 <- runif(365, min = 10, max = 25)
max1 <- runif(365, min = 26, max = 35)
min1 <- runif(365, min = 0, max = 9)

mean3 <- runif(365, min = 10, max = 25)
max3 <- runif(365, min = 30, max = 40)
min3 <- runif(365, min = -5, max = 5)

mean2 <- runif(365, min = 10, max = 25)
max2 <- runif(365, min = 200, max = 220)
min2 <- runif(365, min = -10, max = 9)

temp <- rbind(data.frame(day = 1:365, mean = mean1, max = max1, min = min1, label = 'A'),
            data.frame(day = 1:365, mean = mean2, max = max2, min = min2, label = 'B'),
            data.frame(day = 1:365, mean = mean3, max = max3, min = min3, label = 'C'))


ggplot(data = temp, aes(x = day, y = mean, color = label)) +
  geom_ribbon(data = temp %>% group_by(label),
              aes(ymin = stats::predict(loess(min ~ day)), ymax = stats::predict(loess(max ~ day)),
                  color = label),
              alpha = 0.1) +
  geom_smooth(se = F) 

Thanks!

EDIT #2: See bottom for smoothed ribbon. Adopted from https://stackoverflow.com/a/71423425/6851825

EDIT: 2nd option below uses min / max directly to define shaded range.

We could specify a fixed confidence interval by putting the confidence interval into a ribbon layer that uses the stat_smooth calculation, but where we override the y range to use the smooth value plus a constant.

ggplot(data = temp, aes(x = day, y = mean)) +
  stat_smooth(
    geom="ribbon",
    aes(ymax = after_stat(y) + 1,
        ymin = after_stat(y) - 1),
    alpha = 0.1
  ) +
  geom_smooth(se = FALSE)

在此处输入图像描述

Of if you mean you want to use the min and max values directly as your shaded range:

ggplot(data = temp, aes(x = day, y = mean)) +
  geom_ribbon(aes(ymin = min, ymax = max),
              alpha = 0.1) +
  geom_smooth(se = FALSE)

在此处输入图像描述


Adopted from https://stackoverflow.com/a/71423425/6851825 , we can put the min and max into the data frame and make a ribbon that calls predict(loess(y~x)) to calculate the min and max ranges.

temp <- data.frame(day = 1:365, mean = mean,
                   max = max, min = min)

ggplot(data = temp, aes(x = day)) +
  geom_ribbon(alpha = 0.1,
              aes(ymin = predict(loess(min~day)),
                  ymax = predict(loess(max~day)))) +
  geom_smooth(aes(y = mean), se = FALSE) +
  
  # these are to confirm the ranges match what geom_smooth would produce
  geom_smooth(aes(y = max), se = FALSE, linetype = "dashed", size = 0.2) +
  geom_smooth(aes(y = min), se = FALSE, linetype = "dashed", size = 0.2)

在此处输入图像描述


EDIT based on new grouped data:

The prior technique doesn't work with grouped data because the base predict function doesn't "see" groups unless we've put it inside dplyr::group_by and dplyr::mutate . So we can use those to precalculate the values we need in the data = part.

ggplot(data = temp, aes(x = day, y = mean, color = label)) +
  geom_ribbon(data = temp %>% group_by(label) %>%
                mutate(ymin_smooth = stats::predict(loess(min~day)),
                       ymax_smooth = stats::predict(loess(max~day))),
              aes(ymin = ymin_smooth,  ymax = ymax_smooth, fill = label),
              alpha = 0.1) +
  geom_smooth(se = F) 

在此处输入图像描述

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