简体   繁体   中英

Plot an interactive ggplotly plot via shiny (currently produces an empty plot)

I have problems generating a window where one can select one out of a list of interactive plots to be displaied. Currently, the result is a window with the selection sidebar but an empty plot in the main window. The code I put together from parts I've found on the internet is as follows:

ui <- pageWithSidebar(
  headerPanel(h1(textOutput("XRD-Ergebnisse"))),
  sidebarPanel(
    uiOutput("filter_degree"), width = 2
  ),
  mainPanel = mainPanel(
    h3(textOutput("Diffraction Pattern")),
    plotlyOutput("plot")
  )
)
#server.r
server <- function(input, output, session){
  output$filter_degree <- renderUI({
    radioButtons("rd", "Select Option", choices = str_replace(files, ".xy", ""),
                 selected = "AH1Y")
  })
  output$plot <- renderPlotly({
    plot <- html[which(str_replace(files, ".xy", "") == input$rd)]
    })
}
shinyApp(ui = ui, server = server)

and I've loaded the following packages:

c("powdR", "ggplot2", "stringr", "tools", "readxl", "dplyr", "shiny", "plotly")

of which the first ones were used to create the variable html , which is a large list() of interactive plots that are output of functions of the powdR package and, according to the respective documentation, ggplotly plots. This is why I used plotlyOutput instead of plotOutput . The plots themselves have two panels and a legend each and are interactive (posting the complete data and script to get the plots would be too much, I guess).

Unfortunately, despite trying for hours I haven't got any useful results. I hope the error is obvious to more advanced Shiny users than I am (ie to not absolute beginners).

Notes: str_replace(...) here produces only a character vector with strings equal to the names of the list (html), of which "AH1Y" is one option (here the one to be preselected).

Edit: For the definition of the object html

html <- list()
for(i in 1:NROW(results)){
  html[[i]] <- plot(results[[i]], wavelength = "Cu", interactive = TRUE, mode = "both", main = str_replace(files[[i]], ".xy", ""))
}
names(html) <- str_replace(files, ".xy", "")

Which gives a large list object. This object, however, is not accessible as html[[x]] but as html[x] (for reasons I don't know). Running just html[x] in R studio plots the x th graph to the viewer panel. The [[x]] call only produces an error message:

Warning: Error in [[: subscript out of bounds
  [No stack trace available]

Edit #2: When I try to use the non-interactive version and manually ggplotly() it, I get:

Warning messages:
1: In geom2trace.default(dots[[1L]][[1L]], dots[[2L]][[1L]], dots[[3L]][[1L]]) :
  geom_GeomDrawGrob() has yet to be implemented in plotly.
  If you'd like to see this geom implemented,
  Please open an issue with your example code at
  https://github.com/ropensci/plotly/issues
2: In geom2trace.default(dots[[1L]][[1L]], dots[[2L]][[1L]], dots[[3L]][[1L]]) :
  geom_GeomDrawGrob() has yet to be implemented in plotly.
  If you'd like to see this geom implemented,
  Please open an issue with your example code at
  https://github.com/ropensci/plotly/issues

-could the issue be some parts of the plot that are not compatible with plotly?

Edit #3: I narrowed down the problem The plots I want to display were generated using plotly::subplot() or a similar function. When I only plot one of the plot panels I can pass it to the first script within the html list correctly. However, if I eg take this plot that was compatible with the script so far and apply subplot() in order to show the plot two times stacked on each other, it will no longer be possible to display it correctly in via shinyApp() .

Here's an example of using ggplotly to make two plots that get saved in a list and then called by a selector.

library(shiny)
library(plotly)

ui <- fluidPage(
  sidebarPanel(
    selectInput("plots", "Plots", c("plot1", "plot2"))
  ),
  mainPanel(
    plotlyOutput("plot")
  )
  
)

server <- function(input, output, session) {
  p1 <- ggplot(iris, aes_string(x="Sepal.Length", y="Petal.Length")) +
    geom_point()  
  p1 <- ggplotly(p1)
  p2 <- ggplot(iris, aes_string(x="Sepal.Width", y="Petal.Width")) +
    geom_point() 
  p2 <- ggplotly(p2)
  plots <- list("plot1" = p1, "plot2" = p2)
  
  output$plot <- renderPlotly({
    out <- plots[[input$plots]]
  })
  
}

shinyApp(ui, server)

Solution: Somehow the data to plot gets lost on the way; I have to plot from within the server <-... function like this:

server <- function(input, output, session){
  output$filter_degree <- renderUI({
    radioButtons("rd", "Select Sample", choices = str_replace(files, ".xy", ""),
                 selected = "AH1Y")
  })
  output$plot <- renderPlotly({
    plot(results[[which(str_replace(files, ".xy", "") == input$rd)]], wavelength = "Cu", interactive = TRUE, mode = "both",
         main = str_replace(files[[i]], ".xy", ""))
  })
}
shinyApp(ui = ui, server = server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM