R 闪亮并巧妙地获得图例点击事件
Posted
技术标签:
【中文标题】R 闪亮并巧妙地获得图例点击事件【英文标题】:R shiny and plotly getting legend click events 【发布时间】:2018-05-04 11:07:40 【问题描述】:我有一个闪亮的 R 页面,并根据单击饼图过滤数据。如果我可以通过单击图例条目触发相同的过滤事件,那就太好了,但我似乎找不到事件触发器,所以它只是过滤该图表而不传播到其他图表。图例点击事件是否可访问?
library(data.table)
library(plotly)
library(shiny)
dt = as.data.table(mtcars)
ui <- fluidPage(
plotlyOutput("pie1"),
plotlyOutput("pie2")
)
server <- function(input, output)
gearDT = reactive(
return(dt[,.N,by=gear])
)
cylDT = reactive(
return(dt[,.N,by=cyl])
)
output$pie1 <- renderPlotly(
plot_ly(gearDT(), labels = ~gear, values = ~N, type = "pie") %>%
layout(showlegend = TRUE)
)
output$pie2 <- renderPlotly(
plot_ly(cylDT(), labels = ~cyl, values = ~N, type = "pie") %>%
layout(showlegend = TRUE)
)
shinyApp(ui = ui, server = server)
【问题讨论】:
你能准备一个minimal reproducible example吗?如果您更完整地说明您的问题并展示您迄今为止所采取的步骤,那么您可能会收到更有成效的答案 @KevinArseneau 感谢凯文的建议,我附上了一个例子,不过你可能已经回答了我的问题。 【参考方案1】:面向未来的读者
Plotly 现在创建了一个名为 plotly_relayout
的事件。此事件在布局更改时触发。单击图例是这些更改之一。
此事件中的一个变量称为hiddenlabels
。此变量包含所有隐藏的图例轨迹的名称。
observe(
relayout <- event_data("plotly_relayout")
hidden_labels <- relayout$hiddenlabels
print(hidden_labels)
)
编辑
如果 plotly_relayout
不适合您,请检查 event when clicking a name in the legend of a plotly's graph in R Shiny。
【讨论】:
Wilmar,我只是尝试与这个观察者合作,看到我已经使用其中一些观察情节事件来点击情节中的粒子、缩放等,但是当我把这个重新布局代码放入我的应用程序,它似乎只听缩放和旋转,并且只包含 $scene.camera 元素。有什么线索吗?也许您可以提供一个工作示例? 感谢您的快速响应,我也查看了,没有查看图例点击的示例。我发布了一个带有演示应用程序的问题,该应用程序显示了非工作情况。如果您有任何意见,将不胜感激,谢谢! ***.com/questions/54822671/… 我在我的帖子中添加了指向您问题答案的链接。祝你好运!【参考方案2】:简短的回答是是,但有一些注意事项,实施起来需要比我在回答中完全涵盖的更多工作。
plotly
包包含event_data
函数。在documentation 中,您会发现涵盖了三个事件:
plotly_hover
plotly_click
plotly_selected
使用这些的示例在上面的链接中。它们不具体涉及与图例的交互,而是适当地涉及绘图中的数据。
不过,有 plotly 提供的postMessage API,shiny 和其他框架如 jupyter 用来捕获事件.我没有通过文档来突出与传说有关的事件。这需要一些 javascript,您可以在 R 中使用 shinyjs
访问它们。
为直接实现这一目标付出的努力可能比您愿意付出的多。如果您不必走这条路,那么我相信您会在使用 shiny input
和 reactive
过滤和重绘函数时获得更好的回报。
使用更新后的示例进行编辑
您对问题的编辑揭示了您的问题的更多信息。虽然它不可重现,但manuf
不是mtcars
的列名(我假设您将该名称分配给行名)。如果您的图例在图之间共享,您可以使用documentation 中所示的子图分组图例。
进一步修订
饼图在子图中的表现有点奇怪,请参阅this 和docs。以下代码为您提供了一个可重现的最小解决方案。
dt <- as.data.table(mtcars)
ui <- fluidPage(plotlyOutput("pie"))
server <- function(input, output)
gearDT <- reactive(return(dt[,.N,by=gear]))
cylDT <- reactive(return(dt[,.N,by=cyl]))
output$pie <- renderPlotly(
plot_ly() %>%
add_pie(data = gearDT(), labels = ~gear, values = ~N, name = "gear",
domain = list(x = c(0, 0.5), y = c(0, 1))) %>%
add_pie(data = cylDT(), labels = ~cyl, values = ~N, name = "cyl",
domain = list(x = c(0.5, 1), y = c(0, 1))) %>%
layout(showlegend = TRUE,
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
)
shinyApp(ui = ui, server = server)
屏幕截图显示了从两条轨迹中过滤出的共同元素 (4)。
虽然您最初的问题涉及shiny
,但我将其纳入我的回答中。 plotly
图表独立于此,并且可以作为具有相同功能的独立小部件完美运行。如果您打算在 rmarkdown
文档中这样做,或者不需要依赖 shiny
,这可能很有用。
【讨论】:
谢谢凯文,这可能比我现在愿意承担的更多,但我会记住的。 我一定在路上的某个地方修改了 mtcars,已经修好了。子情节可能是我前进的方向,再次感谢。【参考方案3】:library(dygraphs)
library(datasets)
ui <- shinyUI(fluidPage(
mainPanel(
dygraphOutput("dygraph"),dygraphOutput("dygraph1"),dygraphOutput("dygraph2")
)
)
)
server <- shinyServer(function(input, output)
output$dygraph <- renderDygraph(
dygraph(ldeaths, main = "All", group = "lung-deaths")
)
output$dygraph1 <- renderDygraph(
dygraph(mdeaths, main = "Male", group = "lung-deaths")
)
output$dygraph2 <- renderDygraph(
dygraph(fdeaths, main = "Female", group = "lung-deaths")
)
)
shinyApp(ui = ui, server = server)
【讨论】:
不确定这是否能回答问题。能稍微解释一下吗? 我对这个问题的理解是,他想用图例过滤饼图,而不是点击图表。上面的代码通过使用 plotly 包来做同样的事情。 @Rahul 我的问题是我希望其他图表也可以通过点击另一个图表的图例来过滤。据我所知,此解决方案只会过滤该图表。 在这种情况下你可以使用 dygraphs 。我已经更新了我对那个案例的回答 感谢 Rahul,看起来很有趣!不过,这似乎只是时间序列数据,这不是我最关心的问题。以上是关于R 闪亮并巧妙地获得图例点击事件的主要内容,如果未能解决你的问题,请参考以下文章