通过Shiny中的串扰与DT一起使用Plotly [英] Using Plotly with DT via crosstalk in Shiny

查看:90
本文介绍了通过Shiny中的串扰与DT一起使用Plotly的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个应用程序,以将csv文件读取为闪亮的文件,并将绘图散点图与DT表链接起来.我在DT数据表( https://plot.ly/r/datatable上,从Plotly网站上跟踪了该示例/),但从csv中保存的数据另存为反应性输入,而散点图的x和y变量具有selectinput. 单击操作按钮后,我可以生成图和DT表,还可以更新DT,使其仅显示刷过散点图时选定的行.我的问题是,当我在DT中选择行时,散点图中的相应单个点不会被选中(应为红色).我似乎是使用反应性函式()作为x和y变量的输入,而不是使用图的公式,但我似乎无法克服这个问题.

I am writing an app to read a csv file into shiny and link a plotly scatter plot with a DT table. I pretty much followed the example from the Plotly website on DT datatable (https://plot.ly/r/datatable/) with the exception that the saved data from the csv is saved as a reactive input and that I have selectinput for the x and y variables for the scatterplot. I can generate the plot and DT table after clicking on the action button and I can also update the DT to only show selected rows from brushing the scatterplot. My problem is that when I select rows in the DT, then the corresponding individual points in the scatterplot does not become selected (should be in red color). I seems to be that I used reactive functions() as input for the x and y variables instead of formulas in plotly but I cannot seem to overcome this problem.

控制台上出现警告消息,但我似乎无法弄清楚如何解决此问题:

A warning message appear on the console but I cant seem to figure out how to fix this:

origRenderFunc()中的警告: 忽略显式提供的小部件ID"154870637775";闪亮不使用它们 将off事件(即'plotly_deselect')设置为与on事件(即'plotly_selected')匹配.您可以通过highlight()函数更改此默认设置.

Warning in origRenderFunc() : Ignoring explicitly provided widget ID "154870637775"; Shiny doesn't use them Setting the off event (i.e., 'plotly_deselect') to match the on event (i.e., 'plotly_selected'). You can change this default via the highlight() function.

感谢您对此问题的任何投入.

Would be thankful for any input on this issue.

我已经简化了闪亮的应用程序,使其仅包含相关的代码块:

I have simplified my shiny app to include only the relevant code chunks:

library(shiny)
library(dplyr)
library(shinythemes)
library(DT)
library(plotly)
library(crosstalk)

ui <- fluidPage(
  theme = shinytheme('spacelab'),
  titlePanel("Plot"),
  tabsetPanel(

    # Upload Files Panel
    tabPanel("Upload File",
             titlePanel("Uploading Files"),
             sidebarLayout(
               sidebarPanel(
                 fileInput('file1', 'Choose CSV File',
                           accept=c('text/csv', 
                                    'text/comma-separated-values,text/plain', 
                                    '.csv')),

                 tags$br(),

                 checkboxInput('header', 'Header', TRUE),
                 radioButtons('sep', 'Separator',
                              c(Comma=',',
                                Semicolon=';',
                                Tab='\t'),
                              ','),
                 radioButtons('quote', 'Quote',
                              c(None='',
                                'Double Quote'='"',
                                'Single Quote'="'"),
                              '"'),
                 # Horizontal line ----
                 tags$hr(),

                 # Input: Select number of rows to display ----
                 radioButtons("disp", "Display",
                              choices = c(Head = "head",
                                          All = "all"),
                              selected = "head")


               ),
               mainPanel(
                 tableOutput('contents')
               )
             )
    ),

    # Plot and DT Panel
    tabPanel("Plots",
             titlePanel("Plot and Datatable"),
             sidebarLayout(
               sidebarPanel(
                 selectInput('xvar', 'X variable', ""),
                 selectInput("yvar", "Y variable", ""),
                 actionButton('go', 'Update')
               ),
               mainPanel(
                 plotlyOutput("Plot1"),
                 DT::dataTableOutput("Table1")
                 )
             )
    )
  )
)


# Server function ---------------------------------------------------------


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

  ## For uploading Files Panel ## 

  MD_data <- reactive({ 
    req(input$file1) ## ?req #  require that the input is available
    df <- read.csv(input$file1$datapath, 
                   header = input$header, 
                   sep = input$sep,
                   quote = input$quote)
    return(df)
  })


  # add a table of the file
  output$contents <- renderTable({
    if(is.null(MD_data())){return()}

    if(input$disp == "head") {
      return(head(MD_data()))
    }
    else {
      return(MD_data())
    }
  })



  #### Plot Panel ####

  observeEvent(input$go, {

    m <- MD_data ()



    updateSelectInput(session, inputId = 'xvar', label = 'Specify the x variable for plot',
                      choices = names(m), selected = NULL)
    updateSelectInput(session, inputId = 'yvar', label = 'Specify the y variable for plot',
                      choices = names(m), selected = NULL)

    plot_x1 <- reactive({
      m[,input$xvar]})

    plot_y1 <- reactive({
      m[,input$yvar]})

    ########   
    d <- SharedData$new(m)


    # highlight selected rows in the scatterplot
    output$Plot1 <- renderPlotly({

      s <- input$Table1_rows_selected

      if (!length(s)) {
        p <- d %>%
          plot_ly(x = ~plot_x1(), y = ~plot_y1(), type = "scatter", mode = "markers", color = I('black'), name = 'Unfiltered') %>%
          layout(showlegend = T) %>% 
          highlight("plotly_selected", color = I('red'), selected = attrs_selected(name = 'Filtered'), deselected = attrs_selected(name ="Unfiltered)"))
      } else if (length(s)) {
        pp <- m %>%
          plot_ly() %>% 
          add_trace(x = ~plot_x1(), y = ~plot_y1(), type = "scatter", mode = "markers", color = I('black'), name = 'Unfiltered') %>%
          layout(showlegend = T)

        # selected data
        pp <- add_trace(pp, data = m[s, , drop = F], x = ~plot_x1(), y = ~plot_y1(), type = "scatter", mode = "markers",
                        color = I('red'), name = 'Filtered')
      }

    })

    # highlight selected rows in the table
    output$Table1 <- DT::renderDataTable({
      T_out1 <- m[d$selection(),]
      dt <- DT::datatable(m)
      if (NROW(T_out1) == 0) {
        dt
      } else {
        T_out1
        }
    })


    }) 



}

shinyApp(ui, server)

推荐答案

您需要一个sharedData对象,以便Plotly和DT可以共享更新的选择.希望我下面的玩具示例可以帮助说明.不幸的是,我还没有找到使串扰与导入文件一起工作的方法(我自己的

You need a sharedData object so that both Plotly and DT can share updated selections. Hopefully my toy example below can help illustrate. Unfortunately, I have not found a way of making crosstalk work with imported files (my own question refers).

library(shiny)
library(crosstalk)
library(plotly)
library(ggplot2)

# Shared data available for use by the crosstalk package
shared_df <- SharedData$new(iris)

ui <- fluidPage(

  # Application title
  titlePanel("Crosstalk test"),

  # Sidebar with a slider input for number of bins 
  sidebarLayout(
    sidebarPanel(
      filter_select("iris-select", "Select Species:",
                    shared_df,
                    ~Species),
      filter_slider("iris-slider", "Select width:",
                    shared_df,
                    ~Sepal.Width, step=0.1, width=250)
    ),

    # Show a plot of the generated data
    mainPanel(
      plotlyOutput("distPlot"),
      DTOutput("table")
    )
  )
)

# Define server logic required to draw a histogram
server <- function(input, output) {

  output$distPlot <- renderPlotly({
    ggplotly(ggplot(shared_df) +
      geom_point(aes(x = Sepal.Width, y = Sepal.Length, colour = Species))
    )
  })

  output$table <- renderDT({
    datatable(shared_df, extensions="Scroller", style="bootstrap", class="compact", width="100%",
              options=list(deferRender=TRUE, scrollY=300, scroller=TRUE))
  }, server = FALSE)
}

# Run the application 
shinyApp(ui = ui, server = server)

这篇关于通过Shiny中的串扰与DT一起使用Plotly的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆