sammerk sammerk - 3 months ago 22
R Question

renderImage() and .svg in shiny app

I don't get

renderImage()
to work with a .svg file.
My minimal example (adapted from the corresponding RStudio-tutorial):

ui.R



shinyUI(pageWithSidebar(
headerPanel("renderSVG example"),
sidebarPanel(
sliderInput("obs", "Number of observations:",
min = 0, max = 1000, value = 500),
actionButton("savePlot", "savePlot")
),
mainPanel(
# Use imageOutput to place the image on the page
imageOutput("plot"),
imageOutput("plot_as_svg")
)
))


server.R



require("ggplot2")
library(svglite)

shinyServer(function(input, output, session) {

## create plot with renderPlot()


output$plot<- renderPlot({
hist(rnorm(input$obs), main="Generated in renderPlot()")
})


## create .svg file of the plot and render it with renderImage()

output$plot_as_svg <- renderImage({
# A temp file to save the output.
# This file will be removed later by renderImage
outfile <- tempfile(fileext='.svg')

# Generate the svg
svglite(outfile, width=400, height=300)
hist(rnorm(input$obs), main="Generated in renderImage()")
dev.off()

# Return a list containing the filename
list(src = outfile,
contentType = 'text/svg+xml',
width = 400,
height = 300,
alt = "This is alternate text")
}, deleteFile = TRUE)

})


Any ideas where the problem is?

Answer

Inspired by R_User123456789s solution (here) for base graphics above I got it the following way with ggplot2

ui.r

shinyUI(pageWithSidebar(
  headerPanel("renderSVG example"),
  sidebarPanel(
    sliderInput("obs", "Number of observations:",
                min = 0, max = 1000,  value = 500)
  ),
  mainPanel(
    # Use imageOutput to place the image on the page
    imageOutput("plot"),
    imageOutput("plot_as_svg")
  )
))

server.r

require("ggplot2")

shinyServer(function(input, output, session) {

  ## create plot with renderPlot()


  output$plot<- renderPlot({
    hist(rnorm(input$obs), main="Generated in renderPlot() as png")
  })


  ## create .svg file of the plot and render it with renderImage()

  output$plot_as_svg <- renderImage({

    width  <- session$clientData$output_plot_width
    height <- session$clientData$output_plot_height
    mysvgwidth <- width/96
    mysvgheight <- height/96

    # A temp file to save the output.
    # This file will be removed later by renderImage

    outfile <- tempfile(fileext='.svg')

    # Generate the svg
    #to see actually what will be plotted and compare 
    qplot(clarity, data=diamonds, fill=cut, geom="bar")
    #save the plot in a variable image to be able to export to svg
    image=qplot(clarity, data=diamonds[1:input$obs,], fill=cut, geom="bar", main = "ggplot as svg")
    #This actually save the plot in a image
    ggsave(file=outfile, plot=image, width=mysvgwidth, height=mysvgheight)

    # Return a list containing the filename
    list(src = normalizePath(outfile),
         contentType = 'image/svg+xml',
         width = width,
         height = height,
         alt = "My svg Histogram")
  })

})