Update 3: new test app with dropdownbutton issue
library(shiny)
library(shinydashboard)
library(plotly)
library(shinyWidgets)
rm(list = ls(), envir = environment()) ## to prevent cross over from old runs
testData = data.frame(day = sample(seq(as.Date('1999/01/01'), as.Date('2000/01/01'), by="day"), 24), frequency = sample(1:5, 24, replace = T ), datecoloring = sample(1:2, 24, replace = T ))
testData$dayPOSIXct <- as.POSIXct(testData$day)
dateRangeMin <- min(testData$day)
dateRangeMax <- max(testData$day)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
menuItem("Testpage", tabName = "Testpage", icon = icon("home"))
),
dashboardBody(
tabItems(
# 1) Test Tab ---------------------------------------------------------------
tabItem(tabName = "Testpage",
actionButton(inputId = 'Load', label = 'Data'),
dropdownButton(inputId= "TestButton", label = NULL,
plotlyOutput('testplot', width = 700, height = 500),
icon = icon("list-alt"),
tooltip = tooltipOptions(title = "Click to open and render the plot"), width = "1670px")
)
)
),
title = "Dashboard example"
)
server <- function(input, output,session) {
values <- reactiveValues()
observeEvent(input$Load, {
values$testData <- testData
})
output$testplot <- renderPlotly({
req(values$testData)
p <- plot_ly(data = values$testData, source = 'testplot',
color = as.factor(values$testData$datecoloring), colors = c('#339fff', '#eaf5ff'),
opacity= 0.5, showlegend = T,
marker = list(line = list(width = 2, color = '#0000ff')),
hoverinfo = "text",
text = ~paste('Files:', values$testData$frequency, '<br>Date:', format(values$testData$day, format = '%Y-%m-%d'), sep = ' '))%>%
add_bars( x = ~dayPOSIXct, y = ~frequency, type = "bar", width = 36000000
)
p
})
relayout_data <- reactive({
req(values$testData)
event_data("plotly_relayout", source = "testplot")
})
observeEvent(relayout_data(),{
print(relayout_data())
})
}
shinyApp(ui, server)
UPDATE 2: the issue can indeed be circumvented with approaches that properly use req()
with or without separating the observing of the event_data from the code that does something with the event_data. such as:
relayout_data <- reactive({
req(values$testData)
event_data("plotly_relayout", source = "testplot")
})
observeEvent(relayout_data(),{
print(relayout_data())
})
However, this seems not to provide a solution for situations where the plot is inside i.e. a dropdownbutton panel or other tab/page of a shiny App. After the needed data for the plot is loaded, req() is met and the code will fire, yet the plot is still not rendered as it is not in the current screen.
UPDATE: the issue is also reported on github, no real solution yet https://github.com/ropensci/plotly/issues/1528
Original question / post:
Today I updated all my packages in R and suddenly I got a long list of errors coming from the new plotly version 4.9.0 in R with my R shiny App.
all these errors refer to plotly_relayout
, plotly_click
etc.
Warning: The 'plotly_relayout' event tied a source ID of 'DateRangeHisto' is not registered. In order to obtain this event data, please add
event_register(p, 'plotly_relayout')
to the plot (p
) that you wish to obtain event data from.
I tried to add the event_register in various ways, but no effect. I suppose there is a bug in the new version?
Here is a nonsense dummy app that produces the bug with plotly 4.9.0 and all packages updated.
UPDATE: the error seems to happen when data is not available for the plot
despite the req()
inside the plot_ly
block, the event_data
causes an error. This did not happen with the previous versions of plotly..... so, how to get rid of this is now the question
library(shiny)
library(plotly)
rm(list = ls(), envir = environment()) ## to prevent cross over from old runs
testData = data.frame(day = sample(seq(as.Date('1999/01/01'), as.Date('2000/01/01'), by="day"), 24), frequency = sample(1:5, 24, replace = T ), datecoloring = sample(1:2, 24, replace = T ))
testData$dayPOSIXct <- as.POSIXct(testData$day)
dateRangeMin <- min(testData$day)
dateRangeMax <- max(testData$day)
if(!require('shiny')){ install.packages('shiny', dependencies=TRUE)}
if(!require('shinyWidgets')){ install.packages('shinyWidgets', dependencies=TRUE)}
if(!require('plotly')){ install.packages('plotly', dependencies=TRUE)}
if(!require('htmlwidgets')){ install.packages('htmlwidgets')}
ui <- fluidPage(
actionButton(inputId = 'Load', label = 'Data'),
plotlyOutput('testplot', width = 700, height = 500)
)
server <- function(input, output,session) {
values <- reactiveValues()
observeEvent(input$Load, {
values$testData <- testData
})
output$testplot <- renderPlotly({
req(values$testData)
p <- plot_ly(data = values$testData, source = 'testplot',
color = as.factor(values$testData$datecoloring), colors = c('#339fff', '#eaf5ff'),
opacity= 0.5, showlegend = T,
marker = list(line = list(width = 2, color = '#0000ff')),
hoverinfo = "text",
text = ~paste('Files:', values$testData$frequency, '<br>Date:', format(values$testData$day, format = '%Y-%m-%d'), sep = ' '))%>%
add_bars( x = ~dayPOSIXct, y = ~frequency, type = "bar", width = 36000000
)
p
})
observeEvent(event_data("plotly_relayout", source = "testplot"),{
#any code here, doesn't matter, bug happens already
})
}
shinyApp(ui, server)
Session info
sessionInfo()
R version 3.5.3 (2019-03-11)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1
Matrix products: default
locale:
[1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] plotly_4.9.0 ggplot2_3.1.1 shiny_1.3.2
loaded via a namespace (and not attached):
[1] Rcpp_1.0.1 pillar_1.4.0 compiler_3.5.3 later_0.8.0 colourpicker_1.0.3 plyr_1.8.4 shinyjs_1.0 tools_3.5.3 digest_0.6.19 viridisLite_0.3.0
[11] jsonlite_1.6 tibble_2.1.1 gtable_0.3.0 pkgconfig_2.0.2 rlang_0.3.4 rstudioapi_0.10 crosstalk_1.0.0 yaml_2.2.0 httr_1.4.0 withr_2.1.2
[21] dplyr_0.8.1 htmlwidgets_1.3 grid_3.5.3 DT_0.6 tidyselect_0.2.5 glue_1.3.1 data.table_1.12.2 R6_2.4.0 tidyr_0.8.3 purrr_0.3.2
[31] magrittr_1.5 scales_1.0.0 promises_1.0.1 htmltools_0.3.6 assertthat_0.2.1 mime_0.6 xtable_1.8-4 colorspace_1.4-1 httpuv_1.5.1 miniUI_0.1.1.1
[41] lazyeval_0.2.2 munsell_0.5.0 crayon_1.3.4
The problem is that the observeEvent
is trying to access the event_data
before the plot is rendered. You can work around this behaviour by using req()
also for your event_data()
. Plotly 4.9.0 indeed seems to be more strict about this.
library(shiny)
library(shinydashboard)
library(plotly)
library(shinyWidgets)
rm(list = ls(), envir = environment()) ## to prevent cross over from old runs
testData = data.frame(day = sample(seq(as.Date('1999/01/01'), as.Date('2000/01/01'), by="day"), 24), frequency = sample(1:5, 24, replace = T ), datecoloring = sample(1:2, 24, replace = T ))
testData$dayPOSIXct <- as.POSIXct(testData$day)
dateRangeMin <- min(testData$day)
dateRangeMax <- max(testData$day)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
menuItem("Testpage", tabName = "Testpage", icon = icon("home"))
)
),
dashboardBody(
tabItems(
# 1) Test Tab ---------------------------------------------------------------
tabItem(tabName = "Testpage",
actionButton(inputId = 'Load', label = 'Data'),
dropdownButton(inputId = "TestButton", label = NULL,
plotlyOutput('testplot', width = 700, height = 500),
icon = icon("list-alt"),
tooltip = tooltipOptions(title = "Click to open and render the plot"), width = "1670px")
)
)
),
title = "Dashboard example"
)
server <- function(input, output, session) {
# output$testplot <- renderPlotly({plot_ly(data.frame(NULL), source = 'testplot')})
values <- reactiveValues()
observeEvent(input$Load, {
values$testData <- testData
})
output$testplot <- renderPlotly({
req(values$testData)
p <- plot_ly(data = values$testData, source = 'testplot',
color = as.factor(values$testData$datecoloring), colors = c('#339fff', '#eaf5ff'),
opacity= 0.5, showlegend = T,
marker = list(line = list(width = 2, color = '#0000ff')),
hoverinfo = "text",
text = ~paste('Files:', values$testData$frequency, '<br>Date:', format(values$testData$day, format = '%Y-%m-%d'), sep = ' '))%>%
add_bars( x = ~dayPOSIXct, y = ~frequency, type = "bar", width = 36000000)
p
})
relayout_data <- reactive({
req(values$testData)
req(input$TestButton_state)
event_data("plotly_relayout", source = "testplot")
})
observeEvent(relayout_data(),{
print(relayout_data())
})
}
shinyApp(ui, server)