Skip to content

Instantly share code, notes, and snippets.

@aagarw30
Created January 18, 2016 14:55
Show Gist options
  • Save aagarw30/6c10d6d92f5d512cae41 to your computer and use it in GitHub Desktop.
Save aagarw30/6c10d6d92f5d512cae41 to your computer and use it in GitHub Desktop.
R Shiny - Download plot demo
library(shiny)
shinyServer(function(input,output)({
# x contains all the observations of the x variable selected by the user. X is a reactive function
x <- reactive({
iris[,as.numeric(input$var1)]
})
# x contains all the observations of the y variable selected by the user. Y is a reactive function
y <- reactive({
iris[,as.numeric(input$var2)]
})
# xl contains the x variable or column name of the iris dataset selected by the user
xl <- reactive({
names(iris[as.numeric(input$var1)])
})
# yl contains the y variable or column name of the iris dataset selected by the user
yl <- reactive({
names(iris[as.numeric(input$var2)])
})
# render the plot so could be used to display the plot in the mainPanel
output$plot <- renderPlot({
plot(x=x(), y=y(), main = "iris dataset plot", xlab = xl(), ylab = yl())
})
# downloadHandler contains 2 arguments as functions, namely filename, content
output$down <- downloadHandler(
filename = function() {
paste("iris", input$var3, sep=".")
},
# content is a function with argument file. content writes the plot to the device
content = function(file) {
if(input$var3 == "png")
png(file) # open the png device
else
pdf(file) # open the pdf device
plot(x=x(), y=y(), main = "iris dataset plot", xlab = xl(), ylab = yl()) # draw the plot
dev.off() # turn the device off
}
)
}))
library(shiny)
shinyUI(fluidPage(
titlePanel("Download base plot in Shiny - an example"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "var1", label = "Select the X variable", choices = c("Sepal.Length" = 1, "Sepal.Width" = 2, "Petal.Length" = 3, "Petal.Width" = 4)),
selectInput(inputId = "var2", label = "Select the Y variable", choices = c("Sepal.Length" = 1, "Sepal.Width" = 2, "Petal.Length" = 3, "Petal.Width" = 4), selected = 2),
radioButtons(inputId = "var3", label = "Select the file type", choices = list("png", "pdf"))
),
mainPanel(
plotOutput("plot"),
downloadButton(outputId = "down", label = "Download the plot")
)
)
))
@SymbolixAU
Copy link

Rather than draw your plot twice, once in the renderPlot() and again in the downloadHandler(), you can create a plot function and call that in both instances.

e.g.

## a plot function
myPlot <- function(){
    plot(x=x(), y=y(), main = "iris dataset plot", xlab = xl(), ylab = yl())
}

## call the plot function to show on the page
output$plot <- renderPlot({
    myPlot()
})

## call the plot function when downloading the image
output$down <- downloadHandler(
    filename =  function() {
      paste("iris", input$var3, sep=".")
    },
    # content is a function with argument file. content writes the plot to the device
    content = function(file) {
      if(input$var3 == "png")
        png(file) # open the png device
      else
        pdf(file) # open the pdf device
      myPlot() 
      dev.off()  # turn the device off

    } 
)

@askhari139
Copy link

Hi. downloadHandler returns a blank image when the plot is saved in a reactive element. Any idea why?

@Achavez18
Copy link

Achavez18 commented Feb 10, 2018

I couldn't download as a pdf file somting could help me

Plot

implied by the dependency graph.

Gage_RR_plot <- reactive({
if(is.null(csv_table())){return()}

ss.rr(var = Voltage, part = Battery,
               appr = Voltmeter,
               data = csv_table(),
               main = "Six Sigma Gage R&R Measure",
               sub = "Batteries Project MSA")

 })

output$Gageplot <- renderPlot({
print(Gage_RR_plot())
})

the following renderUI is used to dynamically generate the tabsets when the file is loaded. Until the file is loaded, app will not show the tabset.

output$contents <- renderUI({
if(is.null(csv_table()))
h5("N/D")
else
tabsetPanel(tabPanel("Data", tableOutput("table")),
tabPanel("Output Gage R&R",renderPrint(
#Gage R&R
ss.rr(var = Voltage, part = Battery,
appr = Voltmeter,
data = csv_table(),
main = "Six Sigma Gage R&R Measure",
sub = "Batteries Project MSA"))),
tabPanel("Gage R&R", plotOutput("Gageplot",height = 700 ,width = 500),
# downloadHandler contains 2 arguments as functions, namely filename, content

                     output$downloadPlot <- downloadHandler(filename = function(){
                       paste("","pdf",sep=".")
                     },
                       #specify file name                             
                         content = function(file) {
                        #open de device
                           pdf(file)
                           #create the plot
                          print(Gageplot()) 
                          # close the device
                           dev.off()
                        },
                 contentType='pdf'
                       
                     )))

})

})

shinyApp(ui, server)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment