Search code examples
rdatetimezoomingshiny

Zoomable shiny plot using POSIXct date ranges


I am trying to amend my shiny code so that my plot is made zoomable.

The problem is, my x axis uses as.POSIXct dates as their limits.

For example, a working version of the current app is:

library(shiny)
ui <- fluidPage(selectInput(inputId = "data",label="Make a choice", choices=c("A","B")), 
                plotOutput("plot1"),dateInput(inputId = "lowerlimit", label="Lower Date",value="2016-01-01"), dateInput(inputId = "upperlimit",label="Upper Date"))

server <- function(input,output){
  output$plot1 <- renderPlot({
    dates=seq(as.POSIXct("2016-01-01 00:00:00",tz="UTC"), as.POSIXct("2016-06-01 23:45:00",tz="UTC"),by="15 min")
    values=rnorm(14688)
    data=data.frame(Date=dates,Data=values)
    ggplot(data, aes(Date, Data))+geom_line()+
      scale_x_datetime(limits=c(as.POSIXct(input$lowerlimit), as.POSIXct(input$upperlimit)), labels = date_format("%d-%m-%y"))+ylab("")+
      ggtitle("My Plot")+xlab("")
  })
}

shinyApp(ui=ui, server=server)

However, I want to make plot1 zoomable. I have been trying to follow this example but since my x axis using dates, it does not seem to work.

I have tried:

library(shiny)
ui <- fluidPage(selectInput(inputId = "data",label="Make a choice", choices=c("A","B")), 
                plotOutput("plot1",dblclick = "plot1_dblclick", brush = brushOpts(id="plot1_brush",resetOnNew = T)),
                dateInput(inputId = "lowerlimit", label="Lower Date",value="2016-01-01"), 
                dateInput(inputId = "upperlimit",label="Upper Date"))

server <- function(input,output){

  ranges <- reactiveValues(x = NULL, y = NULL)

  output$plot1 <- renderPlot({

    if (!is.null(ranges$x)) {
      ranges$x <- as.POSIXct(ranges$x, format = "%d-%m-%y",tz="UTC")
    }

    dates=seq(as.POSIXct("2016-01-01 00:00:00",tz="UTC"), as.POSIXct("2016-06-01 23:45:00",tz="UTC"),by="15 min")
    values=rnorm(14688)
    data=data.frame(Date=dates,Data=values)

    ggplot(data, aes(Date, Data))+geom_line()+
      scale_x_datetime(limits=c(as.POSIXct(input$lowerlimit), as.POSIXct(input$upperlimit)), labels = date_format("%d-%m-%y"))+ylab("")+
      ggtitle("My Plot")+xlab("")
  })
  observeEvent(input$plot1_dblclick, {
    brush <- input$plot1_brush
    if (!is.null(brush)) {
      ranges$x <- c(brush$xmin, brush$xmax)
      ranges$y <- c(brush$ymin, brush$ymax)

    } else {
      ranges$x <- NULL
      ranges$y <- NULL
    }
  })
}

shinyApp(ui=ui, server=server)

But I get an error which says "Origin must be supplied". I know that I have still got my lowerlimit and upperlimit as the scale_x_datetime arguments, but I still want this to be the case, and the axis limits change only when a portion of the plot has been selected to zoom into.


Solution

  • try dygraph to plot with xaxis zoom

    https://rstudio.github.io/dygraphs/

    library(shiny)
    library(dygraphs)
    ui <- fluidPage(selectInput(inputId = "data",label="Make a choice",         choices=c("A","B")), 
                dygraphOutput("plot1")
    )
    server <- function(input,output){
      output$plot1 <- renderDygraph({
    
    
    data=as.ts(rnorm(14688),start="2016-01-01" ,end=  "2016-06-01") 
    
    dygraph(data) %>% dyRangeSelector(dateWindow = c("2016-01-01",  "2016-06-01 23:45:00"))
    
      })
    }
    
    shinyApp(ui=ui, server=server)