将时间间隔绘制为分段

时间:2019-03-15 15:11:41

标签: r datetime ggplot2 plot

我有以下数据框:

test_df <- structure(list(system = c("A", "B", "B", "C", "D", "B", "B", 
"C", "B", "B", "A", "D", "D", "B", "E", NA, NA, "B", "A", "D"
), type = c(2L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 2L, 1L, 
2L, 1L, 1L, 2L, 2L, 1L, 1L), start_date = structure(c(16567, 
16604, 16324, 16595, 16111, 17597, 16784, 16648, 16121, 16549, 
16438, 16484, 15997, 16488, 16708, 16121, 16327, 16329, 17010, 
16342), class = "Date"), end_date = structure(c(16995, 16984, 
16661, 16909, 16414, 17843, 16990, 16853, 16323, 16751, 16622, 
16665, 16154, 16624, 16839, 16251, 16456, 16456, 17134, 16458
), class = "Date"), event_duration = c(428, 380, 337, 314, 303, 
246, 206, 205, 202, 202, 184, 181, 157, 136, 131, 130, 129, 127, 
124, 116)), row.names = c(NA, -20L), class = c("tbl_df", "tbl", 
"data.frame"))
test_df
#>    system type start_date   end_date event_duration
#> 1       A    2 2015-05-12 2016-07-13            428
#> 2       B    2 2015-06-18 2016-07-02            380
#> 3       B    2 2014-09-11 2015-08-14            337
#> 4       C    2 2015-06-09 2016-04-18            314
#> 5       D    1 2014-02-10 2014-12-10            303
#> 6       B    1 2018-03-07 2018-11-08            246
#> 7       B    1 2015-12-15 2016-07-08            206
#> 8       C    2 2015-08-01 2016-02-22            205
#> 9       B    1 2014-02-20 2014-09-10            202
#> 10      B    2 2015-04-24 2015-11-12            202
#> 11      A    2 2015-01-03 2015-07-06            184
#> 12      D    2 2015-02-18 2015-08-18            181
#> 13      D    1 2013-10-19 2014-03-25            157
#> 14      B    2 2015-02-22 2015-07-08            136
#> 15      E    1 2015-09-30 2016-02-08            131
#> 16   <NA>    1 2014-02-20 2014-06-30            130
#> 17   <NA>    2 2014-09-14 2015-01-21            129
#> 18      B    2 2014-09-16 2015-01-21            127
#> 19      A    1 2016-07-28 2016-11-29            124
#> 20      D    1 2014-09-29 2015-01-23            116

对于每个system,我想为每个type事件绘制不同颜色的分段序列,从start_dateend_date结束。例如,对于系统A,我想绘制两个段序列:

  • 一个与类型1的事件相对应的事件,其中包含一个分段,该分段从2016-07-28开始,到2016-11-29结束
  • 与类型2的事件相对应的另一个,包含两个段,一个段从2015-01-03开始到2015-07-06结束,另一个段从2015-05-122016-07-13结束。如您所见,序列中的事件可以重叠。我不确定如何确保用户仍可以区分事件:也许有人可以使用箭头或竖线或其他方式来显示事件的开始和结束。

理想情况下,每个系统的图应位于不同的方面,因为我认为将所有图放在同一图上会造成完全混乱(当然,实际数据帧比此样本数据帧大得多)

对于系统B,我将有3个段对应于类型1的事件,5个段对应于类型2的事件,依此类推。如何创建我想要的情节?我希望有一个ggplot2解决方案。

1 个答案:

答案 0 :(得分:1)

一种选择是使用抖动来避免过度绘制起点和终点。这种方法是否奏效取决于您要绘制多少段。

为确保能够将线的y方向调整为相同的量,可以将抖动添加到df本身并使用它来绘制线段:

test_df$jitter <- jitter(test_df$type, amount = 0.25)

ggplot(test_df) + 
  geom_segment(aes(x=start_date, xend=end_date, y=jitter, yend=jitter)) + 
  facet_wrap(~system) +
  scale_y_continuous(breaks=c(1,2), labels=c(1,2)) +
  theme(panel.grid.minor.y = element_blank())

enter image description here

您也可以按照建议使用开始和结束指示符,以帮助强调片段的结尾,但是如果片段的数量很大,这可能只会增加噪音。

ggplot(test_df) + 
  geom_point(aes(x=start_date, y=jitter), size=1) +
  geom_segment(aes(x=start_date, xend=end_date, y=jitter, yend=jitter), 
                   arrow=arrow(30,unit(1.25,"mm"),"last","closed")) + 
  facet_wrap(~system) +
  scale_y_continuous(breaks=c(1,2), labels=c(1,2)) +
  theme(panel.grid.minor.y = element_blank())

enter image description here