R Plotly 版本 4.9.0 中的 plotly_click 错误。新版本有bug吗?
Errors with plotly_click in R Plotly version 4.9.0. Is there a bug in the new version?
更新 3:带有下拉按钮问题的新测试应用程序
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)
更新 2: 这个问题确实可以通过正确使用 req()
的方法来规避,无论是否将 event_data 的观察与代码分开它对 event_data 做了一些事情。例如:
relayout_data <- reactive({
req(values$testData)
event_data("plotly_relayout", source = "testplot")
})
observeEvent(relayout_data(),{
print(relayout_data())
})
但是,这似乎无法为绘图位于内部的情况提供解决方案,即下拉按钮面板或闪亮应用程序的其他 tab/page。加载绘图所需的数据后,满足 req() 并且代码将触发,但绘图仍未呈现,因为它不在当前屏幕中。
更新:github 上也报告了这个问题,还没有真正的解决方案
https://github.com/ropensci/plotly/issues/1528
原题/post:
今天我更新了 R 中的所有包,突然我收到一长串错误,这些错误来自 R 中新的 plotly 版本 4.9.0 和我的 R 闪亮应用程序。
所有这些错误都涉及 plotly_relayout
、plotly_click
等
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.
我尝试用各种方式添加event_register,但没有效果。我想新版本中有一个错误?
这是一个产生错误的无意义的虚拟应用程序
情节 4.9.0
和所有包更新。
更新:当数据不可用于绘图时似乎会发生错误
尽管 plot_ly
块中有 req()
,但 event_data
会导致错误。这在以前的 plotly 版本中没有发生.....所以,现在的问题是如何摆脱它
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 信息
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
问题是 observeEvent
试图在渲染图之前访问 event_data
。您可以通过对您的 event_data()
使用 req()
来解决此问题。 Plotly 4.9.0 确实似乎对此更严格。
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)
我遇到了同样的问题,避免警告的一种可能方法是使用 suspended = TRUE
以挂起状态启动监视 event_data
的 observeEvent
,例如
observer <- observeEvent(event_data("plotly_relayout", source = "testplot"), suspended = TRUE, {
print(event_data("plotly_relayout", source = "testplot"))
})
然后只有在定义绘图对象p
后在renderPlotly
中添加observer$resume()
创建绘图后才开始观察。
以下最小的 shiny-app 通过观察 event_data("plotly_click")
在 uiOutput
内的情节来说明这一点,该情节仅在选择 actionButton
和 checkbox
后可用:
library(shiny)
library(plotly)
ui <- fluidPage(
## button
actionButton("load", label = "New data"),
## checkbox
checkboxInput("show", label = "Show plot"),
## plot
uiOutput("plot_ui"),
## click events
tableOutput("clicked")
)
server <- function(input, output, session) {
## reactive values
r <- reactiveValues(
data = NULL,
suspended = TRUE,
clicked = NULL
)
## load data
observeEvent(input$load, {
r$data <- data.frame(x= 1:100, y = rnorm(100))
})
## show plot only if checkbox is selected
output$plot_ui <- renderUI({
req(input$show)
plotlyOutput("plot")
})
## plotly plot
output$plot <- renderPlotly({
req(r$data)
p <- plot_ly(data = r$data, x = ~x, y = ~y, mode = "markers", type = "scatter", source = "plot")
## resume observer only if suspended
if(r$suspended) {
observer$resume()
r$suspended <- FALSE
}
return(p)
})
## observe click events
observer <- observeEvent(event_data("plotly_click", source = "plot"), suspended = TRUE, {
r$clicked <- rbind(r$clicked, event_data("plotly_click", source = "plot"))
})
## display clicked points
output$clicked <- renderTable(
r$clicked
)
}
shinyApp(ui, server)
注意:反应值 r$suspended
确保仅当观察者的状态实际上被挂起时才调用 observer$resume()
。
更新 3:带有下拉按钮问题的新测试应用程序
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)
更新 2: 这个问题确实可以通过正确使用 req()
的方法来规避,无论是否将 event_data 的观察与代码分开它对 event_data 做了一些事情。例如:
relayout_data <- reactive({
req(values$testData)
event_data("plotly_relayout", source = "testplot")
})
observeEvent(relayout_data(),{
print(relayout_data())
})
但是,这似乎无法为绘图位于内部的情况提供解决方案,即下拉按钮面板或闪亮应用程序的其他 tab/page。加载绘图所需的数据后,满足 req() 并且代码将触发,但绘图仍未呈现,因为它不在当前屏幕中。
更新:github 上也报告了这个问题,还没有真正的解决方案 https://github.com/ropensci/plotly/issues/1528
原题/post:
今天我更新了 R 中的所有包,突然我收到一长串错误,这些错误来自 R 中新的 plotly 版本 4.9.0 和我的 R 闪亮应用程序。
所有这些错误都涉及 plotly_relayout
、plotly_click
等
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.
我尝试用各种方式添加event_register,但没有效果。我想新版本中有一个错误?
这是一个产生错误的无意义的虚拟应用程序 情节 4.9.0 和所有包更新。
更新:当数据不可用于绘图时似乎会发生错误
尽管 plot_ly
块中有 req()
,但 event_data
会导致错误。这在以前的 plotly 版本中没有发生.....所以,现在的问题是如何摆脱它
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 信息
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
问题是 observeEvent
试图在渲染图之前访问 event_data
。您可以通过对您的 event_data()
使用 req()
来解决此问题。 Plotly 4.9.0 确实似乎对此更严格。
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)
我遇到了同样的问题,避免警告的一种可能方法是使用 suspended = TRUE
以挂起状态启动监视 event_data
的 observeEvent
,例如
observer <- observeEvent(event_data("plotly_relayout", source = "testplot"), suspended = TRUE, {
print(event_data("plotly_relayout", source = "testplot"))
})
然后只有在定义绘图对象p
后在renderPlotly
中添加observer$resume()
创建绘图后才开始观察。
以下最小的 shiny-app 通过观察 event_data("plotly_click")
在 uiOutput
内的情节来说明这一点,该情节仅在选择 actionButton
和 checkbox
后可用:
library(shiny)
library(plotly)
ui <- fluidPage(
## button
actionButton("load", label = "New data"),
## checkbox
checkboxInput("show", label = "Show plot"),
## plot
uiOutput("plot_ui"),
## click events
tableOutput("clicked")
)
server <- function(input, output, session) {
## reactive values
r <- reactiveValues(
data = NULL,
suspended = TRUE,
clicked = NULL
)
## load data
observeEvent(input$load, {
r$data <- data.frame(x= 1:100, y = rnorm(100))
})
## show plot only if checkbox is selected
output$plot_ui <- renderUI({
req(input$show)
plotlyOutput("plot")
})
## plotly plot
output$plot <- renderPlotly({
req(r$data)
p <- plot_ly(data = r$data, x = ~x, y = ~y, mode = "markers", type = "scatter", source = "plot")
## resume observer only if suspended
if(r$suspended) {
observer$resume()
r$suspended <- FALSE
}
return(p)
})
## observe click events
observer <- observeEvent(event_data("plotly_click", source = "plot"), suspended = TRUE, {
r$clicked <- rbind(r$clicked, event_data("plotly_click", source = "plot"))
})
## display clicked points
output$clicked <- renderTable(
r$clicked
)
}
shinyApp(ui, server)
注意:反应值 r$suspended
确保仅当观察者的状态实际上被挂起时才调用 observer$resume()
。