Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent shiny from updating elements of plotly

Tags:

r

shiny

plotly

I am trying to keep the color scale and size scale of my plot constant, regardless of which points are actually displayed.

In ggplot, I could set these constant using arguments like scale_color_gradient(limits=c(0,1)). However, I cannot find a parallel function in plot_ly and for other reasons, I cannot use ggplotly() here.

I believe this can also be done with eventReactive() but I'm having trouble understanding how to use it.

Here is a minimal example, where the plot color and size keep changing.

library(dplyr)
library(shiny)
library(plotly)

df <- as.data.frame(list("UserID"=c(1,1,1,1,2,2,2,2), 
                          "Category"=c('A','A','B','B','A','A','B','B'),
                          "Rate"=c(2,3,5,6,8,6,7,1),
                          "x"=c(1,3,5,7,2,4,6,8),
                          "y"=c(1,3,5,7,2,4,6,8)
                    ))

ui <- (fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput("userInput","Select User", sort(unique(df$UserID)),
                  selected=1),
      checkboxGroupInput("CategoryInput", "Select Category", sort(unique(df$Category)),
                         selected=c('A','B'))
    ),

    mainPanel(
      plotlyOutput("mainPlot")#,
    )
  )
))

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

  # filter for both user and category
  filteredFull <- reactive({
      df %>% 
        filter(
          UserID == input$userInput,
          Category %in% input$CategoryInput
        )
  })

  output$mainPlot <- renderPlotly({
        plot_ly(data=filteredFull(), x=x, y=y,
                       color=Rate, size=Rate,
                       mode='markers')
  })
}

shinyApp(ui, server)

Is it possible to update only which points are displayed, without updating the scale/range of the color/size?

like image 680
Adam_G Avatar asked May 16 '16 21:05

Adam_G


1 Answers

Plotly has those colorscale limits as well. They are nested under the marker attribute. You can set the color scales maximum and minimum values (numeric values) to leave the scale constant regardless which points are actually displayed.

I just added marker = list(cmin = 1, cmax = 8) to the plot_ly command. So you would have to scan your df to determine which are your maximum and minimum values.

Code below:

library(dplyr)
library(shiny)
library(plotly)

df <- as.data.frame(list(
  "UserID" = c(1, 1, 1, 1, 2, 2, 2, 2), 
  "Category" = c('A', 'A', 'B', 'B', 'A', 'A', 'B', 'B'),
  "Rate" = c(2, 3, 5, 6, 8, 6, 7, 1),
  "x" = c(1, 3, 5, 7, 2, 4, 6, 8),
  "y" = c(1, 3, 5, 7, 2, 4, 6, 8)
))

ui <- (fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput("userInput","Select User", sort(unique(df$UserID)), selected=1),
      checkboxGroupInput("CategoryInput", "Select Category", sort(unique(df$Category)), selected=c('A','B'))
    ),

    mainPanel(
      plotlyOutput("mainPlot"),
      plotlyOutput("mainPlotFixedSize")
    )
  )
))

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

  # filter for both user and category
  filteredFull <- reactive({
      df %>% 
        filter(
          UserID == input$userInput,
          Category %in% input$CategoryInput
        )
  })

  output$mainPlot <- renderPlotly({
    plot_ly(data=filteredFull(), x=x, y=y,
      color=Rate, size=Rate,
      mode='markers', marker = list(cmin = 1, cmax = 8))
  })

  output$mainPlotFixedSize <- renderPlotly({
    plot_ly(data=filteredFull(), x=x, y=y,
      color=Rate, mode='markers', 
      marker = list(sizemode = "area", size = Rate*3400, cmin = 1, cmax = 8))
  }) 
}

shinyApp(ui, server)
like image 54
K. Rohde Avatar answered Oct 22 '22 17:10

K. Rohde