Home > Enterprise >  Using Reactive to trigger log scale in shiny/plotly
Using Reactive to trigger log scale in shiny/plotly

Time:10-12

This shiny app has some radio buttons to see whether the plotly object needs to have a log scale. The textOutput verifies that the reactive function is following the changes in the input, yet the layout does not change.

Could anyone help?

library(tidyverse)
library(plotly)

c1 <- c(1,2,3,4,5)
c2 <- c(6,3,4,6,5)
c3 <- c(1,2,3,4,5)
df<- data.frame(c1,c2,c3)
cols <- names(df)

ui <- fluidPage(
  titlePanel("Log Test"),
  sidebarLayout(
    sidebarPanel(
      selectInput("x",
                  "x-axis",
                  cols),
      selectInput("y",
                  "y-axis",
                  cols),
      radioButtons("rb", "Log Axis", choiceNames = list("X", "Y", "Both", "None"), choiceValues = list("X", "Y", "Both", "None")) 
    ),
    
    mainPanel(
      
      plotlyOutput("plot"),
      textOutput("note")
    )
  )
)

server <- function(input, output, session) {
  x <- reactive({
    df[,input$x]
  })
  
  y <- reactive({
    df[,input$y]
  })

  
  logsc <- reactive({
    if (input$rb=='X'){
      list('log','linear')
    }else if (input$rb=='Y'){
      list('linear','log')
    }else if (input$rb=='Both'){
      list('log','log')
    }else{
      list('linear','linear')
    }
    
    
  })
  output$plot <- renderPlotly(
    {
      plot1 <- plot_ly(
        x = x(),
        y = y(), 
        type = 'scatter',
        mode = 'markers',
        
        )
      
      plot1 <- layout(plot1, xaxis = list(type = logsc()[1], ticks ='inside'),yaxis = list(type = logsc()[2], ticks = 'inside'))
      
      plot1
      
    }
  )
  output$note <- renderText({
    paste0("rb ", logsc()[1],"-", logsc()[2])
  })
}

shinyApp(ui = ui, server = server)

CodePudding user response:

As you checked it, reactive works fine. Your issue is with logsc() value (of type list) and being subset with single bracket (like a vector).

Single bracket subsetting of a list returns a list containing one item:

> list(1,2,3)[2]
[[1]]
[1] 2

Double bracket subsetting of a list returns a single item of the list

> list(1,2,3)[[2]]
[1] 2

You have been fooled by paste that unlisted you list

To fix your code you can write the call to layout() this way:

plot1 <- layout(plot1, 
                xaxis = list(type = logsc()[[1]], 
                             ticks ='inside'),
                yaxis = list(type = logsc()[[2]], 
                             ticks = 'inside'))
  • Related