Multiple line graphs using plotly in shiny R - r

I'm new to shiny R and Plotly. I'm trying to build a dashboard that has two drop-down boxes and we take input through these dropdown boxes and plot Plotly graphs. All the datasets have time, temp, and weight columns. time goes on the x-axis and for y-axis we can select either temp or weight or maybe both.
the first drop-down takes the input to which dataset to select.
second dropdown box takes the input to select the variable from the dataset selected.
Most of the things I have figured out, however, y-axis label does not change dynamically. the label is getting (input$variable) instead of temp or weight.
here is the shiny r output
also here is the reproducible example and my code
library(shiny)
library(plotly)
library(DT)
df1 <- data.frame("time" = 1:10, "temp" = c(21,15,31,12,23,45,67,34,54,10), "weight" = c(10,20,30,40,65,35,68,89,100,23), stringsAsFactors = FALSE)
df2 <- data.frame("time" = 1:10, "temp" = c(31,65,31,22,23,45,67,54,54,45), "weight" = c(30,20,40,40,65,85,68,89,14,24), stringsAsFactors = FALSE)
ui <- fluidPage(
titlePanel( div(column(width = 5, h2('title here')), )),
# Input: Selector for choosing dataset
selectInput(inputId = "dataset",
label = "Choose a dataset:",
choices = c("df1","df2")),
selectInput(inputId = "variable",
label = "Variable selection",
choices = c("temp","weight"),
selected = "weight",
multiple = FALSE),
mainPanel(
# Output
tabsetPanel(type = "tabs",
tabPanel("Plot", plotlyOutput('plot')),
tabPanel("Data", DT::dataTableOutput("table")),
tabPanel("Key_metrics", DT::dataTableOutput("Key_metrics")))
)
)
server <- function(input, output) {
dataDf <- reactive({
temp <- get(input$dataset)
})
output$plot <- renderPlotly(
plot_ly(dataDf(), x = ~time, y =~get(input$variable), type = 'scatter', mode = 'lines', name = "temp") %>%
add_trace(dataDf(), x = ~time, y = ~weight, type = 'scatter', mode = 'lines',name = "weight")
)
output$table <- DT::renderDataTable({
dataDf()
})
output$Key_metrics <- DT::renderDataTable({
})
}
shinyApp(ui,server)

You can specify axis labels in layout(). Note that xaxis and yaxis require a list as argument (see here for more details):
output$plot <- renderPlotly(
plot_ly(dataDf(), x = ~time, y =~get(input$variable), type = 'scatter', mode = 'lines', name = "temp") %>%
add_trace(dataDf(), x = ~time, y = ~weight, type = 'scatter', mode = 'lines',name = "weight") %>%
layout(xaxis = list(title = "Time"), yaxis = list(title = input$variable))
)
Edit: following a comment, here's how to plot two lines if two variables are selected and one otherwise (don't forget to put multiple = TRUE in selectInput():
library(shiny)
library(plotly)
library(DT)
df1 <- data.frame("time" = 1:10, "temp" = c(21,15,31,12,23,45,67,34,54,10), "weight" = c(10,20,30,40,65,35,68,89,100,23), stringsAsFactors = FALSE)
df2 <- data.frame("time" = 1:10, "temp" = c(31,65,31,22,23,45,67,54,54,45), "weight" = c(30,20,40,40,65,85,68,89,14,24), stringsAsFactors = FALSE)
ui <- fluidPage(
titlePanel( div(column(width = 5, h2('title here')), )),
# Input: Selector for choosing dataset
selectInput(inputId = "dataset",
label = "Choose a dataset:",
choices = c("df1","df2")),
selectInput(inputId = "variable",
label = "Variable selection",
choices = c("temp","weight"),
selected = "weight",
multiple = TRUE),
mainPanel(
# Output
tabsetPanel(type = "tabs",
tabPanel("Plot", plotlyOutput('plot')),
tabPanel("Data", DT::dataTableOutput("table")),
tabPanel("Key_metrics", DT::dataTableOutput("Key_metrics")))
)
)
server <- function(input, output) {
dataDf <- reactive({
temp <- get(input$dataset)
})
output$plot <- renderPlotly({
if (length(input$variable) > 1){
plot_ly(dataDf(), x = ~time, y =~get(input$variable[1]),
type = 'scatter', mode = 'lines', name = "temp") %>%
add_trace(dataDf(), x = ~time, y = ~get(input$variable[2]),
type = 'scatter', mode = 'lines',name = "weight") %>%
layout(xaxis = list(title = "Time"))
}
else {
plot_ly(dataDf(), x = ~time, y =~get(input$variable[1]), type = 'scatter', mode = 'lines', name = "temp") %>%
add_trace(dataDf(), x = ~time, y = ~get(input$variable[1]), type = 'scatter', mode = 'lines',name = "weight") %>%
layout(xaxis = list(title = "Time"), yaxis = list(title = input$variable))
}
})
output$table <- DT::renderDataTable({
dataDf()
})
output$Key_metrics <- DT::renderDataTable({
})
}
shinyApp(ui,server)
Put what you want as y-axis label based on the original answer. Note that this answer only works if there are two choices.

Related

how to add reactive x and y axis labels to shiny plotly graph?

I am struggling to find a way to add axis labels to this plotly graph. Since it's a bit different than when I've used plotly or even ggplot outside of apps, I can't seem to make it work. Any tips?
I would need the x and y axis labels to change with the widget on the right side of the code. I'm also not sure if the labels already show and its a matter of the graph being too large to show them.
library(shiny)
library(plotly)
library(tibble)
library(tidyverse)
library(tidyr)
library(readr)
library(dplyr)
library(ggplot2)
library(gapminder)
#read data
gm <- gapminder
# Define UI ----
ui <- fluidPage(
column(3,offset = 4, titlePanel("Explore Gapminder Data with Shiny")),
headerPanel('Graphs'),
mainPanel(
plotlyOutput('plot')
),
sidebarPanel(
#variable selection for x-axis
selectInput(inputId ='xvrbl', #The input slot that will be used to access the value.
label = 'X-Axis Variable', #Display label for the control, or NULL for no label.
choices = colnames(gm), #List of values to select from
selected = 'CO2 emissions (metric tons per capita)'
),
checkboxInput(inputId = "LogX",
label = "Log Transform",
value = FALSE),
#variable selection for y-axis
selectInput(inputId ='yvrbl', #The input slot that will be used to access the value.
label = 'Y-Axis Variable', #Display label for the control, or NULL for no label.
choices = colnames(gm), #List of values to select from
selected = 'gdpPercap'
),
checkboxInput(inputId = "LogY",
label = "Log Transform",
value = FALSE),
# date range - slider
sliderInput(
inputId = "time",
label = "Years",
min = min(gm$year),
max = max(gm$year),
step = 5,
value = range(gm$year)
)
)
)
server <- function(input, output) {
x <- reactive({
x <- dat()[[input$xvrbl]]
if (input$LogX) x <- log(x)
return(x)
})
y <- reactive({
y <- dat()[[input$yvrbl]]
if (input$LogY) y <- log(y)
return(y)
})
dat <- reactive({
subset(gm, year >= input$time[[1]], year <= input$time[[2]])
})
output$plot <- renderPlotly({
plot_ly(
x = x(),
y = y(),
type = "scatter",
mode = "markers",
color = dat()$continent
)
})
}
# Run the app
shinyApp(ui = ui, server = server)
You should specify the layout parameter to renderPlotly:
output$plot <- renderPlotly({
plot_ly(
x = ~x(),
y = ~y(),
type = "scatter",
mode = "markers",
color = dat()$continent) %>%
layout(
yaxis = list(title = input$yvrbl),
xaxis = list(title = input$xvrbl)
)
})

R shiny: How to copy data derived from plotly_selection events into a data frame/table and update each time by pressing an actionButton?

I'm putting together a shiny app to play around with some athlete GPS data. Essentially, I'm looking to structure my script so that each time the user selects an area of interest on the plotly plot and the "Add" actionButton is clicked, the table below will add the calculated Start_time, Time_at_peak, Max_velocity, Time_to_peak, and Distance_to_peak values.
The issue can be seen in the GIF below: - Once the area of interest is selected and the "Add" button clicked, the first values seem correct. However, when the user selects a second area of interest to add to the table, it overwrites the initial entry and will keep overwriting each time a new selection is made. This is seemingly because because the code is inside the observeEvent(event_data("plotly_selected"), which, confusingly, it needs to be in order to calculate the variables of interest.
I'm currently a little stumped and can't seem to find any relevant information. As such, any guidance would be greatly appreciated!
Here is a we transfer link to some test data that can be uploaded to the app: https://wetransfer.com/downloads/5a7c5da5a7647bdbe133eb3fdac79c6b20211119052848/afe3e5
library(shiny)
library(readr)
library(DT)
library(dplyr)
library(plotly)
library(lubridate)
library(tidyr)
library(purrr)
library(htmlwidgets)
library(shinydashboard)
library(dashboardthemes)
library(shinyjs)
x_df <- data.frame(Start_time = character(1), Time_at_peak = character(1), Max_velocity = integer(1),
Time_to_peak = integer(1), Distance_to_peak = integer(1))
x_df$Start_time <- as.character("0:00:00.0")
x_df$Time_at_peak <- as.character("0:00:00.0")
x_df$Max_velocity <- as.integer(0)
x_df$Time_to_peak <- as.integer(0)
x_df$Distance_to_peak <- as.integer(0)
runApp(shinyApp(
ui=(fluidPage(
titlePanel("Event to Table"),
mainPanel(
fileInput(
inputId = "filedata",
label = "Upload data file (.csv)",
accept = c(".csv")),
plotlyOutput('myPlot'),br(),br(),br(),br(),
DTOutput("testing"), br(), br(),
fluidRow(
valueBoxOutput("starttime", width = 2),
valueBoxOutput("endtime", width = 2),
valueBoxOutput("maxvelocity", width = 2),
valueBoxOutput("timediff", width = 3),
valueBoxOutput("distance", width = 3)
),
useShinyjs(),
fluidRow(
div(style = "text-align:center", actionButton("Add", "Add Data to Table"),
downloadButton("export", "Export Table as .CSV"))), br(),
DTOutput(outputId = "table")))
),
server = (function(input, output, session) {
data<-reactive({
req(input$filedata)
read.csv(input$filedata$datapath, header = TRUE)%>%
rename(Velocity = 'Speed..m.s.',
Player = 'Player.Display.Name',
Latitude = 'Lat',
Longtitude = 'Lon',
AccelImpulse = 'Instantaneous.Acceleration.Impulse',
HeartRate = 'Heart.Rate..bpm.')
})
observe({
thedata<-data()
updateSelectInput(session, 'y', choices = names(data))
})
output$myPlot = renderPlotly({
plot_ly(data = data(), x = ~Time, y = ~Velocity, height = 450,
marker =list(color = 'rgb(132,179,202)', size = 0.1),
line = list(color = 'rgb(132,179,202)', size = 0.1, width = 0.9),
type = 'scatter', mode = 'markers+lines') %>%
layout(dragmode = "select",
showlegend = F,
title = list(text = 'Velocity Trace', font = list(size = 20)),
xaxis = list(title = list(text = "", standoff = 0), nticks = 10),
yaxis = list(title = list(text = "Velocity (m/s)"), nticks = 5, gridcolor = "#46505a"),
font = list(color = 'black'),
margin = list(t = 70))
})
observeEvent(event_data("plotly_selected"), {
event.data <- event_data("plotly_selected")
if (max(event.data$y) < 1.5) {
maxvel <- (max(event.data$y))
maxpos <- match(maxvel, event.data$y)
}
else {
filter1 <- filter (event.data, event.data$y > 1.5)
maxvel <- (max(filter1$y))
maxpos <- match(maxvel, event.data$y)
}
zero_val <- function(x) x == 0
zero_index <- event.data$y[1:maxpos] %>% detect_index(zero_val, .dir = "backward")
if (zero_index==0) {starttime <- event.data$x[1]}
else {starttime <- event.data$x[zero_index]}
endvel <- which.max(event.data$y)
endtime <- event.data$x[endvel]
timediff <- paste(today(), endtime) %>% as_datetime() - paste(today(), starttime) %>% as_datetime()
sprint <- as_tibble(event.data$y[zero_index:endvel])
ms <- as_tibble(rep(0.1, count(sprint)))
time_vel <- cbind(ms, sprint)
distance <- sum(time_vel[1]*time_vel[2])
sprintselect <- as_tibble(cbind(Start_time = starttime,
Time_at_peak = endtime,
Max_velocity = round(maxvel, 2),
Time_to_peak = round(timediff, 1),
Distance_to_peak = round(distance, 1)))
values <- reactiveValues()
values$df <- x_df
addData <- observe({
if(input$Add > 0) {
newLine <- isolate(data.frame(Start_time = sprintselect$Start_time, Time_at_peak = sprintselect$Time_at_peak,
Max_velocity = sprintselect$Max_velocity,
Time_to_peak = sprintselect$Time_to_peak,
Distance_to_peak = sprintselect$Distance_to_peak,
stringsAsFactors= FALSE))
values$df <- isolate(rbind(values$df, newLine))}
})
output$testing <- renderDataTable({values$df})
})
})
))
I've managed to figure it out and thought I'd post an answer rather than delete the question - just in case someone out there is looking to do a similar thing and they are unsure how to do it.
Firstly, I removed the pre-populated table x_df from the beginning - it was no longer required.
Although I thought the code needed to sit inside the observeEvent(event_data("plotly_selected") to function correctly, it did not - thankfully, because that was at the root of the issue. Instead, I used observeEvent(input$Add, { (which is the correct code to use as opposed to if(input$Add > 0)) to anchor the event to the click of the Add button.
The values <- reactiveValues() was placed outside the observeEvent() and an IF statement was used to either add the data to the values$df data frame on it's own if it was the first selection, or bind it to the existing saved data.
Here's the new code and a GIF demonstrating.
library(shiny)
library(readr)
library(DT)
library(dplyr)
library(plotly)
library(lubridate)
library(tidyr)
library(purrr)
library(htmlwidgets)
library(shinydashboard)
library(dashboardthemes)
library(shinyjs)
runApp(shinyApp(
ui=(fluidPage(
titlePanel("Event to Table"),
mainPanel(
fileInput(
inputId = "filedata",
label = "Upload data file (.csv)",
accept = c(".csv")),
plotlyOutput('myPlot'),br(),br(),br(),br(),
DTOutput("testing"), br(), br(),
fluidRow(
valueBoxOutput("starttime", width = 2),
valueBoxOutput("endtime", width = 2),
valueBoxOutput("maxvelocity", width = 2),
valueBoxOutput("timediff", width = 3),
valueBoxOutput("distance", width = 3)
),
useShinyjs(),
fluidRow(
div(style = "text-align:center", actionButton("Add", "Add Data to Table"),
downloadButton("export", "Export Table as .CSV"))), br(),
DTOutput(outputId = "table")))
),
server = (function(input, output, session) {
values <- reactiveValues(df_data = NULL)
data<-reactive({
req(input$filedata)
read.csv(input$filedata$datapath, header = TRUE)%>%
rename(Velocity = 'Speed..m.s.',
Player = 'Player.Display.Name',
Latitude = 'Lat',
Longtitude = 'Lon',
AccelImpulse = 'Instantaneous.Acceleration.Impulse',
HeartRate = 'Heart.Rate..bpm.')
})
observe({
thedata<-data()
updateSelectInput(session, 'y', choices = names(data))
})
output$myPlot = renderPlotly({
plot_ly(data = data(), x = ~Time, y = ~Velocity, height = 450,
marker =list(color = 'rgb(132,179,202)', size = 0.1),
line = list(color = 'rgb(132,179,202)', size = 0.1, width = 0.9),
type = 'scatter', mode = 'markers+lines') %>%
layout(dragmode = "select",
showlegend = F,
title = list(text = 'Velocity Trace', font = list(size = 20)),
xaxis = list(title = list(text = "", standoff = 0), nticks = 10),
yaxis = list(title = list(text = "Velocity (m/s)"), nticks = 5, gridcolor = "#46505a"),
font = list(color = 'black'),
margin = list(t = 70))
})
observeEvent(input$Add, {
event.data <- event_data("plotly_selected")
if (max(event.data$y) < 1.5) {
maxvel <- (max(event.data$y))
maxpos <- match(maxvel, event.data$y)
}
else {
filter1 <- filter (event.data, event.data$y > 1.5)
maxvel <- (max(filter1$y))
maxpos <- match(maxvel, event.data$y)
}
zero_val <- function(x) x == 0
zero_index <- event.data$y[1:maxpos] %>% detect_index(zero_val, .dir = "backward")
if (zero_index==0) {starttime <- event.data$x[1]}
else {starttime <- event.data$x[zero_index]}
endvel <- which.max(event.data$y)
endtime <- event.data$x[endvel]
timediff <- paste(today(), endtime) %>% as_datetime() - paste(today(), starttime) %>% as_datetime()
sprint <- as_tibble(event.data$y[zero_index:endvel])
ms <- as_tibble(rep(0.1, count(sprint)))
time_vel <- cbind(ms, sprint)
distance <- sum(time_vel[1]*time_vel[2])
sprintselect <- as_tibble(cbind(Start_time = starttime,
Time_at_peak = endtime,
Max_velocity = round(maxvel, 2),
Time_to_peak = round(timediff, 1),
Distance_to_peak = round(distance, 1)))
newLine <- isolate(data.frame(Start_time = sprintselect$Start_time, Time_at_peak = sprintselect$Time_at_peak,
Max_velocity = sprintselect$Max_velocity,
Time_to_peak = sprintselect$Time_to_peak,
Distance_to_peak = sprintselect$Distance_to_peak,
stringsAsFactors= FALSE))
if (is.null(values$df)){
values$df <- newLine}
else {
values$df <- isolate(rbind(values$df, newLine))}
output$testing <- renderDataTable({values$df})
})
})
))

Selecting many items from the list in R

I created an application in Shiny where I would like to choose multiple items from the drop-down menu. Unfortunately, I don't know how to make items on the list reduce after a given menu selection. By which all lines merge into a whole. what should I add in the code so that each model is a separate line. Below I put a picture with charts.
My code:
library(shiny)
library(plotly)
library(readxl)
library(shinyWidgets)
library(shinydashboard)
library(shinyjs)
library(DT)
df1 <- data.frame(Month = rep(month.abb[1:12],10,replace = TRUE), Model = paste0('Ferrari ', rep(LETTERS[1:10], each = 12)),
Value = sample(c(0:300),120, replace = T),
Car = rep('Ferrari', 10,each = 12), Year = rep(2019:2020, each = 60),Country = rep(c("USA","DE"), each = 12, times = 5), stringsAsFactors = F)
df2 <- data.frame(Month = rep(month.abb[1:12],10,replace = TRUE), Model = paste0('Porsche ', rep(LETTERS[1:10], each = 12)),
Value = sample(c(0:300),120, replace = T),
Car = rep('Porsche', 10,each = 12), Year = rep(2019:2020, each = 60), Country = rep(c("USA","DE"), each = 12, times = 5),stringsAsFactors = F)
data <-rbind(df1, df2)
ui <- fluidPage(
titlePanel("Test"),
sidebarLayout(
sidebarPanel( width = 3,
uiOutput("category1"),
uiOutput("category2"),
uiOutput("category3"),
uiOutput("category4")),
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("Plot", plotlyOutput("plot", height = 550,width = 1000))
)
)
)
)
server <- function(input, output,session) {
output$category1 <- renderUI({
selectInput('cat1', 'Choose year:', multiple = T, selected = NULL, choices = sort(as.numeric(unique(data$Year))))
})
df_subset <- eventReactive(input$cat1,{
if(input$cat1=="All") {df_subset <- data}
else{df_subset <- data[data$Year == input$cat1,]}
})
df_subset1 <- reactive({
if(is.null(input$cat2)){df_subset()} else {df_subset()[df_subset()$Country %in% input$cat2,]}
})
output$category2 <- renderUI({
selectInput('cat2', 'Choose country:', choices = sort(as.character(unique(df_subset()$Country))), multiple = T, selected = NULL)
})
df_subset2 <- reactive({
if(is.null(input$cat3)){df_subset1()} else {df_subset1()[df_subset1()$Car %in% input$cat3,]}
})
output$category3 <- renderUI({
selectInput('cat3', 'Choose car:', choices = sort(as.character(unique(df_subset1()$Car))), multiple = F, selected = NULL)
})
df_subset3 <- reactive({
if(is.null(input$cat4)){df_subset2()} else {df_subset2()[df_subset2()$Model %in% input$cat4,]}
})
output$category4 <- renderUI({
pickerInput('cat4', 'Choose model:', choices = sort(as.character(unique(df_subset2()$Model))), multiple = TRUE, selected = NULL)
})
output$plot <- renderPlotly({
xform <- list(categoryorder = "array",
categoryarray = df_subset3()$Month,
title = " ",
nticks=12)
plot_ly(data=df_subset3(), x=~Month, y = ~Value, type = 'scatter', mode = 'lines', name = 'Value') %>%
layout(title = " ",xaxis = xform) %>%
layout(legend = list(orientation = 'h', xanchor = "center", y=1.1, x=0.5))
})
}
shinyApp(ui, server)
To display each model as a separate line on the plot, you can assign the Model column of your dataset to the color parameter of plot_ly this way:
plot_ly( data = df_subset3(), x = ~Month, y = ~Value, color = ~Model, ...)

Filter Plotly Bar Chart with dropdown box selection

I have a static bar chart in Plotly, however the data that I am pulling in is a lot bigger than I realised and there is too much for the chart to show anything meaningful. In the UI I have a dropdown box with a selection of US States and I'd like to be able to filter the bar chart based on the users dropdown box selection. Is there a simple way of filtering the DF?
output$County_Chart <- renderPlotly({
validate(
need(County_data(),""))
ct_Plot_Data <- County_data()
Bar <- plot_ly(ct_Plot_Data, x = ct_Plot_Data$Value, y = ct_Plot_Data[,c("COUNTY")], type = 'bar',
name = 'Value', marker = list(color = 'rgb((49,130,189)', orientation = 'h')) %>%
layout(
yaxis = list(title = "",
categoryorder = "array",
categoryarray = ~COUNTY)
) %>%
add_trace(x = ct_Plot_Data$Population, name = 'Population', marker = list(color = 'rgb(204, 204, 204)'))
Bar
})
Thanks in advance
As you haven't provided any example data, please check the following example:
library(shiny)
library(plotly)
library(datasets)
DF <- as.data.frame(state.x77)
ui <- fluidPage(
selectizeInput("vars", "Select variables", names(DF), multiple = TRUE, options = list('plugins' = list('remove_button'))),
selectizeInput("states", "Select states", rownames(DF), multiple = TRUE, options = list('plugins' = list('remove_button'))),
plotlyOutput("Bar")
)
server <- function(input, output, session) {
filteredDF <- reactive({
req(input$states, input$vars)
cbind(stack(DF[input$states, ], select = input$vars), states = rownames(DF[input$states,]))
})
output$Bar <- renderPlotly({
req(filteredDF())
p <- plot_ly(filteredDF(), x=~ind, y= ~values, type = "bar", color = ~states)
p
})
}
shinyApp(ui, server)

R Plotly extendTraces: Change to incremental and clear data

I am trying out the R Streaming example for extendTraces on Plotly. I am trying to add a functionality to the chart such that it would clear all the data as the browser starts stalling after some time (eg., an actionButton, etc). Is there a way to stop the trace and clear the trace/data on a second click of the actionButton ? Alternatively, is it possible to make the chart incremental, such that the entire data isn't getting stored locally.
https://plot.ly/r/streaming/#streaming-in-r
library(shiny)
library(plotly)
rand <- function() {
runif(1, min=1, max=9)
}
ui <- fluidPage(
includeCSS("styles.css"),
headerPanel(h1("Streaming in Plotly: Multiple Traces", align = "center")),
br(),
div(actionButton("button", "Extend Traces"), align = "center"),
br(),
div(plotlyOutput("plot"), id='graph')
)
server <- function(input, output, session) {
p <- plot_ly(
type = 'scatter',
mode = 'lines'
) %>%
add_trace(
y = c(rand(),rand(),rand()),
line = list(
color = '#25FEFD',
width = 3
)
) %>%
add_trace(
y = c(rand(),rand(),rand()),
line = list(
color = '#636EFA',
width = 3
)
) %>%
layout(
yaxis = list(range = c(0,10))
)
output$plot <- renderPlotly(p)
observeEvent(input$button, {
while(TRUE){
Sys.sleep(1)
plotlyProxy("plot", session) %>%
plotlyProxyInvoke("extendTraces", list(y=list(list(rand()), list(rand()))), list(1,2))
}
})
}
shinyApp(ui, server)
Thanks in advance,
Raj.
Hi maybe you could do something like this?
library(shiny)
library(plotly)
library(shinyjs)
rand <- function() {
runif(1, min=1, max=9)
}
ui <- fluidPage(
# includeCSS("styles.css"),
headerPanel(h1("Streaming in Plotly: Multiple Traces", align = "center")),
br(),
div(actionButton("button", "Extend Traces"),actionButton("buttonReset", "Reset Traces"), align = "center"),
br(),
div(plotlyOutput("plot"), id='graph'),
useShinyjs()
)
server <- function(input, output, session) {
values <- reactiveValues()
values$p <- plot_ly(
type = 'scatter',
mode = 'lines'
) %>%
add_trace(
y = c(rand(),rand(),rand()),
line = list(
color = '#25FEFD',
width = 3
)
) %>%
add_trace(
y = c(rand(),rand(),rand()),
line = list(
color = '#636EFA',
width = 3
)
) %>%
layout(
yaxis = list(range = c(0,10))
)
output$plot <- renderPlotly({values$p})
observe({
invalidateLater(1000, session)
req(input$button > 0)
plotlyProxy("plot", session) %>%
plotlyProxyInvoke("extendTraces", list(y=list(list(rand()), list(rand()))), list(1,2))
})
observeEvent(input$buttonReset,{
values$p <- plot_ly(
type = 'scatter',
mode = 'lines'
) %>%
add_trace(
y = c(rand(),rand(),rand()),
line = list(
color = '#25FEFD',
width = 3
)
) %>%
add_trace(
y = c(rand(),rand(),rand()),
line = list(
color = '#636EFA',
width = 3
)
) %>%
layout(
yaxis = list(range = c(0,10))
)
runjs("Shiny.onInputChange('button',0)")
})
}
shinyApp(ui, server)
Hope this helps!!

Resources