ASP 460 2.0 Data Visualisation

Calendar-based Time Series Visualization

R Packages

library(tidyverse)
# install.packages("remotes")
# remotes::install_github("earowang/sugrrants")
library(sugrrants)
library(tsibble)
library(lubridate)
theme_set(theme_bw())

Data

hourly_peds
## # A tibble: 78,755 x 10
##    Date_Time           Date        Year Month   Mdate Day     Time Sensor_ID
##    <dttm>              <date>     <dbl> <ord>   <dbl> <ord>  <dbl>     <dbl>
##  1 2016-01-01 00:00:00 2016-01-01  2016 January     1 Friday     0        18
##  2 2016-01-01 00:00:00 2016-01-01  2016 January     1 Friday     0        13
##  3 2016-01-01 00:00:00 2016-01-01  2016 January     1 Friday     0         3
##  4 2016-01-01 00:00:00 2016-01-01  2016 January     1 Friday     0         9
##  5 2016-01-01 00:00:00 2016-01-01  2016 January     1 Friday     0         6
##  6 2016-01-01 00:00:00 2016-01-01  2016 January     1 Friday     0        25
##  7 2016-01-01 00:00:00 2016-01-01  2016 January     1 Friday     0        30
##  8 2016-01-01 01:00:00 2016-01-01  2016 January     1 Friday     1        18
##  9 2016-01-01 01:00:00 2016-01-01  2016 January     1 Friday     1        13
## 10 2016-01-01 01:00:00 2016-01-01  2016 January     1 Friday     1         3
## # i 78,745 more rows
## # i 2 more variables: Sensor_Name <chr>, Hourly_Counts <dbl>
glimpse(hourly_peds)
## Rows: 78,755
## Columns: 10
## $ Date_Time     <dttm> 2016-01-01 00:00:00, 2016-01-01 00:00:00, 2016-01-01 00~
## $ Date          <date> 2016-01-01, 2016-01-01, 2016-01-01, 2016-01-01, 2016-01~
## $ Year          <dbl> 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 20~
## $ Month         <ord> January, January, January, January, January, January, Ja~
## $ Mdate         <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,~
## $ Day           <ord> Friday, Friday, Friday, Friday, Friday, Friday, Friday, ~
## $ Time          <dbl> 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,~
## $ Sensor_ID     <dbl> 18, 13, 3, 9, 6, 25, 30, 18, 13, 3, 9, 6, 25, 30, 18, 13~
## $ Sensor_Name   <chr> "Collins Place (North)", "Flagstaff Station", "Melbourne~
## $ Hourly_Counts <dbl> 409, 785, 2829, 915, 3643, 2844, 953, 200, 313, 2905, 38~
unique(hourly_peds$Sensor_Name)
## [1] "Collins Place (North)"                 
## [2] "Flagstaff Station"                     
## [3] "Melbourne Central"                     
## [4] "Southern Cross Station"                
## [5] "Flinders Street Station Underpass"     
## [6] "Melbourne Convention Exhibition Centre"
## [7] "Lonsdale St (South)"

Data Visualization

Plot 1

hourly_peds %>%
  filter(Date < as.Date("2016-03-01")) %>% 
  ggplot(aes(x = Time, y = Hourly_Counts, colour = Sensor_Name)) +
  geom_line() +
  facet_calendar(~ Date) + 
  theme_bw() +
  theme(legend.position = "bottom")

Plot 2

hourly_peds %>% 
  ggplot(aes(x = Date, y = Hourly_Counts, colour = Sensor_Name)) +
  geom_line(size = 0.3) +
  facet_grid(
    Sensor_Name ~ ., 
    labeller = labeller(Sensor_Name = label_wrap_gen(20))
  ) + theme(legend.position = "bottom") +
  xlab("Date Time") +
  ylab("Hourly Counts")

Your turn: Level-up plot 2

Plot 3

fs <- hourly_peds %>% 
  filter(Sensor_Name == "Flagstaff Station")
fs
## # A tibble: 11,567 x 10
##    Date_Time           Date        Year Month   Mdate Day     Time Sensor_ID
##    <dttm>              <date>     <dbl> <ord>   <dbl> <ord>  <dbl>     <dbl>
##  1 2016-01-01 00:00:00 2016-01-01  2016 January     1 Friday     0        13
##  2 2016-01-01 01:00:00 2016-01-01  2016 January     1 Friday     1        13
##  3 2016-01-01 02:00:00 2016-01-01  2016 January     1 Friday     2        13
##  4 2016-01-01 03:00:00 2016-01-01  2016 January     1 Friday     3        13
##  5 2016-01-01 04:00:00 2016-01-01  2016 January     1 Friday     4        13
##  6 2016-01-01 05:00:00 2016-01-01  2016 January     1 Friday     5        13
##  7 2016-01-01 06:00:00 2016-01-01  2016 January     1 Friday     6        13
##  8 2016-01-01 07:00:00 2016-01-01  2016 January     1 Friday     7        13
##  9 2016-01-01 08:00:00 2016-01-01  2016 January     1 Friday     8        13
## 10 2016-01-01 09:00:00 2016-01-01  2016 January     1 Friday     9        13
## # i 11,557 more rows
## # i 2 more variables: Sensor_Name <chr>, Hourly_Counts <dbl>
glimpse(fs)
## Rows: 11,567
## Columns: 10
## $ Date_Time     <dttm> 2016-01-01 00:00:00, 2016-01-01 01:00:00, 2016-01-01 02~
## $ Date          <date> 2016-01-01, 2016-01-01, 2016-01-01, 2016-01-01, 2016-01~
## $ Year          <dbl> 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 20~
## $ Month         <ord> January, January, January, January, January, January, Ja~
## $ Mdate         <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,~
## $ Day           <ord> Friday, Friday, Friday, Friday, Friday, Friday, Friday, ~
## $ Time          <dbl> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16~
## $ Sensor_ID     <dbl> 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, ~
## $ Sensor_Name   <chr> "Flagstaff Station", "Flagstaff Station", "Flagstaff Sta~
## $ Hourly_Counts <dbl> 785, 313, 116, 85, 40, 38, 40, 40, 49, 67, 82, 96, 88, 1~
fs_cal <- fs %>%
  frame_calendar(x = Time, y = Hourly_Counts, date = Date)
fs_cal
## # A tibble: 11,567 x 12
##    Date_Time           Date        Year Month   Mdate Day     Time Sensor_ID
##    <dttm>              <date>     <dbl> <ord>   <dbl> <ord>  <dbl>     <dbl>
##  1 2016-01-01 00:00:00 2016-01-01  2016 January     1 Friday     0        13
##  2 2016-01-01 01:00:00 2016-01-01  2016 January     1 Friday     1        13
##  3 2016-01-01 02:00:00 2016-01-01  2016 January     1 Friday     2        13
##  4 2016-01-01 03:00:00 2016-01-01  2016 January     1 Friday     3        13
##  5 2016-01-01 04:00:00 2016-01-01  2016 January     1 Friday     4        13
##  6 2016-01-01 05:00:00 2016-01-01  2016 January     1 Friday     5        13
##  7 2016-01-01 06:00:00 2016-01-01  2016 January     1 Friday     6        13
##  8 2016-01-01 07:00:00 2016-01-01  2016 January     1 Friday     7        13
##  9 2016-01-01 08:00:00 2016-01-01  2016 January     1 Friday     8        13
## 10 2016-01-01 09:00:00 2016-01-01  2016 January     1 Friday     9        13
## # i 11,557 more rows
## # i 4 more variables: Sensor_Name <chr>, Hourly_Counts <dbl>, .Time <dbl>,
## #   .Hourly_Counts <dbl>
glimpse(fs_cal)
## Rows: 11,567
## Columns: 12
## $ Date_Time      <dttm> 2016-01-01 00:00:00, 2016-01-01 01:00:00, 2016-01-01 0~
## $ Date           <date> 2016-01-01, 2016-01-01, 2016-01-01, 2016-01-01, 2016-0~
## $ Year           <dbl> 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2~
## $ Month          <ord> January, January, January, January, January, January, J~
## $ Mdate          <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1~
## $ Day            <ord> Friday, Friday, Friday, Friday, Friday, Friday, Friday,~
## $ Time           <dbl> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1~
## $ Sensor_ID      <dbl> 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,~
## $ Sensor_Name    <chr> "Flagstaff Station", "Flagstaff Station", "Flagstaff St~
## $ Hourly_Counts  <dbl> 785, 313, 116, 85, 40, 38, 40, 40, 49, 67, 82, 96, 88, ~
## $ .Time          <dbl> 0.1842593, 0.1857890, 0.1873188, 0.1888486, 0.1903784, ~
## $ .Hourly_Counts <dbl> 0.9556459, 0.9522512, 0.9508343, 0.9506113, 0.9502877, ~
p_fs <- fs_cal %>% 
  ggplot(aes(x = .Time, y = .Hourly_Counts, group = Date)) +
  geom_line() +
  theme(legend.position = "bottom")

p_fs

prettify(p_fs)

Your turn: Level-up the plot

Plot 4

fs_cal_free <- fs %>% 
  frame_calendar(x = Time, y = Hourly_Counts, date = Date, scale = "free")

p_fs_free <- fs_cal_free %>% 
  ggplot(aes(x = .Time, y = .Hourly_Counts, group = Date)) +
  geom_line() +
  theme(legend.position = "bottom")
prettify(p_fs_free)

Your turn: Level-up the plot

Plot 5

fs_polar <- fs %>% 
  frame_calendar(x = Time, y = Hourly_Counts, date = Date, polar = TRUE)

p_fs_polar <- fs_polar %>% 
  ggplot(aes(x = .Time, y = .Hourly_Counts, group = Date)) + geom_path() +
  theme(legend.position = "bottom")
prettify(p_fs_polar)

Your turn: Level-up the plot

Plot 6

pedestrian_dec <- hourly_peds %>% 
  filter(Month == "December") %>% 
  frame_calendar(
    x = Time, y = Hourly_Counts, date = Date, width = 0.97, height = 0.97
  )

p_boxplot <- pedestrian_dec %>% 
  ggplot() +
  geom_boxplot(
    aes(x = .Time, y = .Hourly_Counts, group = Date_Time),
    outlier.size = 0.3, width = 0.004, position = "identity",
    colour = "grey50"
  )

p_boxplot

prettify(p_boxplot)

Plot 7

p_boxplot_2 <- p_boxplot + 
  geom_smooth(
    aes(.Time, .Hourly_Counts, group = Date), 
    se = FALSE, method = "loess"
  )

prettify(p_boxplot_2)

The content is based on the paper

Wang, E., Cook, D., & Hyndman, R. J. (2020). Calendar-based graphics for visualizing people’s daily schedules. Journal of computational and graphical statistics, 29(3), 490-502.