如何在Shiny的Plotly事件中获取Facet(分面)数据?
解决Plotly分面图表点击事件中获取分面信息的问题
我完全理解你的困扰——默认情况下,用ggplotly()生成的分面图表,event_data()返回的结果里确实不包含分面的分组信息(比如你例子里的gear)。不过我们可以通过自定义数据映射的方法来解决这个问题,把分面变量绑定到Plotly能识别的隐藏字段中,这样事件触发时就能拿到分面信息了。
核心思路
我们可以利用ggplot的customdata美学属性,把分面变量(比如gear)映射到这个属性上。Plotly会自动将customdata的内容包含在所有交互事件数据中,这样点击、悬停等操作就能获取到对应的分面信息了。
修改后的完整代码
library(plotly) library(shiny) ui <- fluidPage( plotlyOutput("plot"), verbatimTextOutput("hover"), verbatimTextOutput("click"), verbatimTextOutput("brush"), verbatimTextOutput("zoom") ) server <- function(input, output, session) { output$plot <- renderPlotly({ key <- row.names(mtcars) # 关键修改:在aes中添加customdata = gear,把分面变量传入Plotly p <- ggplot(mtcars, aes(x = mpg, y = wt, colour = factor(vs), key = key, customdata = gear)) + geom_point() + facet_grid(rows = "gear") ggplotly(p) %>% layout(dragmode = "select") }) output$hover <- renderPrint({ d <- event_data("plotly_hover") if (is.null(d)) "Hover events appear here (unhover to clear)" else d }) output$click <- renderPrint({ d <- event_data("plotly_click") if (is.null(d)) "Click events appear here (double-click to clear)" else d }) output$brush <- renderPrint({ d <- event_data("plotly_selected") if (is.null(d)) "Click and drag events (i.e., select/lasso) appear here (double-click to clear)" else d }) output$zoom <- renderPrint({ d <- event_data("plotly_relayout") if (is.null(d)) "Relayout (i.e., zoom) events appear here" else d }) } shinyApp(ui, server)
效果验证
运行修改后的代码,点击任意分面里的点,你会发现click输出的结果中多了customdata字段,这个字段的值就是该点所在分面的gear值。比如点击gear=3分面里的点,customdata会显示3,完全符合我们的需求。
后续扩展
拿到分面信息后,你就可以用这个值来过滤原始数据,进而更新另一张图表了。比如可以在server里添加一个响应式数据:
filtered_data <- reactive({ click_info <- event_data("plotly_click") if (is.null(click_info)) { mtcars } else { mtcars[mtcars$gear == click_info$customdata, ] } })
然后用filtered_data()来渲染第二张图表即可。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

