【问题标题】:Change Plotly highlight with Buttons使用按钮更改 Plotly 突出显示
【发布时间】:2019-04-26 01:12:45
【问题描述】:

我正在使用 Plotly 绘制时间序列,并通过单击某个列/天,发生一些特殊事件。现在我还想使用导航按钮(下一天/前一天),它会更改所选日期。

问题是突出显示仍然在图中单击的列上,因此与单击导航按钮时实际选择的日期不同。

如何使用 actionButtons 更改 Plotly 的突出显示?

如何使用 actionButtons 模拟对 Plotly 列的点击?

测试应用:

## Libs##########
library(shiny)
library(ggplot2)
library(plotly)
library(data.table)

## Data ############
dfN <- data.table(
  time_stamp = seq.Date(as.Date("2018-04-01"), as.Date("2018-07-30"), 1),
  val = runif(121, 100,1000),
  qual = 8,
  col = "green", stringsAsFactors = F
)
setkey(dfN, time_stamp)

Rnd <- sample(1:nrow(dfN), size = 10, replace = F)
dfN[Rnd,"col"] <- "red"
dfN[Rnd, "qual"] <- 3

## Ui ##########
ui <- fluidPage(
  plotlyOutput("plot"),
  h4("Which Day is selected:"),
  verbatimTextOutput("selected"),
  actionButton("prev1", "Previous Element"),
  actionButton("next1", "Next Element")
)

## Server ##########
server <- function(input, output, session) {
  ## Plot
  output$plot <- renderPlotly({
    key <- highlight_key(dfN)
    p <- ggplot() +
      geom_col(data = key, aes(x = plotly:::to_milliseconds(time_stamp), y = val, fill=I(col),
                               text=paste("Date: ", time_stamp, "<br>",
                                          "Quality: ", qual))) +
      labs(y = "", x="") +
      theme(legend.position="none")

    ggplotly(p, source = "Src", tooltip = "text") %>% 
      layout(xaxis = list(tickval = NULL, ticktext = NULL, type = "date")) %>% 
      highlight(selectize=F, off = "plotly_doubleclick", on = "plotly_click", color = "blue",
                opacityDim = 0.5, selected = attrs_selected(opacity = 1))
  })

  ## Selected Day reactive
  SelectedDay <- reactiveVal(NULL)

  ## Plotly Event for clicks
  observe({
    s <- event_data("plotly_click", source = "Src")
    req(s)
    SelectedDay(as.Date(s$x))
  })

  ## Action buttons for next / previous Day
  observeEvent(input$next1, {
    IND <- which(dfN$time_stamp == SelectedDay()) + 1
    if (IND >= length(dfN$time_stamp)) {
      IND = length(dfN$time_stamp)
      print("last element reached")
    }
    SelectedDay(dfN[IND,time_stamp])
  })
  observeEvent(input$prev1, {
    IND <- which(dfN$time_stamp == SelectedDay()) - 1
    if (IND <= 1) {
      print("first element reached")
      IND = 1
    }
    SelectedDay(dfN[IND,time_stamp])
  })

  ## Print the actual selection
  output$selected <- renderPrint({
    req(SelectedDay())
    SelectedDay()
  })
}

shinyApp(ui, server)

【问题讨论】:

    标签: javascript r shiny plotly r-plotly


    【解决方案1】:

    我需要删除您的ggplotly(),但我将采取以下方法:

    ## Libs##########
    library(shiny)
    library(plotly)
    library(data.table)
    
    ## Data ############
    
    dfN <- data.table(
      time_stamp = seq.Date(as.Date("2018-04-01"), as.Date("2018-07-30"), 1),
      val = runif(121, 100,1000),
      qual = 8,
      col = "green", stringsAsFactors = F
    )
    setkey(dfN, time_stamp)
    
    Rnd <- sample(1:nrow(dfN), size = 10, replace = F)
    dfN[Rnd,"col"] <- "red"
    dfN[Rnd, "qual"] <- 3
    
    ## Ui ##########
    ui <- fluidPage(
      plotlyOutput("plot"),
      h4("Which Day is selected:"),
      verbatimTextOutput("selected"),
      actionButton("prev1", "Previous Element"),
      actionButton("next1", "Next Element")
    )
    
    ## Server ##########
    server <- function(input, output, session) {
      ## Plot
      output$plot <- renderPlotly({
        plot_ly(dfN, source = "Src", x=~time_stamp, y=~val, selectedpoints=as.list(which(dfN$time_stamp==SelectedDay())-1), type = "bar")
      })
    
      ## Selected Day reactive
      SelectedDay <- reactiveVal(dfN$time_stamp[1])
    
      ## Plotly Event for clicks
      observe({
        s <- event_data("plotly_click", source = "Src")
        req(s)
        SelectedDay(as.Date(s$x))
      })
    
      ## Action buttons for next / previous Day
      observeEvent(input$next1, {
        IND <- which(dfN$time_stamp == SelectedDay()) + 1
        if (IND >= length(dfN$time_stamp)) {
          IND = length(dfN$time_stamp)
          print("last element reached")
        }
        SelectedDay(dfN[IND,time_stamp])
      })
      observeEvent(input$prev1, {
        IND <- which(dfN$time_stamp == SelectedDay()) - 1
        if (IND <= 1) {
          print("first element reached")
          IND = 1
        }
        SelectedDay(dfN[IND,time_stamp])
      })
    
      ## Print the actual selection
      output$selected <- renderPrint({
        req(SelectedDay())
        SelectedDay()
      })
    }
    
    shinyApp(ui, server)
    

    也许您可以根据自己的需要调整它。另请参阅:https://plot.ly/r/reference/#bar-selectedpoints

    多个selectedpoints 示例:

    library(plotly)
    
    singleP <- plot_ly(data.frame(x=1:10, y=1:10), x=~x, y=~y, selectedpoints=list(1,8), type = "bar")
    
    multiP <- plot_ly(data.frame(x=1:10, y=1:10)) %>% 
      add_trace(x=~x, y=~y, selectedpoints=list(1,8), type = "bar") %>% 
      add_trace(x=~x, y=~y, selectedpoints=list(0,2,6), type = "bar")
    
    subplot(singleP, multiP)
    

    【讨论】:

    • 谢谢,这很有用,因为我不知道 selectedpoints 参数。我必须检查是否可以从我的ggplotly 方法切换。
    • 是否可以包含多个选定点?根据参考资料,它应该是可能的,但我无法让它在 R 中运行,因为当我包含超过 1 个索引时,根本没有突出显示。
    • 当然,这是可能的。我在答案中添加了一个显示两个用例的基本示例。
    • 啊,我必须将list(which(...)) 换成as.list(which(...)) 才能正常工作。
    • 太棒了!我相应地更新了我的原始答案以获得更好的可重用性。
    【解决方案2】:

    您好,我试图在小提琴图中突出显示最近的数据点(通过尾部参数在列中的最后一个),所以我想这适合这个问题。虽然我不知道要放置 selectedpoints 参数。这是我的代码(不突出显示顺便说一句;):

    fig <- df %>%
      plot_ly(
        y = ~v.x,
        type = 'violin',
        box = list(
          visible = T
        ),
        selectedpoints = list(tail(df$column, 1)),
        meanline = list(
          visible = T
        ),
        x0 = 'P violin plot'
      ) 
    
    fig <- fig %>%
      layout(
        yaxis = list(
          title = "",
          zeroline = F
        )
      )
    
    fig  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-27
      • 1970-01-01
      相关资源
      最近更新 更多