Get rid of whitespace between plots (insertUI)

I have a seemingly easy problem that I don't manage to solve:

I use the insertUI function in a shiny app where the user can insert as many plots as wanted. Some of the plots should be smaller than others (from a purely aesthetic aspect) and I have adjusted the height of the plots in the renderPlot({}, size=xx) function. Now, the problem is that this creates a whitespace between the plots (see attached image). This is not desired since the comparison of plots should be easy to the user. Does anybody have an idea how I can get rid of the whitespace? It seems to be a problem in the tags$div(), and I have tried adjusting it by setting a size of the div, without success.

Example code:

library(shiny)
library(shinydashboard)
library(ggplot2)

### UI

ui <- dashboardPage(
  dashboardHeader(),
  
  dashboardSidebar(
    actionButton("add", "Add"),
    radioButtons("add_elements", "Elements", c("Element1",  "Element2")),
    actionButton("remove", "Remove")
  ),
  dashboardBody(
    fluidRow(
      tags$div(id="placeholder")
    )
  )
)

#### SERVER


server <- function(input, output, session) {
  
  # Test data set
  
  a<-(letters)
  b<-rnorm(length(letters), 4,2)
  c<-rnorm(length(letters), 10,15)
  d<-c(1:10,20:30,45:49)
  
  data<-data.frame(a,b,c,d)
  names(data)<-c("name","v1","v2","v3")
  
  # Initialize empty vector
  
  inserted<- c()
  
  ### Elements ###
  
  observeEvent(input$add, {
    id_add <- paste0(input$add, input$add_elements)
    insertUI(selector = '#placeholder', where = "afterEnd",
             ui= switch(input$add_elements,
                        'Element1'= plotOutput(id_add),
                        'Element2' = plotOutput(id_add))
    )
    
    output[[id_add]] <- 
      if (input$add_elements == "Element1") renderPlot({ 
       g<-ggplot(data=data, aes(x=name, y=v2)) + geom_point()
       plot(g)
      }, height=200) # this plot is smaller
    else if (input$add_elements == "Element2") renderPlot({
      g<-ggplot(data=data, aes(x=name, y=v3)) + geom_point()
      plot(g)
    })
    inserted <<- c(id_add,inserted)
  })
  
  ### Remove Elements ###
  observeEvent(input$remove, {
    removeUI(
      ## pass in appropriate div id
      selector = paste0('#', inserted[length(inserted)])
    )
    inserted <<- inserted[-length(inserted)]
  })
  
}

shinyApp(ui = ui, server = server)

I am still stuck with this issue. Does anybody have an idea where the problem might be? I am not sure whether the renderPlot() function assigns predefined margins to the plot that are passed to the UI or whether this problem can be solved using HTML code.

I finally found the solution and want to share it for completedness. The output plots in HTML have the .class attribute .shiny-plot-output. The actual plot areas can be changed through a .css file (which should be stored in a folder called www)

I changed the code as follows:

dashboardBody(
    fluidPage(

# refers to the css syles sheet
      tags$head(
        tags$link(rel = "stylesheet", type = "text/css", href = "styles.css")
      ),
      tags$div(id="placeholder")
    )
)

The css file looks like this:


/*css file*/

.shiny-plot-output {
	height: 200px !important;
}

The plots should now be aligned vertically without any whitespace. Note that forcing to overwrite with !important is crucial.

1 Like

I have found a bit easier way. Just set inline = T in the plotOutput, and then specify image size in renderPlot(). That worked perfect for me.

1 Like