Reputation: 6437
I have tried to apply the answers given in both this question on saving plots, and this question on downloading reactive outputs without success. I am not sure if my reactive function is outputting the wrong type of data or if my downloadHandler()
is not written properly.
Also, the linked questions pass function()
s to reactive()
which I am warned is deprecated, so I have avoided it here. (The behavior did not change, though.)
ui.R:
library(shiny)
# Define UI for application
shinyUI(pageWithSidebar(
# Application title
headerPanel("App"),
sidebarPanel(
downloadButton("savemap", label="Download Map (Hires)")
),
mainPanel(
tabsetPanel(
tabPanel("Map",
plotOutput("myworld", height="650px",width="750px",
clickId="plotclick")
)
)
)
))
server.R
library(shiny)
library(maps)
library(mapdata)
library(rworldmap)
library(gridExtra)
shinyServer(function(input, output) {
theworld <- reactive({
myplot <- map("world2", wrap=TRUE, plot=TRUE,
resolution=2)
})
output$myworld <- renderPlot({
print(theworld())
})
output$savemap <- downloadHandler(
filename = function() {
paste('fuzzymap-', Sys.Date(), '.png', sep="")
},
content = function(file) {
# function to actually write the image file
# https://stackoverflow.com/questions/14810409/save-plots-made-in-a-shiny-app?rq=1
png(file)
print(theworld())
dev.off()
})
})
The map in the reactive function is plotted sucessfully at startup. The download prompt is generated and a png file downloads, but it contains no data. Additionally, the following non-fatal error is returned, but a search turned up no leads:
Error opening file: 2
Error reading: 9
Upvotes: 1
Views: 1756
Reputation: 103898
I think you're confused about what map()
returns. You call it for its
side-effect of drawing a plot, not it's return value. Rather than making
it a reactive value, just keep it as an anonymous function.
Here's a simplified version that works for me:
library(shiny)
library(maps)
ui <- bootstrapPage(
plotOutput("myworld", height = 450, width = 750),
downloadButton("savemap", "Download map")
)
theworld <- function() {
map("world2", wrap = TRUE, resolution = 2)
}
server <- function(input, output) {
output$myworld <- renderPlot({
theworld()
})
output$savemap <- downloadHandler(
filename = function() {
paste0("fuzzymap-", Sys.Date(), ".png")
},
content = function(file) {
png(file)
theworld()
dev.off()
}
)
}
runApp(list(server = server, ui = ui))
Upvotes: 5