2

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

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)

在此处输入图像描述

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

更新:

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

这里提出了一个改变点击点形状的相关问题。

4

1 回答 1

6

您可以使用'功能将Plotly'事件添加到 Shiny 应用程序中。htmlwidgetonrender

ggplotly(p) %>% onRender(javascript)

将数组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]
                  );

  });
}

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)

一些解释:

  • 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在本例中
于 2017-08-30T21:17:27.527 回答