T.G.
T.G.

Reputation: 793

Shiny plotOutput dynamic properties

I have a plot that depends on user's input. Depending on the input, the plot size will be different.

Can I control dynamically the plot's height? I know that in plotOutput() I have a height argument, but I can't find a way to change it dynamically.

Reproducible example, when you choose A, the plot looks fine, but if you choose B it's much to high-

library(shiny)
library(ggplot2)

df1 <- data.frame(x = 1:2000, y = rnorm(2000), type = rep(LETTERS[1:8], 250))
df2 <- data.frame(x = 1:100, y = rexp (100), type = rep(c('A','B'), 50))

ui <- shinyUI(fluidPage(title = '',
  fluidRow(selectInput("table",'', choices = c('A','B'))),
  fluidRow(plotOutput("my_plot", height = '1000px'))
  )
)

server <- shinyServer(function(input, output) {
  output$my_plot <- renderPlot({
    t <- if(input$table == 'A') df1
    else df2
    ggplot(t) + facet_grid(type~.) +
      geom_point(mapping = aes(x=x, y=y))
  }
  )
})
shinyApp(ui, server)

One last thing, in the real app it's not that I have 2 different sizes, depending on the input the size needs to change.

Upvotes: 4

Views: 2451

Answers (1)

Gopala
Gopala

Reputation: 10483

To do what you need, you need to use server side rendering. UI does not know what the plot has and how to adjust anything dynamically. It just takes what the server produced and pops it on the screen.

Here is a piece of code that does (I think what you need). BTW - I also put the 'data' part into it's own reactive function. You can modify my code further to make the pixel heights 'computed' vs. hard coded and such.

library(shiny)
library(ggplot2)

df1 <- data.frame(x = 1:2000, y = rnorm(2000), type = rep(LETTERS[1:8], 250))
df2 <- data.frame(x = 1:100, y = rexp (100), type = rep(c('A','B'), 50))

ui <- shinyUI(fluidPage(title = '',
                        fluidRow(selectInput("table",'', choices = c('A','B'))),
                        fluidRow(uiOutput('myPlotUI'))
)
)

server <- shinyServer(function(input, output) {
  myData <- reactive({
    if (input$table == 'A')
      df1
    else
      df2
  })
  myPlot <- reactive({
    output$myPlot <- renderPlot({
      ggplot(myData()) + facet_grid(type~.) +
        geom_point(mapping = aes(x=x, y=y))
    })
    if (input$table == 'A') {
      plotOutput('myPlot', height = '1000px')
    } else {
      plotOutput('myPlot', height = '250px')
    }
  })
  output$myPlotUI <- renderUI({
    myPlot()
  })
})
shinyApp(ui, server)

Upvotes: 3

Related Questions