Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R shiny: How to get square plot to use full width of panel?

Tags:

r

shiny

I have a square plot (aspect ratio 1:1) that I'm trying to scale to be the full width of mainPanel. Due to the height parameter being 400px by default, the plot comes out as a 400x400 image in the middle of the panel:

enter image description here

I read that you can alter the height parameter of plotOutput to be "100%" or "auto" to have the panel use the natural dimensions of the image. However, plotOutput then tries to retrieve the height parameter from renderPlot, which itself is getting its height value from plotOutput resulting in a "Catch-22" scenario and a plot of height 0px.

What I'm trying to do is set the height value of renderPlot (or plotOutput) to be equal to the width of mainPanel, but I'm unsure how to access this value. Here's my code so far:

library( shiny )
library( ggplot2 )

server <- function(input, output)
{
    output$plot1 <- renderPlot({
        X <- data.frame( x=rnorm(input$n), y=rnorm( input$n ) )
        ggplot( X, aes(x=x, y=y) ) + geom_point() + coord_fixed()
    }, height=400   # how to get this value to be mainPanel width?
    )
}

ui <- fluidPage(
    sidebarLayout( 
        sidebarPanel(
            sliderInput("n", "Number of Samples", min=10, max=1000, value=100) ),
        mainPanel( plotOutput("plot1", height="auto") )
    )
)

shinyApp(ui = ui, server = server)

Any thoughts?

like image 263
Artem Sokolov Avatar asked Nov 10 '16 22:11

Artem Sokolov


1 Answers

Based on this post:

library( shiny )
library( ggplot2 )

server <- function(input, output)
{
  output$plot1 <- renderPlot({
    X <- data.frame( x=rnorm(10), y=rnorm( 10) )
    ggplot( X, aes(x=x, y=y) ) + geom_point() +  coord_fixed()
    } ,
    height=reactive(ifelse(!is.null(input$innerWidth),input$innerWidth*3/5,0))
  )
}

ui <- fluidPage(
  sidebarLayout( 
    sidebarPanel(
      tags$head(tags$script('$(document).on("shiny:connected", function(e) {
                            Shiny.onInputChange("innerWidth", window.innerWidth);
                            });
                            $(window).resize(function(e) {
                            Shiny.onInputChange("innerWidth", window.innerWidth);
                            });
                            ')),
      sliderInput("n", "Number of Samples", min=10, max=1000, value=100) ),
    mainPanel( plotOutput("plot1"))
  )
)

shinyApp(ui = ui, server = server)
like image 136
HubertL Avatar answered Sep 21 '22 13:09

HubertL