I want to adapt this code to be able to choose which plot I want to download in pdf format. I have tried to assign the plot to an object called "p1" for plot1 and "p2" for plot2 and then call the objects in each condition but it doesn't work. The only way it works is as it is now that I put the complete function of the plot, but I can't choose which of the two.
I also want to put the download button inside the sidebarPanel but then it stops working. How can I make it to be in the sidebar?
library(shiny)
# Define UI for application that draws a histogram
ui <- 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 plot", choices = list("plot1", "plot2"))
),
mainPanel(
plotOutput("plot"),
plotOutput("plot2"),
downloadButton(outputId = "down", label = "Download the plot")
)
)
)
# Define server logic required to draw a histogram
server <- 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())
})
# render the plot so could be used to display the plot in the mainPanel
output$plot2 <- renderPlot({
plot(x=x(), y=y(), main = "iris plot 2", xlab = xl(), ylab = yl(), col = "blue")
})
# 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 == "plot1")
pdf(file) # open the png device
# if(input$var3 == "png2")
# pdf(file)
else
pdf(file) # open the pdf device
plot(x=x(), y=y(), main = "iris dataset plot", xlab = xl(), ylab = yl())
dev.off() # turn the device off
}
)
}
# Run the application
shinyApp(ui = ui, server = server)
CodePudding user response:
You can use recordPlot()
to put the plot in an object and replayPlot()
in an opened device:
library(shiny)
# Define UI
ui <- 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 plot",
choices = list("plot1", "plot2")
)
),
mainPanel(
plotOutput("plot"),
plotOutput("plot2"),
downloadButton(outputId = "down", label = "Download the plot")
)
)
)
# Define server logic required to draw a histogram
server <- 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)])
})
Plot1 <- reactive({
plot(
x=x(), y=y(), main = "iris dataset plot", xlab = xl(), ylab = yl()
)
recordPlot()
})
Plot2 <- reactive({
plot(
x=x(), y=y(), main = "iris plot 2", xlab = xl(), ylab = yl(), col = "blue"
)
recordPlot()
})
# render the plot so could be used to display the plot in the mainPanel
output$plot <- renderPlot({
Plot1()
})
# render the plot so could be used to display the plot in the mainPanel
output$plot2 <- renderPlot({
Plot2()
})
# downloadHandler contains 2 arguments as functions, namely filename, content
output$down <- downloadHandler(
filename = function() {
paste("iris", input$var3, "pdf", sep=".")
},
# content is a function with argument file. content writes the plot to the device
content = function(file) {
if(input$var3 == "plot1"){
pdf(file)
replayPlot(Plot1())
dev.off()
}else{
pdf(file)
replayPlot(Plot2())
dev.off()
}
}
)
}
# Run the application
shinyApp(ui = ui, server = server)