1
votes

I have a shiny app that I want to display a 3D surface plot for a different item depending on what the user selects. My data is stored in a dataframe. Currently, I change this data to a list because all of the examples that I've seen with plotly use lists (particularly the examples here and here), but if there is a way to use data frames with plotly surface plots then that would be better for how my data is organized. What I am having trouble with is how to get the variable filteredList to be reactive so that a list is created from the data that gets filtered from the filteredData, which keeps only data entries with the item number selected by the user. I have hardcoded a case that picks out only item 1 and plots it how I want it displayed, but is not reactive to the user's desired input. The next line in my code (commented out) is my attempt at making the plot reactive. Any help that can be provided is much appreciated!

#Check packages to use in library
  {
    library('shiny') #allows for the shiny app to be used
    library('ggplot2')
    library('plotly')
  }

  #Data

  horizontal_position <- c(-2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2)
  vertical_position <- c(-2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2)
  data_val <- sample(0:100, 25)
  item_no <- as.character("Item 1")
  item_1 <-data.frame(item_no, horizontal_position, vertical_position, data_val)

  horizontal_position <- c(-2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2)
  vertical_position <- c(-2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2)
  data_val <- sample(215:270, 25)
  item_no <- as.character("Item 2")
  item_2 <-data.frame(item_no, horizontal_position, vertical_position, data_val)

  item_data <-rbind(item_1, item_2) #dataframe containing both items

  itemchoices <- as.character(unique(item_data$item_no)) 

  # UI

  ui <- fluidPage(
    column(2,
    selectInput(inputId = "Item", label="Select Item:", choices = itemchoices, selected = "Item 1", multiple = FALSE, selectize = TRUE)
    ),
      column(4,
             plotlyOutput("plot3")
      )

    )

  #SERVER

  server <- function(input, output, session)
  {
    filteredData <- reactive({
      m <- item_data %>% filter(
        item_no %in% input$Item
      )
      m
    })

    filteredList <- list(x = unique(item_data[1:25,'horizontal_position']), y = unique(item_data[1:25,'vertical_position']), z = matrix(item_data[1:25,'data_val'], nrow = length(unique(item_data[1:25,'horizontal_position']))))
    # filteredList <- reactive({list(x = unique(filteredData()$horizontal_position), y = unique(filteredData()$vertical_position), z = matrix(filteredData()$data_val, nrow = length(unique(filteredData()$horizontal_position))))})



    output$plot3 <- renderPlotly({
      plot_ly(x=filteredList$x, y = filteredList$y, z= filteredList$z) %>% add_surface()
    })

  }

  #Run the Shiny App to Display Webpage

  shinyApp(ui=ui, server=server)
1
Your attempt with a reactive list works fine with this plotly call : plot_ly(x=filteredList()$x, y = filteredList()$y, z= filteredList()$z)HubertL

1 Answers

0
votes

I am working on an app that does the same thing. Check out it out here. My code is on GitHub: https://github.com/jeffreyxparker/3D-Shiny-Tool