Making flattened pdfs in Sweave - r

So I am creating pdfs using Sweave that include some graphs that have a ton of points on them. I can get the pdf well enough, but it seems to have created it with a ton of layers, so it's hard to open the file in Acrobat or Reader. When I do, I literally can watch the points load on the document.
Is there a way to flatten the pdf in Sweave so that it's not so bulky?
(Note that I am using RStudio. I know I should probably be using something else, but I haven't found anything that has worked this smoothly yet.)

There is no need to switch to Knitr for this, though there are plenty of advantages in doing so.
One solution is just to arrange for the plot file to be produced and then include it yourself rather than rely on Sweave to do it for you
<<gen_fig, echo=true, eval=true>>=
png("path/to/fig/location/my_fig.png")
plot(1:10)
dev.off()
#
\includegraphics[options_here]{path/to/fig/location/my_fig}
Another option is to consider whether a plot with a "ton of points" is a useful figure - can you see all the points? Is the density of the points of interest? Alternatives include plotting via the hexbin package or generating a 2-d density of the points and plotting that as a lower-density set of points. The ggplot2 package has plenty of this functionality built in, see e.g. stat__bin2d() or stat_binhex() for examples.

As Gavin said, there is no need to switch to knitr for this, though there are other advantages to do so. However, you don't even need to write your own saving and including code; Sweave can do that for you. If the initial document is:
\documentclass{article}
\usepackage[american]{babel}
\begin{document}
<<>>=
n <- 100000
DF <- data.frame(x=rnorm(n), y=rnorm(n))
#
<<gen_fig, fig=TRUE>>=
plot(DF)
#
\end{document}
Then just by changing the arguments to the figure chunk, you can get a PNG instead of a PDF:
<<gen_fig, fig=TRUE, png=TRUE, pdf=FALSE>>=
plot(DF)
#
In this simple example, it shrinks my final PDF from 685K to 70K.

As has already been mentioned you should probably switch to knitr, which makes swapping between pdfs and other formats much nicer. In particular, you should look at:
the transition guide between knitr and sweave
global options: that way you can easily swap between pdfs, high-res png and low-res pngs.
caching: only generate the figures when needed.
Here is an example of using the PNG device:
\documentclass{article}
\begin{document}
<<gen_fig, dev='png'>>=
n <- 100000
DF <- data.frame(x=rnorm(n), y=rnorm(n))
plot(DF)
#
\end{document}
There is no need to specify fig=TRUE for knitr. If the image quality of the PNG device in the graphics package is not enough, you can easily switch to other PNG devices, e.g. dev='CairoPNG' or 'Cairo_png'. In Sweave you just write more code to do the same thing.

Related

How to using code to save plots in Rstudio?

Is there any way to save the plots by code in RStudio?
Like something in Python save.plt().
I have noticed the function savePlot can save the figures but I cannot load it in RStudio, since it reports the errors in loading X11().
This leads me to think about another question... What is your way to using R or what is the proper way to using R? As a beginner I found RStudio is super easy to use and I like the idea that saving all the environments into a single file. But apparently it is no need to using X11() in plotting...
If you want to save from code the plot that is displayed in the RStudio plot tab then you have to call for example
rstudioapi::savePlotAsImage("test.png",width=300,height=150)
Plots can be saved as a jpg:
jpeg("Name_of_your_plot.jpg")
# your plot for example
plot(x,y)
dev.off()
Instead of jpg you can choose other image formats such as png, pdf or PostScript. The above code can be modified as:
png("Name_of_your_plot.png")
# your plot for example
plot(x,y)
dev.off()
If you have a ggplot you can use ggsave.

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...
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')
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:
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)
#
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!

Produce two plots from same chunk / statement in knitr

Is it possible to have plot-generating code output two versions of the same figure, at different sizes, from a .Rmd document? Either through chunk options (I didn't see anything that works directly here), or through a custom knitr hook? Preferably this would be done with the png device.
My motivation: I'd like to be able to output a figure at one size, which would fit inline in a compiled HTML document, and another figure that a user could show after clicking (think fancybox). I think I'll be able to handle the scripting necessary to make that work; however, first I need to convince R / knitr to output two versions of the figure.
Although I'm sure there are workarounds, it would be best if there was some way to get it to 'just work' behind the scenes, e.g. through a knitr hook. That way, we don't have to do anything special to the R code within a chunk, we just modify how we parse / evaluate that chunk.
Alternatively, one could use SVG graphics that would scale nicely, but then we lose the nice inference of good sizes for the plot labels, and vector graphics aren't great for plots with many many points.
I thought there was not a solution, and was about to say no to #baptiste, but got a hack in my mind soon. Below is an R Markdown example:
```{r test, dev='png', fig.ext=c('png', 'large.png'), fig.height=c(4, 10), fig.width=c(4, 10)}
library(ggplot2)
qplot(speed, dist, data=cars)
```
See the [original plot](figure/test.png) and
a [larger version](figure/test.large.png).
The reason I thought the vectorized version of dev would not work was: for dev=c('png', 'png'), the second png file will overwrite the first one because the figure filename is the same. Then I realized fig.ext was also vectorized, and a file extension like large.png does not really destroy the file extension png; this is why it is a hack.
Anyway, by vectorized versions of dev, fig.ext, fig.height, and fig.width, you can save the same plot to multiple versions. If you use a deterministic pattern for the figure file extensions, I think you can also cook up some JavaScript code to automatically attach fancy boxes onto images.
If you just need the small and large figure, can you just do:
<<plotSmall, fig.height=6, fig.width=8, out.width='.1\\textwidth'>>=
plot(...)
#
<<plotBig, fig.height=6, fig.width=8, out.width='.99\\textwidth'>>=
plot(...)
#
Or more simply:
<<plotBoth, fig.height=6, fig.width=8, out.width=c('.1\\textwidth', '.9\\textwidth')>>=
plot(...)
plot(...)
#
(sure you know this, but .Rmd is for LaTeX, while .Rhtml is for html - the .Rhtml syntax is slightly different.)

have knitr output figures in different formats

Let's say I have a long report that produces a lot of figures which knitr makes as pdfs and it works really well with LaTeX. At the end of the project, my co-authors would like to have also raster based figures. One option would be to convert everything using ImageMagick. Another option would be to specify for each chunk dev = c("jpg", "pdf"), but given the number of figures, this could be cumbersome.
Is there a global switch to make knitr produce figures in pdf and other formats at the same time?
I think in the preamble
opts_chunk$set(dev = c("pdf", "jpg"))
should do. Within a R-chunk of course.

Redirecting R output and graphs

I use Sweave and LaTex to create reports from R output and graphs. But sometime it is required to have graphs in editable format. I tried R2wd package but it doesn't seem very flexible with ggplot2. I'd highly appreciate if someone point out me some efficient ways. Thanks
It really depends what you mean by "editable", and what kinds of files/endpoints you're talking about. There are a lot of discussions out there (e.g. this R-help thread from 2006) about (1) the best options for generating figures to embed in Word (or PowerPoint, which is pretty much the same question) and (2) the best options for figures that can be edited (by which I mean that they can be modified by non-R-users, not just moved from file to file). The general conclusions I have seen are:
PDF files: vector format, editable in Adobe Illustrator ($$$), only sorta-kinda-embeddable in MS Office documents
Windows metafiles or extended metafiles (WMF/EMF): vector format, very limited support outside of the Windows platform. Somewhat wonky format, but MS Office-native. Will certainly have limited support for things like alpha channels (transparency).
SVG: vector format. Very modern, editable in Inkscape (don't know where else), not particularly MS Office-compatible (I think). (Generatable at least via the Cairo package.)
PNG: raster format, but very compact (you can make the resolution absurdly large and still have a reasonably small output file); probably the easiest/lowest-common-denominator solution if you only need portability and not editability.
As of R 2.13.0, Sweave can automatically generate both PDF and PNG files on the fly for each figure chunk. If this is saved as document foo.Rnw:
\documentclass{article}
\begin{document}
\SweaveOpts{png=TRUE,pdf=TRUE,eps=FALSE}
<<fig1,fig=TRUE>>=
plot(1:5,1:5,col=1:5,pch=16)
#
\end{document}
... then after Sweaveing your directory will contain the files foo-fig1.png and foo-fig1.pdf. I don't know if that answers your question, but your question isn't entirely clear ...
The package pgfSweave links together Sweave with tikzDevice. tikzDevice uses the LaTeX tikz package to put the instructions to draw a plot into LaTeX code. So you can copy the resulting code from one file to another. pgfSweave also adds some handy features like cacheing.
You could also just output PDFs of your plots with pdf() and then insert the LaTeX code to load those plots as figures. You lose the automated file management of Sweave that way though.

Resources