Plotting with R - skewed eps image & resolution problem - r

I want to create a graphics of a function in R. The code is:
x <- seq(from=0, to=1, by=0.00001)
f <- function(x) ....
y <- f(x)
plot(x, y, xlab="x", ylab="f(x)", pch=16, cex=0.5)
min(y)
[1] 0.2291203
max(y)
[1] 0.7708797
When I save the graphics as bmp from RGui, it looks like here and this is fine. When I save it as eps and include in LaTeX with:
\begin{figure}[htbp]
\centering
\includegraphics[scale=0.4]{./images/f-probart.eps}
\end{figure}
it is skewed, as shown in the screen capture from here
What is wrong? I guess there is a problem with exporting from RGui in eps, as the resulted eps is also shown skewed in IrfanView. Hence I suspect that is not the LaTeX inclusion code that is wrong...
How could I create this graphics with a requested resolution, say 244 dpi? Is there another package/function that allows me to export eps with a specific resolution?
Thanks

I cannot reproduce your error, so I guess it's something specific to your system. If I save as eps and include it in latex (using the graphicx package), everything works completely fine. Keep in mind that if you used the postscript() function in R, you have to specify the width and height of your picture as well. I could be wrong, but I think it defaults to the default values of the graphics window in R (which could explain the dimensions of your eps pictures).
If you saved from the graphics window, it normally should take the current width and height of the graphics window. It does so on my R version, but maybe your options are set differently? check ps.options() and see if width and height have value 0. If that's not the case, that could be the problem.
On a side-note : You could use pdf instead. See ?pdf in R. It allows you to specify the width and height of the picture, and reproduces correctly in Latex. You should use pdftex for building the file then.
My experience is that using pdf graphics and pdftex is less trouble than passing through PS. In fact, in latex there is no need to pass through eps any more to come to a decent pdf. Another advantage of using pdftex is that you can easily combine all graphics formats in the same document. (For EPS you need the epstopdf package)
2) the dpi requirement is only useful for grid images, so not for eps and pdf which are vectorized. I'd use png, that's the best format for graphs. See the option res in the function png().
png("somefile.png",res=244)
plot(x, y, xlab="x", ylab="f(x)", pch=16, cex=0.5)
dev.off()
Alternatively, you could use the function bmp() for bitmap graphics in exactly the same way. Don't forget the dev.off() at the end.

I used the Cairo package; the code was:
Cairo(24000,24000,file="a.ps",type="ps",bg="transparent",pointsize=12, units="px", dpi=2400)
plot(x, y, xlab="x", ylab="f(x)", pch=16, cex=0.5, type='l')
dev.off()
The resulted graph looked fine. One question, however: according to #Joris Meys, the dpi is useless for vector graphics; in this case, why specifying dpi for the Cairo function is mandatory?

Related

Increasing resolutions of pdf graphics in R

If I'm creating pdf figures in R, is there an input argument analogous to res (for png) that I can use to increase the resolution from the default in the following:
pdf("Dsr_2b.pdf")
hist(Dsr,breaks=200,xlim=c(-0.03,0.03),main="Figure 2b: Dsr")
dev.off()
Nothing I saw in the documentation seemed to be geared to this.

filled.contour() in R: labeling axis - cex, las, et al

I want to use filled.contour() to plot some data I have in a matrix.
Everything is perfect until when I import the graphics into my tex file and realize I need to play with the font size for it to be readable in the final document.
Unfortunately, it seems I am unable to tune the parameter cex in filled.contour(), and the same goes for las (I'd like the ylabel to be parallel to the x axis).
Below is a simple example. Although I expected the output to be different in each case, namely the font size, the produced plot is pretty much the same.
Thanks a lot for any help you can give me on this.
x=1:10
y=1:10
z=array(rnorm(100),dim=c(10,10))
filled.contour(x,y,z)
filled.contour(x,y,z,xlab='x',ylab='y')
filled.contour(x,y,z,xlab='x',ylab='y',las=1)
filled.contour(x,y,z,xlab='x',ylab='y',las=1,cex=2)
filled.contour(x,y,z,xlab='x',ylab='y',las=1,cex=20)
#QuantIbex is right, though you can also pass through other graphics parameters by specifying in the plot.title, plot.axes, key.title and key.axes arguments.
This is necessary because the usual graphics parameters are not passed straight through, as described in ?filled.contour:
...: additional graphical parameters, currently only passed to
‘title()’.
E.g.:
x=1:10
y=1:10
z=array(rnorm(100),dim=c(10,10))
filled.contour(x,y,z,las=0,
plot.axes={
axis(1,cex.axis=2)
axis(2,cex.axis=2)
},
plot.title={
title(xlab="x",cex.lab=2)
mtext("y",2,cex=2,line=3,las=1)
}
)

How to get R plot window size?

How can I get the size of the plot window in R? I've been using xwininfo, but there must be a function or variable in R to extract the current plot height and width.
UPDATE
This works as a savePlot() replacement if you don't have Cairo support and you want to export plots to Windows or other 100 dpi devices:
dev.copy(png, "myplot.png", width=dev.size("px")[1], height=dev.size("px")[2],
res=100, bg="transparent")
dev.off()
You can use dev.size. Here is an example:
x11()
plot(1)
dev.size("in")
[1] 6.989583 6.992017
dev.size("cm")
[1] 17.75354 17.75972
This gets the size of your plotting window in inches and centimeters.
Similar for a png device:
png('kk.png')
dev.size("in")
[1] 6.666667 6.666667
Does this help you?
As mentioned , using some par settings you can control control the size and the location of the plot regions. But those parameters can be a little bit confusing.( at least for me), I tried to resume some of them in this plot precising the units of each parameter.
PS: the original graphics is adpated from Paul Murrel Book: R graphics.
You should have a look to par()$fin.
HTH

How to reduce size of knitr generated pdf file?

I'm working with Rnw file that I knit into a pdf report.
All is working smoothly so far, but my report is consists of quite an amount of figures and maps.
So the problem that appeared now is that the final version of the report is over 200MB, which makes it quite a pain to share around. I believe it is mostly caused by the vector (pdf) graphics included.
Are there any solutions / strategies to reduce the size of such large report?
You can play with the device function to set which graphical device is used to record plots. For latex it is pdf by default, to change it to png (as mentioned by #Roland) you can do this for example:
<<my-label, eval=TRUE, dev='png'>>=
set.seed(1213) # for reproducibility
x = cumsum(rnorm(100))
mean(x) # mean of x
plot(x, type = 'l') # Brownian motion
#

Producing a vector graphics image (i.e. metafile) in R suitable for printing in Word 2007

First a caveat: I posted this question here on SuperUser, but it is clearly the wrong place to ask R questions. I recognize that it is not directly a programming question, but I believe it can be solved by changing how plots are produced (i.e. by coding appropriately). So I hope readers find this appropriate for the forum.
R plots usually consist entirely of vector graphics elements (i.e. points, lines, polygons, text). R permits you to save your figure (or copy-paste) in various formats including various raster formats, as a PDF, or as a Windows meta-file.
I usually save my images as PDFs and print them. This renders the images exactly as I intended them on paper, in the highest quality. I avoid raster formats (e.g. JPG, TIFF) for printing as inevitably the quality is poorer and publishers prefer vector formats.
However, I need to make a large multi-page desktop published document using Microsoft Word 2007, and therefore using PDFs is not an option. When I import my figures from meta-files, or copy and paste directly from R into Word both the screen and print rendering of the image changes slightly (e.g. polygons and their fills become slightly misaligned).
Given that I want to retain high vector quality (and not use raster formats), what can I do to make R vector graphics work with Word? (Of course Sweave and LaTeX would be nice, but again, not a realistic option).
Consider this example:
plot(c(1:100), c(1:100), pch=20)
## Copy and paste to Word 2007 as Windows metafile
## Print
## Quality is poorer (e.g. dot fills misaligned with borders)
pdf("printsPerfectly.pdf")
plot(c(1:100), c(1:100), pch=20)
dev.off()
## Now print PDF
## Quality is as expected
EDIT: Further to suggestions by #John I produced it as an EPS postscript file (see below), inserted it as a picture into Word. Because ultimately it will be printed from a PDF created from Word, I converted it to a PDF using default Word 2007 settings, printed it on my HP Laserjet P1606dn laser printer, and then took aphotograph to illustrate the issue of polygons borders and fills misaligning (image on left, below). I also produced it directly as PDF from R using pdf() and printed the PDF and took a photograph (image on right, below).
It may seem like small potatoes! But when you have gone to a lot of trouble to achieve high quality, it is disappointing to be thwarted at the end. In addition, it is not really obvious here, but the numerals are not as high-quality (left) as in the PDF (right), disregarding differences in focus on the photograph.
The accepted answer to me is not acceptable, since if one goes to the trouble of making a nice vector based figure, the last thing one would like to do is just rasterize it to a bitmap... Unless it's an increadibly complex graph that takes ages to render in vector format, or something like that, but for most graphs that's not the case.
The best solution is to export to Word directly in native Office vector format. I just made a new package, export, that allows one to do exactly that an allows export of either graphs or statistical tables to Word and Powerpoint, see
https://cran.r-project.org/web/packages/export/index.html and for demo see
https://github.com/tomwenseleers/export
For example:
library(devtools)
devtools::install_github("tomwenseleers/export")
library(export)
?graph2ppt
?graph2doc
?table2ppt
?table2doc
## export of ggplot2 plot
library(ggplot2)
qplot(Sepal.Length, Petal.Length, data = iris, color = Species,
size = Petal.Width, alpha = I(0.7))
# export to Word
graph2doc(file="ggplot2_plot.docx", width=7, height=5)
# export to Powerpoint
graph2ppt(file="ggplot2_plot.pptx", width=7, height=5)
You can also export to enhanced metafile using the function
graph2emf(file="ggplot2_plot.emf", width=7, height=5)
but the quality of the native Office format is better.
For final production you can also readily print it to PDF from Powerpoint if need be, and it will stay nicely in vector format then.
Your only option is to use high resolution raster graphics. Once you're over 300 dpi it will be completely indistinguishable from vector printed; it will just make larger files.. Your copy and paste method is coming in at 72 dpi and will look terrible. If you import from a file you can get the resolution in the file and things will be much better. Fortunately Office 2007 is supposed to handle png images, which have the best compression for typical graphs. Let's say you wanted the image 4" wide and 6" high...
png('printsGreat.png', width = 4, height = 6, units = 'in', res = 300)
plot(c(1:100), c(1:100), pch=20)
dev.off()
Also, Office 2007 is supposed to be able to handle EPS files and R postscript files are by default EPS compatible when you print one page.
postscript("printsPerfectly.eps", width = 4, height = 6, horizontal = FALSE, onefile = FALSE)
plot(c(1:100), c(1:100), pch=20)
dev.off()
But if you don't have luck with them go back to the high resolution image.
My preferred solution is to use the windows metafile device for plotting, e.g.:
win.metafile("mygraph.wmf")
print(gg1)
dev.off()
This produces a *.wmf file that can be copy-pasted into the word file.
The devEMF package seems to produce graphics that look nicer than the default wmf when pasted into PowerPoint.
Since I tried to produce png at high res in R and it didn't seem to work on my PC (if I set the resolution higher than, say, 300 dpi, R would produce an error like "cannot start png device"), the way I found was to save the figure using postscript() and then use GSView to convert the ps file into png with 600 dpi resolution. MS Word consumes the png's happily and the quality of print seems to be perfect.
What #Tom Wenseleers said:
The current best answer above to me is not acceptable, since if one
goes to the trouble of making a nice vector based figure, the last
thing one would like to do is just rasterize it to a bitmap... Unless
it's an increadibly complex graph that takes ages to render in vector
format, or something like that, but for most graphs that's not the
case.
For me, there is a new best answer to this question, since graph2ppt and graph2doc tend to move axis labels around (which apparently cannot be fixed; see here: https://github.com/davidgohel/rvg/blob/master/R/body_add_vg.R and here: export::graph2office moves axis labels around).
I think that .svg is the most appropriate vector format for usage with publication graphics. The only drawback is that older versions of e.g. MS Word cannot handle it. IN R, you could use the native graphics::svg - device. However, I'd recommend to use CairoSVG from the Cairo - Package, especially when you are working with non-native fonts (e.g. via the extrafont - package), because in contrast to graphics::svg, Cairo::CairoSVG embeds fonts quite nicely (without relying on GhostScript, if I am right).
If you are working with an older version of MS Word, you could use incscape (a free vector graphic editor) and convert your graph to .wmf, for example (which might be better than printing to .wmf directly, because R rasterizes points when exporting .wmf files).
An example:
## create plot
library (ggplot2)
library (extrafont)
# note: if you want to use other fonts than the standard ones - in this example "ChantillyLH" -
# you must register your fonts via
# font_import () ##run only once (type "y" in the console)
# and
# loadfonts (device = "win") ##run only once.
# Otherwise, the extrafont - package is not needed.
beautiful_plot <-
ggplot (data = iris, mapping = aes (x = Sepal.Length, y = Petal.Length)) +
geom_point () +
theme (text = element_text (size = 18,
family = "ChantillyLH")
)
# export SVG
library (Cairo)
CairoSVG ("My_Path/My_Plot.svg", width = 6, height = 6)
print (beautiful_plot)
dev.off ()
# the resulting SVG-file is in the the "My_Path" - Folder.
In Incscape, it looks like this:
Newer versions of Word can import raster graphics from SVG files. R 3.6.2 has built-in support for creating SVG files with the svg function - no extra packages needed.
Your example then becomes
svg("printsPerfectly.svg", width=4, height=4)
plot(c(1:100), c(1:100), pch=20)
dev.off()
Note that there is a known issue when you try to create PDF files from Word documents with embedded SVG files with thin lines. If you are using thin lines, e.g. with lwd=0.7 somewhere, you need to apply this workaround.

Resources