У меня есть циклические данные, и я пытаюсь построить среднее значение, наложенное на полосу стандартного отклонения. Использование geom_ribbon()
имеет ту же проблему, что и geom_line()
, поскольку оно соединяет ближайшие значения x, а не порядок данных. Есть ли способ заполнить данные между двумя путями, а не строками?
Вот пример. Как видно на полученном рисунке, линии стандартного отклонения от geom_ribbon()
соединены ближайшим x, тогда как geom_path()
правильно отображает линии. Желаемый график должен заполнить область между красной и синей линиями стандартного отклонения.
library(tidyverse)
DF <- tibble(
Order = seq(1,20),
x = c(seq(0,18,2), seq(19, 1, -2)),
y = sin(4.5*(Order-1)*pi/180),
sd1 = y + 1,
sd2 = y - 1
)
p <- ggplot(DF, aes(x=x, y=y)) +
geom_ribbon(aes(ymin = sd1, ymax = sd2), fill = 'lightblue', alpha = 0.2) +
geom_path() +
geom_path(aes(y=sd1), col = 'blue') +
geom_path(aes(y=sd2), col = 'red')
ggsave('plot.png', p)
Обновил вопрос, надеюсь, более ясно, к чему я стремлюсь.
Вы сказали «площадь» в единственном числе. Вы имеете в виду, что область между верхней синей линией и нижней красной линией должна быть заполнена? Или следует заполнить область между двумя синими линиями и отдельно область между двумя красными линиями? Или что-то другое? Было бы яснее, если бы вы дали нам два графика: один с правильно нанесенным черным (?) контуром, а другой - с правильно нанесенными лентами.
Там нет обобщающего ответа, поэтому я не предлагаю закрыть, но связан с этим вопросом.
Спасибо. Определенно ищу обобщающий подход, поскольку реальные данные имеют разное количество циклов, и каждый цикл имеет переменное количество точек. Подумываю об использовании группирующей переменной и geom_path, чтобы просто рисовать вертикальные линии между совпадающими точками верхнего и нижнего стандартных отклонений. Не совсем тот оттенок, который мне нужен, но...
Разве не это делает geom_polygon()? Как и geom_path, он соединяет наблюдения в том порядке, в котором они появляются в данных.
Да, спасибо. Требуются серьезные споры, но это сделает свое дело.
library(tidyverse)
library(zoo)
DF <- tibble(
Order = seq(1,20),
x = c(seq(0,18,2), seq(19, 1, -2)),
y = sin(4.5*(Order-1)*pi/180),
sd1 = y + 1,
sd2 = y - 1
)
DF %>%
mutate(sl1 = (sd1 - lag(sd1, default = first(sd1))) / (x - lag(x, default = 1)),
sl2 = (sd2 - lag(sd2, default = first(sd2))) / (x - lag(x, default = 1))) %>%
{full_join(filter(., sl1 < 0) %>% select(-sd2, -sl1, -sl2),
filter(., sl2 >= 0) %>% select(-sd1, -sl1, -sl2))} %>%
arrange(x) %>%
mutate(sd1_app = zoo::na.spline(sd1, na.rm = F),
sd2_app = zoo::na.spline(sd2, na.rm = F)) -> DF1
ggplot(DF, aes(x=x, y=y)) +
geom_ribbon(data = DF1, aes(ymin = sd1_app, ymax = sd2_app),
fill = 'lightblue', alpha = 0.3) +
geom_path() +
geom_path(aes(y=sd1), col = 'blue') +
geom_path(aes(y=sd2), col = 'red')
Created on 2024-06-25 with reprex v2.0.2
Предоставьте описание или изображение, отражающее ожидаемый результат.