1

So a plotly plot has an embedded rangeslider however I do not like the looks of it. The rangeslider in R Shiny looks much better and professional, however how do i connect the two?

Lets say you have a dataframe with some values and a daterange like:

library(lubridate)

    df <- data.frame(
  "Date" = c(seq(ymd('2015-09-15'), ymd('2015-09-24'), by = "1 days")),
  "values" = c(3,6,5,3,5,6,7,7,4,2)
    )

Code for the plotly plot

library(plotly)

    plot_df <- plot_ly(df) 

    plot_df  <- plot_df  %>%  add_lines(type = 'scatter', mode = "lines",
                                      x = ~Date, y = ~values)

Code Shiny

library(shiny)
library(shinydashboard)

  ui <- dashboardPage(
  dashboardHeader(title = "Basic dashboard"),
  dashboardSidebar(),
  dashboardBody(
    # Boxes need to be put in a row (or column)
    fluidRow(
      box(plotlyOutput("plotdf", height = 250)),
      
      box(
        title = "Controls",
        sliderInput("Date", "", min = df$Date[1], tail(df$Date, 1), value = tail(df$Date, 1)
        )
      )
    )
  )
)

server <- function(input, output) {
  output$plotdf<-renderPlotly({
    plot_df
  })
}

shinyApp(ui, server)

enter image description here

H. berg
  • 471
  • 1
  • 3
  • 11

1 Answers1

1

We can use dplyr::filter and pipe it to plot_ly().

    output$plotdf<-renderPlotly({
        filter(df, Date <= input$Date) %>% 
        plot_ly() %>%  
         add_lines(type = 'scatter', mode = "lines",
                                            x = ~Date, y = ~values)
    })

Edit: Below is the plot code separated from the app with a sliderInput to select a range of dates.

library(shiny)
library(dplyr)
library(lubridate)
library(plotly)

source(file = 'my_functions_script.R', local = TRUE)


df <- data.frame(
    "Date" = c(seq(ymd('2015-09-15'), ymd('2015-09-24'), by = "1 days")),
    "values" = c(3,6,5,3,5,6,7,7,4,2)
)


library(shiny)
library(shinydashboard)

ui <- dashboardPage(
    dashboardHeader(title = "Basic dashboard"),
    dashboardSidebar(),
    dashboardBody(
        # Boxes need to be put in a row (or column)
        fluidRow(
            box(plotlyOutput("plotdf", height = 250)),
            
            box(
                title = "Controls",
                shiny::sliderInput("Date", "", min = df$Date[1], tail(df$Date, 1), value = c(df$Date[1],tail(df$Date, 1))
                )
            )
        )
    )
)

server <- function(input, output) {
    output$plotdf<-renderPlotly({
        filter(df,Date >= input$Date[[1]], Date <= input$Date[[2]]) %>% 
            plt()
        
    })
}

shinyApp(ui, server)

enter image description here

jpdugo17
  • 6,816
  • 2
  • 11
  • 23
  • Awsome! However do I need to add the full plotly code of the plot to server? Cause this is an easy plot but my orgininal plot is much more complicated with lots of code....and I wanto add various of these plots in Shiny.....so thereby the server-code will be very long....so I would rather have the plotly plot seperated in a script and call it than in renderPlotly – H. berg Dec 17 '21 at 13:35
  • 1
    @H.berg Yes, we can wrap the plotly code into a function that takes one argument named `data`, and use it inside the server code when needed. Check my edit. – jpdugo17 Dec 17 '21 at 13:46
  • Ah right though not every plot is the same so I neeed various function than I guess...its not possible to so "source(....locatiion of script etc)...at least I trief but didnt work – H. berg Dec 17 '21 at 13:50
  • You can put all the functions in a script located in the working directory and then call `source(file = 'my_functions_script.R', local = TRUE)` below the libraries code. That should work. – jpdugo17 Dec 17 '21 at 14:05
  • Final question: how do I add 2 value sin the Rangeslider in this pipeline explained here: https://stackoverflow.com/questions/38181744/r-shiny-input-slider-range-values/38181817 – H. berg Dec 17 '21 at 14:27
  • 1
    @H.berg To have 2 values in the slider, pass a vector `c(value1, value2)` to the value argument. I edited the code to include it. – jpdugo17 Dec 17 '21 at 14:53