Shiny 更新单击的点以突出显示它

Prr*_*dep 2 r ropensci shiny plotly ggplotly

这是提取点击事件的工作示例。我想问你是否有办法通过增加大小或突出显示等来更新点击点?

library(shiny)
library(plotly)

ui <- fluidPage(
    plotlyOutput("plot"),
    verbatimTextOutput("click")
)

server <- function(input, output, session) {

    nms <- row.names(mtcars)

    output$plot <- renderPlotly({
        p <- ggplot(mtcars, aes(x = mpg, y = wt, col = as.factor(cyl), key = nms)) + 
           geom_point()
        ggplotly(p)

    })

    output$click <- renderPrint({
        d <- event_data("plotly_click")
        if (is.null(d)) "Click events appear here (double-click to clear)" 
        else cat("Selected point associated with Car: ", d$key)
    })

}

shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

我已经搜索了 SO 和其他合适的来源以找到以下问题的解决方案,但找不到。

更新:

  • 这个解决方案更适合这个玩具情节。但是,我的原始用例包含 50 多个感兴趣的变量级别,并且很有可能已经存在洋红色或任何其他颜色。此外,改变颜色需要相当长的时间。
  • 有没有办法增加点击点的大小以将其与附近的数百个点区分开来?

已在此处询问有关更改单击点形状的相关问题。

Max*_*ers 5

您可以使用's函数将Plotly's事件添加到您的 Shiny 应用程序中。htmlwidgetonrender

ggplotly(p) %>% onRender(javascript)
Run Code Online (Sandbox Code Playgroud)

colors传递给restyle函数的数组。所选点 ( pointNumber) 为洋红色,而其他点从图例中获取颜色。你可以对marker大小做同样的事情,标记符号有点棘手,因为Plotly这里不接受数组。

function(el, x){
  el.on('plotly_click', function(data) {
    colors = [];
    var base_color = document.getElementsByClassName('legendpoints')[data.points[0].curveNumber].getElementsByTagName('path')[0].style['stroke']
    for (var i = 0; i < data.points[0].data.x.length; i += 1) {
      colors.push(base_color)
    };
    colors[data.points[0].pointNumber] = '#FF00FF';
    Plotly.restyle(el, 
                   {'marker':{color: colors}}, 
                   [data.points[0].curveNumber]
                  );

  });
}
Run Code Online (Sandbox Code Playgroud)
library(shiny)
library(plotly)
library(htmlwidgets)

ui <- fluidPage(
  plotlyOutput("plot")
)

javascript <- "
function(el, x){
  el.on('plotly_click', function(data) {
    colors = [];

    var base_color = document.getElementsByClassName('legendpoints')[data.points[0].curveNumber].getElementsByTagName('path')[0].style['stroke']
    for (var i = 0; i < data.points[0].data.x.length; i += 1) {
      colors.push(base_color)
    };
    colors[data.points[0].pointNumber] = '#FF00FF';
    Plotly.restyle(el, 
                   {'marker':{color: colors}}, 
                   [data.points[0].curveNumber]
                  );
    //make sure all the other traces get back their original color
    for (i = 0; i < document.getElementsByClassName('plotly')[0].data.length; i += 1) {
      if (i != data.points[0].curveNumber) {
        colors = [];
        base_color = document.getElementsByClassName('legendpoints')[i].getElementsByTagName('path')[0].style['stroke'];
        for (var p = 0; p < document.getElementsByClassName('plotly')[0].data[i].x.length; p += 1) {
          colors.push(base_color);
        }
        Plotly.restyle(el, 
                       {'marker':{color: colors}}, 
                       [i]);
      }
    };
  });
}"
server <- function(input, output, session) {

  nms <- row.names(mtcars)

  output$plot <- renderPlotly({
    p <- ggplot(mtcars, aes(x = mpg, y = wt, col = as.factor(cyl), key = nms)) + 
      geom_point()
    ggplotly(p) %>% onRender(javascript)

  })
}

shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)

一些解释:

  • Plotly 的事件,例如在事件函数中plotly_click传递一些信息(data在这种情况下)
  • data.points 包含触发事件的点
  • 在这种情况下,我们只有一个点data.points[0],其中pointNumber是原始数组的索引,curveNumber是跟踪编号。
  • Plotly 将所有输入数据存储在div绘制绘图的位置
  • 我们可以通过 document.getElementsByClassName('plotly')[0].data
  • 可以通过图例的索引document.getElementsByClassName('legendpoints')[i]在哪里访问i图例
  • ggplotly 或 plot_ly 返回 htmlwidgets
  • 可以使用任何 htmlwidget函数添加 Javascript 或 HTML 代码,例如onrender在这种情况下

  • 感谢您从代码编辑中找到剩余部分!您还可以更改大小,例如 `sizes.push(10);... sizes[...pointNumber] = 20;... 'marker': {size: sizes}` (2认同)