Search code examples
rggvis

Interactive datetime input on ggvis plots


Let's say you want to make an interactive ggvis plot with datetime data on the X axis: i.e. you want to be able to zoom in on specific times in the plot.

Is this a) possible b) have any workaround or c) better solved by another package?

Take this example data and plot for example:

library(ggvis)

df <- data.frame(time = rep(as.POSIXct("2013-10-10")+(1:100)*60^2,2),
           treatment = c(rep("a",100),rep("b",100)), rate = rnorm(200,0.3,.01), 
           upper = rnorm(200,0.4,.01), lower = rnorm(200,0.2,.01))

df %>%
  group_by(treatment) %>%
  ggvis(~time,~rate,stroke=~treatment) %>%
  layer_ribbons(y=~upper,y2=~lower,fill=~treatment,opacity:=0.2) %>%
  layer_lines() %>%
  scale_datetime("x", nice = "hour")

Solution

  • I think this would be better solved by another package since ggvis doesn't handle this task very elegantly. As an alternative, we could use dygraphs and dyRangeSelector()

    First, we reshape the data in a wide format:

    library(tidyr)
    x <- df %>%
      gather(key, value, -(time:treatment)) %>%
      unite(t, treatment, key) %>%
      spread(t, value) 
    

    This will give you:

    > head(x)
    #                 time   a_lower    a_rate   a_upper   b_lower    b_rate   b_upper
    #1 2013-10-10 01:00:00 0.1988794 0.2903746 0.4031802 0.2089536 0.2851947 0.3850488
    #2 2013-10-10 02:00:00 0.1997263 0.3012017 0.4030821 0.1935425 0.3103502 0.4047333
    #3 2013-10-10 03:00:00 0.1999701 0.2908635 0.3992913 0.1996834 0.2978400 0.3904020
    #4 2013-10-10 04:00:00 0.2045941 0.2947663 0.4140974 0.2184334 0.2969331 0.3979316
    #5 2013-10-10 05:00:00 0.1801551 0.3167674 0.4180428 0.1842388 0.2974034 0.3987412
    #6 2013-10-10 06:00:00 0.1986528 0.2946848 0.3887903 0.1992093 0.3093617 0.4051101
    

    Then, we create an xts object:

    library(xts)
    y <- xts(x[-1], order.by = x$time)  
    

    Finally, we generate the plot.

    library(dygraphs)
    dygraph(y, main = "A nice dygraph with range selector") %>%
      dyAxis("x", drawGrid = FALSE) %>%
      dySeries(c("a_lower", "a_rate", "a_upper"), label = "a") %>%
      dySeries(c("b_lower", "b_rate", "b_upper"), label = "b") %>%
      dyRangeSelector()
    

    You can zoom either using mouse selection or the range selector

    enter image description here