-1

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 and I viewed several methods(here) but it doesn't work

I also get some advice Here

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.

花落思量错
  • 352
  • 1
  • 11
  • 1
    Is this really a minimal example needed to demonstrate the problem? – Roman Luštrik Apr 15 '21 at 08:00
  • @RomanLuštrik Yeah,it's important to me . – 花落思量错 Apr 15 '21 at 08:16
  • @YBS sir,where are you – 花落思量错 Apr 15 '21 at 08:29
  • Who can do me a favor? – 花落思量错 Apr 15 '21 at 09:12
  • Answers [here](https://stackoverflow.com/questions/62378430/how-to-download-graphs-which-are-dynamic-in-r-shiny/62380138#62380138) might help you. – YBS Apr 15 '21 at 10:50
  • You can also try [here](https://stackoverflow.com/questions/65921012/download-plots-and-tables-in-shiny-in-r-choosing-from-selection-of-tables-plots/65923042#65923042) – YBS Apr 15 '21 at 11:19
  • @YBS Sorry sir, I read what you marked here. I know how to download ggplot2 type plot. But my plot is created by grid.draw() in p1() or p2(). You can see that. I tried several methods just like the tutorials you sent to me but it doesn't work. – 花落思量错 Apr 15 '21 at 15:18
  • @YBS In p1() , I used ggplot2 but I also used ggplotGrob to translate my plot to grid type and then I made some modification. So when I use ggsave or pdf() to save my plot1 it saved nothing but a empty pdf file. I found a stupid way to save this type plot that is duplicated p1() code in downloadHandler and you can see in my code above. It really dose work!! Also makes the code more cumbersome. – 花落思量错 Apr 15 '21 at 15:24
  • @YBS hi, sir. I’m so excited to tell you that I deal with it by myself.Just minutes. I find a amazing package ggplotify . It can convert grid type plot to ggplot2. So that I can output it and download it as ggplot2 type. Everything works well. – 花落思量错 Apr 15 '21 at 16:06
  • That is great!! – YBS Apr 15 '21 at 16:19

1 Answers1

1

Here is my solution .I found a fantastic package that gives me inspiration.

The ggplotify package is created by Guangchuang Yu (School of Basic Medical Sciences, Southern Medical University China)

There is a as.ggplot() function. A amazing function. More secrets about ggplotify can be found here

In my code, I just add as.ggplot in p1(),or p2() .Just to view my answer code below:

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)

                            aa<-as.ggplot(gt)
                            aa
                           })
  
  p2 <- eventReactive(list(input$plot2,
                           input$all), {

                 omit here
                             
                           })
  

  
  output$plot1 <- renderPlot({ p1() })
  output$plot2 <- renderPlot({ p2() })
  output$plot3 <- renderPlot({ 
    ##    plot_list <- list(p1(),p2())
        grid.arrange(grob(p1(),p2(), ncol=1)) 

    
  })
  #download p1
  output$p1 <- downloadHandler(
    filename = function() {
      paste0(input$selectGeneSymbol,"_123",".pdf")
    },
    content = function(file) {
      pdf(file,p1(),width=20,height=10)
      ## ggsave(file,p1(),width=16, height=10)

    }
  )
  
  #download p2
  output$p2 <- downloadHandler(
    filename = function() {
      paste0(input$selectGeneSymbol,"_123",".pdf")
    },
    content = function(file) {
      ggsave(file,p2(),width=20,height=10)

    }
  )


}


# Create Shiny app ----
shinyApp(ui = ui, server = server)
花落思量错
  • 352
  • 1
  • 11