Wednesday, 1 March 2017

r - ggplot with customized font not showing properly on shinyapps.io



I can customize the font in a ggplot with:



library(extrafont)


windowsFonts()
font_import(pattern = "comic", prompt = FALSE)
loadfonts(device = "win")
windowsFonts()

ggplot(mapping=aes(x=seq(1,10,.1), y=seq(1,10,.1))) +
geom_line(position="jitter", color="red", size=2) + theme_bw() +
theme(text=element_text(size=16, family="Comic Sans MS"))



This renders as:



enter image description here



More on the subject e.g. here and here






I can also integrate that plot and extrafont into a shiny app which runs locally as follows:




library(ggplot2)
library(extrafont)
library(shiny)

font_import(paths = "www", pattern = "comic", prompt = FALSE)
loadfonts()
print(fonts())

ui <- fluidPage(plotOutput("plot"),textOutput("fonts"))


server <- function(input, output) {
output$plot <- renderPlot({
ggplot(mapping=aes(x=seq(1,10,.1), y=seq(1,10,.1))) +
geom_line(position="jitter", color="red", size=2) + theme_bw() +
theme(text=element_text(size=16, family="Comic Sans MS"))
})
output$fonts <- renderText(print(fonts()))
}

shinyApp(ui = ui, server = server)






However, when I try to deploy this to shinyapps.io I get an error:




The application failed to start (exited with code 1).



Registering fonts with R Scanning ttf files in www ... Extracting .afm

files from .ttf files...
/srv/connect/apps/21-comic-font/www/comici.ttfWarnung in gzfile(dest,
"w") kann komprimierte Datei
'/opt/R/3.4.3/lib/R/library/extrafontdb/metrics/comici.afm.gz' nicht
öffnen. Grund evtl. 'Permission denied' Fehler in value[3L] :
kann Verbindung nicht öffnen Ruft auf: local ... tryCatch ->
tryCatchList -> tryCatchOne -> Ausführung angehalten








I tried to solve this by incorporating the answer from here. I added my .ttf files to the www directory and the extrafontdb package source to the r-lib directory. (And of course I deployed both..).



The complete app.R file now looks like:



.libPaths(c('r-lib', .libPaths()))
install.packages('r-lib/extrafontdb_1.0.tar.gz',type = 'source',repos = NULL)

library(ggplot2)
library(extrafontdb)

library(extrafont)
library(shiny)

font_import(paths = "www", pattern = "comic", prompt = FALSE)
loadfonts()
print(fonts())

ui <- fluidPage(plotOutput("plot"),textOutput("fonts"))

server <- function(input, output) {

output$plot <- renderPlot({
ggplot(mapping=aes(x=seq(1,10,.1), y=seq(1,10,.1))) +
geom_line(position="jitter", color="red", size=2) + theme_bw() +
theme(text=element_text(size=16, family="Comic Sans MS"))
})
output$fonts <- renderText(print(fonts()))
}

shinyApp(ui = ui, server = server)



When I deploy this I get a running app and the following output:



enter image description here



Now the strange thing is, that renderText(print(fonts())) prints Comic Sans MS. So it seems that my font got loaded. But the plot does not show the proper font.



Why is that? And how can I solve it?


Answer



I found a solution that seems to work on shinyapps.io (but not locally, since it is a Linux only solution. And somehow it did not work with my original 'ComicSans MS' font, but that font is not beautiful anyway.. ;-))




Here we go:




  1. Place custom font in www directory: e.g. IndieFlower.ttf from here

  2. Follow the steps from here



This leads to the following app.R file:




ibrary(ggplot2)
library(shiny)

dir.create('~/.fonts')
file.copy("www/IndieFlower.ttf", "~/.fonts")
system('fc-cache -f ~/.fonts')

ui <- fluidPage(plotOutput("plot"))

server <- function(input, output) {

output$plot <- renderPlot({
ggplot(mapping=aes(x=seq(1,10,.1), y=seq(1,10,.1))) +
geom_line(position="jitter", color="red", size=2) + theme_bw() +
theme(text=element_text(size = 16, family = "IndieFlower"))
})
}

shinyApp(ui = ui, server = server)



The plot looks like:



enter image description here


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...