多个垂直阴影区域

时间:2019-02-16 07:14:00

标签: r area

我正在绘制深度睡眠(y轴)与天(x轴)的比例。我想添加垂直阴影区域以更好地理解(例如,灰色代表周末,橙色代表病假...)。

我尝试使用geom_ribbon(如果数据在WE内,我创建了一个变量值为30,y轴的顶部-在另一列中给出的信息),但是我得到的不是矩形,而是梯形。

在另一篇文章中,有人建议使用“ geom_rect”,如果知道x和y坐标,则建议使用“注释”,但是当我想使用彩色的时,我不知道如何适应我的情况该区域重复到整个周末(由于缺少某些数据,因此并非每7天精确一次)。

你有什么主意吗? 提前非常感谢!

  ggplot(Sleep.data, aes(x = DATEID)) +
  geom_line(aes(y = P.DEEP, group = 1), col = "deepskyblue3") + 
  geom_point(aes(y = P.DEEP, group = 1, col = Sign.deep)) +
  guides(col=FALSE) +
  geom_ribbon(aes(ymin = min, ymax = max.WE), fill = '#6495ED80') +
  facet_grid(MONTH~.) +
  geom_hline(yintercept = 15, col = "forestgreen") +
  geom_hline(yintercept = 20, col = "forestgreen", linetype = "dashed") +
  geom_vline(xintercept = c(7,14,21,28), col = "grey") +
  scale_x_continuous(breaks=seq(0,28,7)) +
  scale_y_continuous(breaks=seq(0,30,5)) +
  labs(x = "Days",y="Proportion of deep sleep stage", title = "Deep sleep") 

Proportion of deep sleep vs time

Head(Sleep.data)

> dput(head(Sleep.data))
structure(list(DATE = structure(c(1L, 4L, 7L, 10L, 13L, 16L), .Label = c("01-Dec-17", 
"01-Feb-18", "01-Jan-18", "02-Dec-17", "02-Feb-18", "02-Jan-18", 
"03-Dec-17", "03-Feb-18", "03-Jan-18", "04-Dec-17", "04-Feb-18", 
"04-Jan-18", "05-Dec-17", "05-Feb-18", "05-Jan-18", "06-Dec-17", 
"06-Feb-18", "06-Jan-18", "07-Dec-17", "07-Feb-18", "07-Jan-18", 
"08-Dec-17", "08-Jan-18", "09-Dec-17", "09-Feb-18", "09-Jan-18", 
"10-Dec-17", "10-Jan-18", "11-Dec-17", "11-Feb-18", "11-Jan-18", 
"12-Dec-17", "12-Jan-18", "13-Dec-17", "13-Feb-18", "13-Jan-18", 
"14-Dec-17", "14-Feb-18", "14-Jan-18", "15-Dec-17", "15-Jan-18", 
"16-Dec-17", "16-Jan-18", "17-Dec-17", "17-Jan-18", "18-Dec-17", 
"18-Jan-18", "19-Dec-17", "19-Jan-18", "20-Dec-17", "21-Dec-17", 
"21-Jan-18", "22-Dec-17", "22-Jan-18", "23-Dec-17", "23-Jan-18", 
"24-Dec-17", "24-Jan-18", "25-Dec-17", "25-Jan-18", "26-Dec-17", 
"26-Jan-18", "27-Dec-17", "27-Jan-18", "28-Dec-17", "28-Jan-18", 
"29-Dec-17", "29-Jan-18", "30-Dec-17", "30-Jan-18", "31-Dec-17", 
"31-Jan-18"), class = "factor"), DATEID = 1:6, MONTH = structure(c(1L, 
1L, 1L, 1L, 1L, 1L), .Label = c("Decembre", "Janvier", "Février"
), class = "factor"), DURATION = c(8.08, 7.43, 6.85, 6.23, 7.27, 
6.62), D.DEEP = c(1.67, 1.37, 1.62, 1.75, 1.95, 0.9), P.DEEP = c(17L, 
17L, 21L, 24L, 25L, 12L), STIMS = c(0L, 0L, 0L, 0L, 390L, 147L
), D.REM = c(1.7, 0.95, 0.95, 1.43, 1.47, 0.72), P.REM = c(17L, 
11L, 12L, 20L, 19L, 9L), D.LIGHT = c(4.7, 5.12, 4.27, 3.05, 3.83, 
4.98), P.LIGHT = c(49L, 63L, 55L, 43L, 49L, 66L), D.AWAKE = c(1.45, 
0.58, 0.47, 0.87, 0.37, 0.85), P.AWAKE = c(15L, 7L, 6L, 12L, 
4L, 11L), WAKE.UP = c(-2L, 0L, 2L, -1L, 3L, 1L), AGITATION = c(-1L, 
-3L, -1L, -2L, 2L, -1L), FRAGMENTATION = c(1L, -2L, 2L, 1L, 0L, 
-1L), PERIOD = structure(c(3L, 3L, 4L, 4L, 4L, 4L), .Label = c("HOLIDAYS", 
"SICK", "WE", "WORK"), class = "factor"), SPORT = structure(c(2L, 
1L, 2L, 2L, 2L, 1L), .Label = c("", "Day", "Evening"), class = "factor"), 
    ACTIVITY = structure(c(6L, 1L, 3L, 4L, 5L, 1L), .Label = c("", 
    "Bkool", "eBike", "Gym", "Natation", "Run"), class = "factor"), 
    TABLETS = c(0.5, 0.5, 0.5, 0.5, 0.5, 0.5), Ratio = c(1.15, 
    2.36, 3.45, 2.01, 5.27, 1.06), Sign = structure(c(2L, 2L, 
    2L, 2L, 2L, 2L), .Label = c("0", "1"), class = "factor"), 
    Sign.ratio = structure(c(2L, 2L, 2L, 2L, 2L, 2L), .Label = c("0", 
    "1"), class = "factor"), Sign.deep = structure(c(2L, 2L, 
    2L, 2L, 2L, 1L), .Label = c("0", "1"), class = "factor"), 
    Sign.awake = structure(c(1L, 2L, 2L, 1L, 2L, 1L), .Label = c("0", 
    "1"), class = "factor"), Sign.light = structure(c(2L, 1L, 
    1L, 2L, 2L, 1L), .Label = c("0", "1"), class = "factor"), 
    index = structure(c(1L, 1L, 1L, 1L, 2L, 1L), .Label = c("0", 
    "1"), class = "factor"), min = c(0, 0, 0, 0, 0, 0), max.WE = c(30, 
    30, 0, 0, 0, 0)), .Names = c("DATE", "DATEID", "MONTH", "DURATION", 
"D.DEEP", "P.DEEP", "STIMS", "D.REM", "P.REM", "D.LIGHT", "P.LIGHT", 
"D.AWAKE", "P.AWAKE", "WAKE.UP", "AGITATION", "FRAGMENTATION", 
"PERIOD", "SPORT", "ACTIVITY", "TABLETS", "Ratio", "Sign", "Sign.ratio", 
"Sign.deep", "Sign.awake", "Sign.light", "index", "min", "max.WE"
), row.names = c(NA, 6L), class = "data.frame")

1 个答案:

答案 0 :(得分:2)

感谢添加数据,这使您更容易准确地了解您正在使用的内容并确认答案确实可以解决您的问题。

我认为创建一个单独的表,使每个连续行的开头和结尾具有相同的PERIOD会有所帮助。我使用dplyr::case_when进行了此操作,假设如果日期是表中的第一行(row_number()== 1),或者它们具有与上一行不同的PERIOD值,则应将日期标记为“开始”。如果日期是表的最后一行,或者日期与下一行不同,则将日期标记为“结束”。我仅保留起点和终点,并将其散布到名为startend的新列中。

library(tidyverse)    
Period_ranges <- Sleep.data %>%
  mutate(period_status = case_when(row_number() == 1      ~ "start",
                               PERIOD != lag(PERIOD)  ~ "start",
                               row_number() == n()    ~ "end",
                               PERIOD != lead(PERIOD) ~ "end",
                               TRUE ~ "other")) %>%
filter(period_status %in% c("start", "end")) %>%
select(DATEID, PERIOD, period_status) %>%
mutate(PERIOD_NUM = cumsum(PERIOD != lag(PERIOD) | row_number() == 1)) %>%
spread(period_status, DATEID)

# Output based on sample data only. If there's a problem with the full data, please add more. To share full data, use `dput(Sleep.data)` or to share 20 rows use `dput(head(Sleep.data, 20))`.
>Period_ranges
   PERIOD PERIOD_NUM end start
 1     WE          1   2     1
 2   WORK          2   6     3

我们现在可以在情节中使用它。如果您要分别切换包含或修饰不同时期类型的外观,则可以使用Period_ranges %>% filter(PERIOD == "WE"),

修改下面的代码
ggplot(Sleep.data, aes(x = DATEID)) +

  # Here I specify that this geom should use its own data.
  # I start the rectangles half a day before and end half a day after to fill the space.
  geom_rect(data = Period_ranges, inherit.aes = F,
            aes(xmin = start - 0.5, xmax = end + 0.5,
                ymin = 0, ymax = 30,
                fill = PERIOD), alpha = 0.5) +
  # Here we can specify the shading color for each type of PERIOD
  scale_fill_manual(values = c(
    "WE" = '#6495ED80',
    "WORK" = "gray60"
  )) +
  # rest of your code

基于数据样本的图表:

enter image description here