1

I would like to create a plot in Shiny that the user can then download as a pdf using a custom font specified as a user input.

To be specific, I would like to use a pdf function such as pdf("plot.pdf", width = 5, height = 5, family = font.family), where the value of font.family is specified by the user.

Here is a simple example below: If I run the example on my machine, it works fine. However, when it is hosted on the RStudio shiny servers, I receive an error saying that the specified font family cannot be found. I think the problem is that the fonts I want are not accessible on the RStudio shiny servers, but is there a way I can include them?

server.R

shinyServer(function(input, output) {

output$distPlot <- renderPlot({

plot(1, xlim = c(0, 1), ylim = c(0, 1))
text(.5, .5, "Custom Font!!"
})

output$downloadPlot <- downloadHandler(

  filename = function() {paste('CustomFont.pdf')}, 
  content = function(file){

font.family <- input$font.family

pdf(file, width = 11, height= 8.5, family = font.family)

plot(1, xlim = c(0, 1), ylim = c(0, 1))
text(.5, .5, fonts(), cex = 10)


dev.off()
}, contentType = "image/pdf"
)
})

ui.R

 shinyUI(fluidPage(

 sidebarLayout(
 sidebarPanel(
  selectInput("font.family", "Choose Font", 
              choices = c("Helvetica Neue", "Times New Roman", "Arial")
  ),
  downloadButton("downloadPlot", "Download Plot as PDF")
),

# Show a plot of the plot
mainPanel(
  plotOutput("distPlot", width = "800px", height = "800px")
  ))))
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • 1
    What's the code that you run on your local machine that allows you to choose a custom font for a plot? Are you using the same operating system on both your local machine and where you are hosting your Shiny app? – MrFlick Jan 19 '15 at 22:37
  • side note : I think the you should take a look at `pdfFonts` to get an idea of the set of fonts used by `pdf`. Maybe you can execute `pdfFonts()` in the server and compare what you have locally. – agstudy Jan 19 '15 at 22:49
  • @agstudy: Thanks for the pdfFonts() tip! This allows me to see which fonts are available on the server. The issue now is that there are some fonts (like Helvetica Neue) that I'd like to use but aren't available on the server. Do you know if I can upload fonts to the Shiny server? – Nathaniel Phillips Jan 21 '15 at 10:42
  • @MrFlick: The code I use is exactly what I have above in the server.R and ui.R code. The selectInput argument allows the user to select the font for the resulting pdf download. I am currently using the default Shiny servers hosted by RStudio, (not my own) so I'm not sure exactly how their's is set up. – Nathaniel Phillips Jan 21 '15 at 10:44

1 Answers1

0

I had a similar problem. To solve that, much of the renderPlot() functionality was recreated using renderImage(), as described in this Shiny tutorial article. Font rendering then worked as desired.

This is the code which solved that question; it might also solve this one.

ui.R amend to

mainPanel(
  imageOutput("myImage")
)

server.R

shinyServer(function(input, output, session) {

  # A dynamically-sized plot
  output$myImage <- renderImage({
    # Read myImage's width and height. These are reactive values, so this
    # expression will re-run whenever they change.
    width  <- session$clientData$output_myImage_width
    height <- session$clientData$output_myImage_height

    # For high-res displays, this will be greater than 1
    pixelratio <- session$clientData$pixelratio

    # A temp file to save the output.
    outfile <- tempfile(fileext='.png')

    # Generate the image file
    png(outfile, width=width*pixelratio, height=height*pixelratio,
        res=72*pixelratio)
    plot(rnorm(100), rnorm(100), family="serif")
    dev.off()

    # Return a list containing the filename
    list(src = outfile,
         width = width,
         height = height,
         alt = "This is alternate text")
  }, deleteFile = TRUE) # delete the temp file when finished

})
Community
  • 1
  • 1
gatherer
  • 333
  • 1
  • 2
  • 9