Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unicode characters in plots to use in dynamic reports using R, Sweave and knitr

I have a problem properly displaying fonts in plots generated by ggplot2 in LaTeX reports generated by R studio in Sweave using knitr.

At first I was not able to properly generate pdfs with polish fonts but that problem was tackled in this post:

Unicode Characters in ggplot2 PDF Output

In short, the author adviced using Cairo package (in R) to generate plots using ggplot2.

This worked for me - once -> meaning I was able to generate a plot with polish characters, but when I am trying to use it in sweave document to generate LaTeX report using knitr like this:

<<pieniadze_graph,fig=TRUE,echo=FALSE>>=
library(Cairo)
cairo_pdf("TutorialExercisesPart2-pieniadze_graph.pdf")  
plot1 <- qplot(expenditure, data = cas) + xlim(0, 8000) + 
    xlab(expression(paste("Pieniądze wydane na ucznia ($)"))) +
    ylab("Liczba szkółńćźżś")
print(plot1)
@ 

I get an error.:

Running pdflatex on TutorialExercisesPart2.tex...failed

While investigating while that happend -> i found that the file that cairo is soppoused to generate is blank (there is a pdf file of a name given to cairo_pdf but it can not be opened with pdf viewer -> error cannot open text file)

Now one note is necessary: The cairo_pdf function requires file name to be set. So I give the pdf a name, that is required to be used later by the tex file in a format filename-chunk_name.pdf (So much for dynamic reports :P)

So I am not for the cairo_pdf option. Is there a way to generate proper pdf files without cairo_pdf option?

I was not able to find anything more on this topic without the cairo-pdf...

When I delete the cairo part my tex file is generated nicely with an ugly looking dots labels PDF file in it...

here is what ąćźżńół letters look like in generated report

Here is how an exported plot into png straight from Rstudio looks like

like image 888
WojciechF Avatar asked Jan 11 '23 07:01

WojciechF


2 Answers

Rather than opening a device like you do with calling cairo_pdf(), you should instruct knitr to use the device. Have a look at the knitr options and "dev" in particular. In summary, you need to

<<pieniadze_graph,fig=TRUE,echo=FALSE,dev='cairo_pdf'>>=
...

or to make it default for all chunks

opts_chunk$set(dev='cairo_pdf')
like image 189
Rosen Matev Avatar answered Jan 13 '23 20:01

Rosen Matev


Ok I finally got it!

It really was a problem with Sweave coding in the chunk heading.

After @Matev's response I began testing the dev='cairo_pdf' -> but this did not change anything in the output.

Why? Because the

<<dev='cairo_pdf'>>=
@

is only interpreted by knitr Rnw file weaver!!! And I was using the Sweave weaver (this is set in the global options of R studio under Sweave section).

After recognising the not-so-obvious mistake (Because both Sweave and knitr use similar chunk heading script format) I seached what Leisch had to say about that in his Sweave Manual. This is his solution for everyone who has the same problem:

  1. Put this code early in the document (after R libraries)

    <<>>=
    my.Swd <- function(name, width, height, ...)
    grDevices::cairo_pdf(filename = paste(name, "pdf", sep = "."),
    width = width, height = height)
    @
    
  2. You may now use the following code in seperate chunks

    <<chunk_name,grdevice=my.Swd,fig=TRUE>>=
    @
    

or as @Matev adviced globally set chunk options for the entire document (but again his answer was for the knitr weaver):

    \SweaveOpts{grdevice=my.Swd}

Now You will get beautiful plots generated by the cairo_pdf device (base R device) which handles uniode fonts nicely!!! And they will get sweaved into Your dynamic reports like magic!

And I would like to thank Yihui for the knitr package which is GREAT!

like image 39
WojciechF Avatar answered Jan 13 '23 19:01

WojciechF