We are about to submit a final camera-ready version of a manuscript and they sent us this email the other day reminding us, among other things, to “adhere to the prescribed [ACM] format as set out in paragraph 2.3.10 [1]”… In a nutshell, they want all figures in EPS format. Now I am very particular about font-consistency when integrating plots within TeX documents, and so I spent most of last night trying to figure this out. I eventually decided to leverage a somewhat widely used technique–‘tikzexternalize’. I found this [2] thread on StackExchange really helpful.
The Problem
I have ten ggplot2 plots that I would like to output to EPS format and at the same time ensure that the fonts used on the plots are consistent with the LaTeX document I am integrating them into.
My normal LaTeX/R plot integration workflow is simple: I run Sweave to generate native TeX code and subsequently integrate resulting ‘.tex’ within the main LaTeX document. This makes it possible for plot fonts to be consistent with whatever font I am using within the LaTeX document. However, this workflow breaks if I use a different output format. The problem is that if I generate EPS files using the traditional R way using postscript function [3], there is NO guarantee that the resulting plot fonts will be consistent with the main LaTeX document.
The Solution
- Run Sweave files to generate TeX equilavalent plots (R CMD Sweave [FILENAME].Rnw)
- Create dumy/fake LaTeX document with class corresponding and integrate Sweave generated TeX using ‘\input’
- Ensure preamble is set up for externalization
- Run LaTeX document using ‘latex –shell-escape FILENAME’ command
- EPS outputs will be generated with incremental names relative to their position within dummy/fake document ([FAKEDOCNAME]-figure0.eps … [FAKEDOCNAME]-figure[N].eps)
- Integrate EPS output in manuscript using ‘\epsfig’ or ‘\includegraphics’
- Run latex or pdflatex on main LaTeX manuscript
A Minimal Example
Sweave file
# Import required packages require(tikzDevice) require(ggplot2) require(reshape2) require(grid) require(scales) require(ggthemes) # Generate native TikZ TeX ouput tikz('minimal_example_plot.tex') dataset <- read.csv( text="Age_Range,Total,Male,Female,Rural_Total,Rural_Male,Rural_Female,Urban_Total,Urban_Male,Urban_Female <1,14698,7293,7405,11536,5736,5800,3162,1557,1605 1-4,63824,31588,32236,49110,24299,24811,14714,7289,7425 5-9,67542,33702,33840,51919,26059,25860,15623,7643,7980 10-14,63241,31573,31668,47725,24319,23406,15516,7254,8262 15-19,52788,26518,26270,38025,19360,18665,14763,7158,7605 20-24,40587,19013,21574,28419,13494,14925,12168,5519,6649 25-29,35558,16909,18649,24678,11865,12813,10880,5044,5836 30-34,28170,14392,13778,19360,9843,9517,8810,4549,4261 35-39,23123,12149,10974,16375,8406,7969,6748,3743,3005 40-44,15747,8285,7462,11578,5951,5627,4169,2334,1835 45-49,12885,6371,6514,9709,4718,4991,3176,1653,1523 50-54,9815,4776,5039,7487,3585,3902,2328,1191,1137 55-59,6722,3270,3452,5299,2536,2763,1423,734,689 60-64,6319,2775,3544,5137,2194,2943,1182,581,601 65-69,4834,2016,2818,4076,1658,2418,758,358,400 70-74,3942,1703,2239,3421,1441,1980,521,262,259 75-79,2819,1276,1543,2479,1132,1347,340,144,196 80-84,1449,655,794,1298,584,714,151,71,80 85+,1720,670,1050,1525,601,924,195,69,126", header=TRUE ) # re-order requests dataset$Age_Range <- factor(dataset$Age_Range, levels=c("<1","1-4","5-9","10-14","15-19","20-24","25-29","30-34","35-39","40-44", "45-49", "50-54", "55-59", "60-64", "65-69", "70-74", "75-79", "80-84", "85+"), labels=c("< 1","1 - 4","5 - 9","10 - 14","15 - 19","20 - 24","25 - 29","30 - 34","35 - 39","40 - 44", "45 - 49", "50 - 54", "55 - 59", "60 - 64", "65 - 69", "70 - 74", "75 - 79", "80 - 84", "85+")) # Convert dataset to molten form experimentdataset <- melt(dataset[c(1, 3:4)], id.vars=c(1)) # Dummy column for fancy faceting experimentdataset["yaba"] <- "Population in Chipata, Zambia (2010 Census of Population)" # Rename levels levels(experimentdataset$variable)[levels(experimentdataset$variable)=="Male"] <- paste("Male Individuals","") levels(experimentdataset$variable)[levels(experimentdataset$variable)=="Female"] <- paste("Female Individuals","") # Final plot ggplot(data=experimentdataset, aes(x=as.factor(Age_Range), y=value, colour=variable, group=variable)) + geom_line(aes(linetype=variable), size=1.5) + geom_point(aes(shape=variable), fill="white", size=1.5) + scale_shape_manual(values=c(1,1)) + scale_linetype_manual(values=c("solid","solid")) + facet_wrap(~ yaba, scales="free_x") + labs(x="Population age ranges",y="Number of individuals") + scale_colour_stata() + theme(legend.title=element_blank(), legend.position="bottom", legend.text=element_text(size=14) legend.key.height=unit(0.35,"cm"), plot.margin=unit(c(0.1,0,-0.5,0.8),"cm"), strip.text = element_text(size=14), axis.title.x = element_text(vjust=-0.8,size=14), axis.title.y = element_text(vjust=-0.2,size=14), axis.text = element_text(size=14), axis.text.x = element_text(angle=90, vjust=0.5)) + guides(linetype=guide_legend(nrow=1,byrow=TRUE),shape=guide_legend(nrow=1,byrow=TRUE)) @
- Run the file above using command below
phiri@phiri-ThinkPad-T540p:~/Dropbox$ R CMD Sweave minimal_example_plot.Rnw Loading required package: tikzDevice : /tmp/RtmpzWjQDz/tikzMetricsDictionary Output file: minimal_example_plot.tex phiri@phiri-ThinkPad-T540p:~/Dropbox$
Dummy/fake host LaTeX document
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 \documentclass[a4paper,10pt]{article}
\usepackage{charter}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzset{external/system call={latex \tikzexternalcheckshellescape -halt-on-error
-interaction=batchmode -jobname "\image" "\texsource";
dvips -o "\image".ps "\image".dvi;
ps2eps "\image.ps"}}
\tikzexternalize
\begin{document}
\input{minimal_example_plot.tex}
\end{document}
- Fake document MUST have lines 4 to 11
- The fake host LaTeX document MUST be run using latex NOT pdflatex (see command below)
phiri@phiri-ThinkPad-T540p:~/Dropbox$ latex --shell-escape minimal_example_fake.tex This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013) : :
Actual LaTeX document
Run the main LaTeX document normally, e.g. using pdflatex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 \documentclass[a4paper,12pt]{article}
\usepackage{charter}
\usepackage{graphicx}
\begin{document}
This is a sample output file. Notice how the text font is consistent with the font used in Figure~\ref{fig:minimal_example_plot}
\begin{figure*}[htbp]
\includegraphics[width=\textwidth]{minimal_example_fake-figure0.eps}
\caption{This plot an integrated into the current document using EPS format}
\label{fig:minimal_example_plot}
\end{figure*}
\end{document}
phiri@phiri-ThinkPad-T540p:~/Dropbox$ pdflatex minimal_example.tex This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013) : :
Final Output

Some Useful Notes
- I found that I did not have to provide explicit width and height parameters to tikz function within my Sweave (.Rnw) files
- I had to painstakingly figure out the appropriate font size for EPS output. Original TeX output use 8-point and I eventually settled for 14-point for EPS output
- EPS output quality is too inferior–see comparison in figure below

Bibliography
[1] http://www.acm.org/sigs/publications/sigguide-v2.2sp
[2] http://tex.stackexchange.com/a/8646/17923
[3] http://stat.ethz.ch/R-manual/R-patched/library/grDevices/html/postscript.html