How to output two grid plots(grid.draw) togather and download them in shinyapp?

I used grid.draw() function of ggnewscale package to get the plot

But it seems the way of download is not the same to ggplot2 type.

I used pdf() to save my plot result in shinyapp.

But when I click the download button the plot result is not picture type or not pdf

It confused me.

Here is my reproducible code and data:

   options(encoding = "UTF-8")
    library(stats)
    library(openxlsx)
    library(shiny)
    library(dplyr)
    library(tidyr)      
    library(ggplot2)
    library(gridExtra)  
    library(ggpubr)
    library(shinythemes)
    library(ggpattern)
    library(grid)
    library(ggh4x)
    library(ggnewscale)
    library(psych)
    library(DT)
    library(shinyBS)
    library(shinyjs)    
    
    ###
    
    
data <- data.frame(
  Name = c(paste0("Group_", LETTERS[1:20])),
  matx <- matrix(sample(1:1000, 1000, replace = T), nrow = 20)
)
names(data)[-1] <- c(paste0("Gene_", 1:50))


Nameff<-structure(list(Name = c("8_TBI(1 month)", "9_control", "9_VEGF", 
                                "10_control", "10_VEGF", "11_Brain Healty", "12_control_1", "12_control_2", 
                                "12_AOD(Jnk1/2/3 ko)", "13_control", "13_Cpt1_ko(Cdh5 driven)", 
                                "14_control", "14_Tsc2ko(Tbx4 driven)", "15_control", "15_Zmpste24 ko", 
                                "16_control", "16_Adrenomedullin\r\nko(Cdh5 driven)", "17_Lung Healthy", 
                                "18_control(14w)", "18_carboplatin(14w)"), Disease = c("TBI\r\n1month", 
                                                                                       "VEGF\r\nsti_DG\r\nregion", "VEGF\r\nsti_DG\r\nregion", "VEGF\r\nsti_CA1\r\nregion", 
                                                                                       "VEGF\r\nsti_CA1\r\nregion", "Healthy\r\n(Brain)", "AOD", "AOD", 
                                                                                       "AOD", "CPT1\r\nko", "CPT1\r\nko", "Tsc2\r\nko", "Tsc2\r\nko", 
                                                                                       "Zmpste\r\n_24 ko", "Zmpste\r\n_24 ko", "AM\r\nko", "AM\r\nko", 
                                                                                       "Healthy\r\n(Lung)", "Chemo/Radio\r\n(Tibiae)", "Chemo/Radio\r\n(Tibiae)"
                                ), Organ = c("Brain", "Brain", "Brain", "Brain", "Brain", "Brain", 
                                             "Lung", "Lung", "Lung", "Lung", "Lung", "Lung", "Lung", "Lung", 
                                             "Lung", "Lung", "Lung", "Lung", "Bone", "Bone"), fill = c("#f15a24", 
                                                                                                       "#FFFFFF", "#f15a24", "#FFFFFF", "#f15a24", "#FFFFFF", "#FFFFFF", 
                                                                                                       "#FFFFFF", "#00FF00", "#FFFFFF", "#00FF00", "#FFFFFF", "#00FF00", 
                                                                                                       "#FFFFFF", "#00FF00", "#FFFFFF", "#00FF00", "#FFFFFF", "#FFFFFF", 
                                                                                                       "#7570B3"), Condition = c("#CCCCFF", "#d9e021", "#d9e021", "#d9e021", 
                                                                                                                                 "#d9e021", "#CCCCFF", "#CCCCFF", "#CCCCFF", "#CCCCFF", "#fbb03b", 
                                                                                                                                 "#fbb03b", "#fbb03b", "#fbb03b", "#fbb03b", "#fbb03b", "#fbb03b", 
                                                                                                                                 "#fbb03b", "#fbb03b", "#d9e021", "#d9e021"), Organ_fill = c("#f15a24", 
                                                                                                                                                                                             "#f15a24", "#f15a24", "#f15a24", "#f15a24", "#f15a24", "#00FF00", 
                                                                                                                                                                                             "#00FF00", "#00FF00", "#00FF00", "#00FF00", "#00FF00", "#00FF00", 
                                                                                                                                                                                             "#00FF00", "#00FF00", "#00FF00", "#00FF00", "#00FF00", "#7570B3", 
                                                                                                                                                                                             "#7570B3"), Alpha = c(1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 
                                                                                                                                                                                                                   0, 1, 0, 1, 0, 0, 1)), row.names = 22:41, class = "data.frame")
####################################################################
ui <- fluidPage(
  theme = shinytheme("superhero"),
  ##
  useShinyjs(),
  ##  
  pageWithSidebar(
    tags$h4(
      Sys.time()),
    sidebarPanel(
      tags$h3("1111"),
      selectInput(
        "selectGeneSymbol", 
        "444d:", 
        choices = colnames(data[,-1]),
        multiple =F,
        width = 400,
        selected = NULL
      ),

      actionButton(inputId = "plot1", label = "down1",width=80),
      actionButton(inputId = "plot2", label = "down2",width=80),
      actionButton(inputId = "all",label = "down1&down2",width=120),
      
      hr(),
      tags$h5(tags$strong("down:")),
      downloadButton("p1", "down1",width=120),
      downloadButton("p2", "down2",width=120)
      
    ),
    
    mainPanel(
      tabsetPanel(
        tabPanel(icon("home"),

                 uiOutput("all")


                 ))
)
)
)
server <- function(input, output, session) {
  ##
  
  plot_data1 <- reactive({
    subset(data, colnames(data[,-1]) %in% input$selectGeneSymbol)
  })
  
  plot_data2 <- reactive({
    subset(data, colnames(data[,-1]) %in% input$selectGeneSymbol)
  })
  
  ##
  global <- reactiveValues(out = NULL,
                           p1 = NULL,
                           p2 = NULL)
  ## 
  observeEvent(input$plot1, {
    global$out <- plotOutput("plot1", height=600)
  })
  ##
  observeEvent(input$plot2, {
    global$out <- plotOutput("plot2", height=600)
  })
  
  observeEvent(input$all, {
    global$out <- plotOutput("plot3", height=600)
  })
  ###############
  output$all <- renderUI({
    global$out
  })
  
  p1 <- eventReactive(list(input$plot1,
                           input$all), {
                            datamean_sd<-data.frame(
                               Nameff,
                               mean=tapply(data[,input$selectGeneSymbol],data$Name,mean),
                               sd=tapply(data[,input$selectGeneSymbol],data$Name,sd)
                             ) 

                             p<-ggplot(data = datamean_sd, aes(Name,mean, label = Name, fill=Organ)) +
                               geom_bar(position="dodge2", stat="identity",width = 0.85,color="black",alpha=datamean_sd$Alpha) +
                               facet_nested(.~Organ+Disease, scales = "free_x", space = "free_x",switch = "x")+
                               theme_classic2() +
                               theme(legend.position = "bottom",
                                     legend.box = "horizontal",
                                     plot.title = element_text(hjust = 0.5),
                                     plot.margin = unit(c(5, 10, 20, 15), "mm"),
                                     strip.background = element_rect(colour="black", fill="white"),
                                     strip.text.x = element_text(size = 6, angle=0),
                                     axis.text.x=element_text(size=8),
                                     strip.placement = "outside"
                               ) +
                               rotate_x_text(angle = 90)+
                               scale_fill_manual(name = "Organ",values = unique(datamean_sd$Organ_fill))

                             gt <- ggplotGrob(p)
                             grid::grid.newpage(); grid::grid.draw(gt)
                           })
  
  p2 <- eventReactive(list(input$plot2,
                           input$all), {
                             datamean_sd<-data.frame(
                               Nameff,
                               mean=tapply(data[,input$selectGeneSymbol],data$Name,mean),
                               sd=tapply(data[,input$selectGeneSymbol],data$Name,sd)
                             ) 
                             
                             p<-ggplot(data = datamean_sd, aes(Name,mean, label = Name, fill=Organ)) +
                               geom_bar(position="dodge2", stat="identity",width = 0.85,color="black",alpha=datamean_sd$Alpha) +
                               facet_nested(.~Organ+Disease, scales = "free_x", space = "free_x",switch = "x")+
                               theme_classic2() +
                               theme(legend.position = "bottom",
                                     legend.box = "horizontal",
                                     plot.title = element_text(hjust = 0.5),
                                     plot.margin = unit(c(5, 10, 20, 15), "mm"),
                                     strip.background = element_rect(colour="black", fill="white"),
                                     strip.text.x = element_text(size = 6, angle=0),
                                     axis.text.x=element_text(size=8),
                                     strip.placement = "outside"
                               ) +
                               rotate_x_text(angle = 90)+
                               scale_fill_manual(name = "Organ",values = unique(datamean_sd$Organ_fill))
                             
                             gt <- ggplotGrob(p)
                             grid::grid.newpage(); grid::grid.draw(gt)
                             
                           })
  

  
  output$plot1 <- renderPlot({ p1() })
  output$plot2 <- renderPlot({ p2() })
  output$plot3 <- renderPlot({ 
    ##    plot_list <- list(p1(),p2())
    #    grid.arrange(grob(p1(),p2(), ncol=1)) 
    lollipop <- gTree(children = gList(p1(), p2()))
    grid.draw(lollipop)
    
  })
  #download p1
  output$p1 <- downloadHandler(
    filename = function() {
      paste0(input$selectGeneSymbol,"_123",".pdf")
    },
    content = function(file) {
      pdf(file,width=20,height=10)
      datamean_sd<-data.frame(
        Nameff,
        mean=tapply(data[,input$selectGeneSymbol],data$Name,mean),
        sd=tapply(data[,input$selectGeneSymbol],data$Name,sd)
      ) 
      
      p<-ggplot(data = datamean_sd, aes(Name,mean, label = Name, fill=Organ)) +
        geom_bar(position="dodge2", stat="identity",width = 0.85,color="black",alpha=datamean_sd$Alpha) +
        facet_nested(.~Organ+Disease, scales = "free_x", space = "free_x",switch = "x")+
        theme_classic2() +
        theme(legend.position = "bottom",
              legend.box = "horizontal",
              plot.title = element_text(hjust = 0.5),
              plot.margin = unit(c(5, 10, 20, 15), "mm"),
              strip.background = element_rect(colour="black", fill="white"),
              strip.text.x = element_text(size = 6, angle=0),
              axis.text.x=element_text(size=8),
              strip.placement = "outside"
        ) +
        rotate_x_text(angle = 90)+
        scale_fill_manual(name = "Organ",values = unique(datamean_sd$Organ_fill))
      
      gt <- ggplotGrob(p)
      grid::grid.newpage(); grid::grid.draw(gt)
      dev.off()
    }
  )
  
  #download p2
  output$p2 <- downloadHandler(
    filename = function() {
      paste0(input$selectGeneSymbol,"_123",".pdf")
    },
    content = function(file) {
      ggsave(file,p2(),width=20,height=10)
      grid::grid.newpage(); grid::grid.draw(gt)
      dev.off()
    }
  )


}


# Create Shiny app ----
shinyApp(ui = ui, server = server)

The biggest problem to me is I used the grid.draw() to create a plot in p1() in my shiny.
And I don't know how to download it in downloadHandler() function.

I tried to use grid::grid.newpage(); grid::grid.draw(gt) in downloadHandler() but it doesn't work.

I found a stupid solution that is run the code of p1() in downloadHandler() again so I can download it but it is complex you know.
Just like this:

https://stackoverflow.com/questions/46499719/error-in-using-heatmap-as-the-plot-input-of-ggsave

I know there is something wrong in my download code. But I need your help to deal with it.

I need the right way to download grid.draw(plot) result in shinyapp.

I found a not perfectly way to download p1 or p2 in downloadHandler() but I need a better way to deal with it.

And all of p1 and p2 are grid types .I'd like to output them togather .
But it doesn't work when I use grid.arrange(p1(),p2()) function.
Because it is used for ggplot2 type.

#########

My first question: how to download p1 or p2 in a better way because of the grid type plot.

My second question: how to output p1() and p2() togathere just like grid.arrange() function?

Vary thanks.

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.