# [S] Summary: Creating postscript for LaTeX

John Castelloe (jcaste@stat.uiowa.edu)
Sun, 18 Oct 1998 12:41:51 -0500

Thanks to everyone who offered advice on creating postscript files in
S-Plus and including them in LaTeX documents. Below (following the
original question) is a collection of responses discussing strategies for
both Windows and UNIX platforms (somewhat mixed together-- sorry).
(Responses contributed by Fei Chen, Roger Koenker, Alan Zaslavsky, Jarle
Tufto, Frank E. Harrell Jr., Steven M. Boker, Brian D. Ripley, Anona
Thorne, Terry M. Therneau, Henrik Aalborg-Nielsen, Paul Monaghan, and Lutz
Prechelt)
--------------------------------------------------------------------------
Original post:

What are the best methods to create postscript files (with reliable height
and width) from S-Plus and import them into LaTeX documents? I'm
interested in automated techiniques which could be most seamlessly
integrated into already-existing functions which create large numbers of
plots in for-loops, and which could create postscript files that don't need
to be meticulously dealt with on the LaTeX end (eg., adjustment of bounding
boxes). I'd appreciate suggestions both for the S-Plus and LaTeX end of
things.

Also, a couple related questions: Is it possible to include special
characters (eg. Greek letters) in S-Plus graphs? What is a good way to
incorporate the placement of legends in the scheme mentioned above-- does
it need to be automatic, or can placement still be done with locator()? I
am generating large numbers of plots in for-loops, each with its own
legend. It's difficult to automate placement since I don't know in advance
which areas of the plot will have the most white space.

John
--------------------------------------------------------------------------
Responses:
--------------------------------------------------------------------------
this is what i do for my papers and plots:

postscript(print=F,onefile=F)
for(i in 1:10)
plot(...)
dev.off()

and the resulting ps.out.000?.ps can be incorporated easily into latex (i
use the package epsfig2, which allows you to rotate and scale the ps file
exactly. you probably know that the ps filels generated by s+ are in eps
format? you can also specify ps file names if you wish.
--------------------------------------------------------------------------
There is some discussion of this in a paper I've done for local
consumption here and which is available at

briefly I use the postscript device driver from S and \usepackage{graphics}
in latex. There is an interesting package called psfrag for special
fonts, but I've not had time to install it workable here yet. The
paper also discusses related techniques for tables.
--------------------------------------------------------------------------
> Is it possible to include special
> characters (eg. Greek letters) in S-Plus graphs?

This is a definite FAQ - shows up about once every year. Here are several
solutions:

(1) for a single Greek character: use the "symbol" font (Font 13 on Unix
systems, I don't know about the PCs).

(2) if it suits your needs and you are on a PC, use the graph editing
features.

(3) if you need to mix things up in one label, use my "postscriptfonts"
archive from Statlib. THese functions allow you to create simple to
moderately complex labels using a string with escape sequences for change
of font, super and subscripts, change of size, etc. Takes some fiddling
to make it beautiful but it works entirely within S-plus.

(4) use the "psfrag" utilities (there are a few variations around) that
work with LaTeX or TeX, so you can create the label in those languages and
have them appear within a PostScript plot. THe way to go for truly
high-quality typesettnig, but requries some additional steps.
--------------------------------------------------------------------------
To produce postscript file:

postscript(file="figure.eps",height=3,width=3)
...
dev.off()

To produce greek letter you may consider using R instead of S-plus.
R allow expressions to be used instead of text strings in the text()
command and as labels in plots. You can, for example, do

plot(x,y,xlab=expression(bar(x) == sum(frac(alpha[i], n))))

For more info on this feature, look at the help for R's text function
at

R itself is available from

You can alternatively use S-plus and replace text strings in the graph
with the psfrag package in LaTeX, by doing something like

\usepackage{psfrag}
...
\begin{figure}
\psfrag{x}{\bar x = \sum \frac{\alpha_i}{n}}
\includegraphics{figure.eps}
\end{figure}
--------------------------------------------------------------------------
See our web page, under Stat Computing Tools

I use a little function setps to make nice postscript for books
and articles - nice fonts, spacing of tick mark labels, etc.
setps is in my Hmisc library. This doesn't help with greek letters etc.
------------
hesweb1.med.virginia.edu/biostat
--------------------------------------------------------------------------
Here's a real life code snip:

for (tSubject in c(1:115)) {
tData <- c(irAMmoodAMmood[tSubject,theBackIndex],irAMmoodAMmood[tSubject,])
tepsfile <- paste("CrossCorrelations/", theSubjects[tSubject],
"-irAMmoodAMmood.eps",sep="")
tmain <- paste("AM Mood \n Autocorrelation for ",
theSubjects[tSubject], sep="")
postscript(tepsfile,height=6.4,horizontal=F)
plot(c(-totalLags,totalLags), c(-1,1), xlab="Days", ylab="Pearson
Product Moment Correlation", main=tmain, axes=T, type="n")
lines(seq(-totalLags,totalLags,by=1),tData, type="l")
dev.off()
}

You can see that I'm storing creating a vector tData that has the
data I want to plot, creating a filename tepsfile that includes a
pathname so that all these encapsulated postscript files will be
on their own directore, creating a main title for the graph that
includes the subject's ID, setting up the postscript device drivers
with an appropriate size and not landscape orientation. Finally
I'm doing the plot and turning the device driver off. This loop
creates 115 different plots that I then process as part of a latex
document.
--------------------------------------------------------------------------
> I forgot to mention that I am using S-Plus 4.5r2 on a Win95 PC, in case
> that makes a difference. (Sorry for the duplicate posting).

Yes, it makes an enormous difference. I do not believe there is a reliable
way to create EPS files on that system. The postscript() graphics driver
does not generate EPS, Export Graph generates (IMHO) poor-quality plots, so
one is reduced to using win.printer/graphsheet with a PostScript printer
driver. On Windows 95 I know of no good one for EPS (I use Adobe's driver
for the distiller device, but it less than ideal). On NT I believe that
Adobe does now have a level-2 only driver that gives EPS output.

A serious competitor is to use pdf.graph and either the ExportPS plug-in to
Acrobat Exchange or ghostscript to convert PDF to EPS.

For Greek letters in graphs to be incorporated into LaTeX, use PSTricks:
see the LaTeX Graphics Companion.

For placement: take a look at key() to replace legend().
--------------------------------------------------------------------------
The next message from me will be the Splus code that runs a sample plot with
Greek symbols in the legend. I'm running it on Unix, but I'm assuming that
you should be able to do the same thing on a pc.

# note: this routine uses mixed.text.vector
# (note that mixed.text could also be used)
# to print nice symbols
# so it is necessary to put the plot into a postscript file
# rather than using an X11 or motif window.
# This routine includes the postscript command for creating the file
# as well as the ghostscript command at the end for viewing it.
# When you run this routine, it's not necessary to have an X11 window
# open, but if you do, it will do no harm.

# does a barplot showing percentage cleared at each time point
# by ethambutol susceptibility

# includes only the 86 subjects on the 3-drug arm
# on therapy for at least 4 weeks

counts_c(33,42,47,0,50,71,67,33,50,79,67,100,50,82,67,100)
cntmat_matrix(counts,4,4,byrow=F)

postscript(print.it=F,file="symbols.ps")

par(oma=c(0,0,1,0),mgp=c(2.3,.8,0))
xcoord_barplot(cntmat, beside=T,space=c(0,1.0),density=c(50,25,14,-1),
yaxt="n",
ylim=c(0,110),
xlab="Week",
ylab="Percentage",
main="Percentage of Patients in each Ethambutol Susceptibility Group
Clearing Bacteremia over Time
for Subjects on Therapy for at least 4 Weeks")

# calculate co-ordinates for week numbers
xforweeks_rep(NA,4)
for (i in 1:4)
{
xforweeks[i]_(xcoord[i*4]-xcoord[i*4-3])/2 + xcoord[i*4-3]
}
# print the week numbers
axis(1,at=xforweeks,lab=c(2,4,8,12),ticks=F,line=-1.3)
axis(2,at=seq(0,100,20),lab=seq(0,100,20),crt=0,tck=.01,cex=.9)

#legend(.7,103,c("MIC <= 2 microgm/ml (n=6)","MIC = 4 microgm/ml
(n=62)","MIC = 8 microgm/ml (n=15)","MIC > 8 microgm/ml
(n=3)"),density=c(50,25,14,-1),bty="n")
# print the symbols for the legend:
legend(.7,103,c(" "," "," "," "),density=c(50,25,14,-1),bty="n")

# print the legend descriptions:
# note: in font 13, All.ASCII[164] is the <= symbol and
# All.ASCII[180] is the >= symbol;
mixed.text.vector(3,103-4.5,
c(1,13,1,13,1),
c("MIC ",All.ASCII[164]," 2 ","m","/ml (n=6)"))
mixed.text.vector(3,103-10.5,
c(1,13,1),
c("MIC = 4 ","m","/ml (n=62)"))
mixed.text.vector(3,103-16.5,
c(1,13,1),
c("MIC = 8 ","m","/ml (n=15)"))
mixed.text.vector(3,103-22.5,
c(1,13,1),
c("MIC > 8 ","m","/ml (n=3)"))

#text(xcoord,counts+2,labels=counts)
rm(counts,cntmat,xcoord,xforweeks)

par(oma=rep(0,4),mgp=c(3,1,0))

# turn off the postscript device
dev.off()

# use ghostscript to view the plot;
# type "quit" to get out of ghostscript
!gs symbols.ps

This is the line which I insert into the Latex file when I want to include a
plot:
\resizebox{\textwidth}{!}{\includegraphics[.5in,2.0in][8in,11in]{slides.ps}}

I've only used it in the slides documentclass, but I would expect it to work
for articles, etc.. One important thing: once you've produced your
postscript file, you need to go in and edit it and delete the last line.
Otherwise, the plot will be displayed perfectly well with xdvi, but when you
try to print your .dvi file, the plot page and all subsequent pages will not
be printed.

Again, this is all based on Unix use. Hope it helps.
--------------------------------------------------------------------------
I use the following to import graphs into Latex2e. This uses nothing
except what is in the official 2e manual, so should work across platforms.

Add the following definition to my TeX file:

\usepackage[dvips]{graphics}

\newcommand{\mfigwide}{\textwidth} %figure width to use
\newcommand{\mfighigh}{3.5in} %figure height to use
\newcommand{\myfig}[1]{\resizebox{\mfigwide}{\mfighigh}
{\includegraphics{../figure/#1}}}

Then in the body of the file

\begin{figure}
\myfig{figprop5.eps}
\caption{Time dependent coefficient plot for the gastric data}
\label{figprop5}
\end{figure}

----------
I happen to have all of my graphs in a directory "figure", each
named "fig_something.eps". You could easily change the "../" part of
the definition.

In the S code I create a graph using the following function:

makefig <- function(file, horizo=F, top=1, right=1) {
ps.options(pointsize=12) # opinion: the default 14 is too big here
postscript(file=file, onefile=F, print.it=F, horizo=horizo)
par(mar=c(4,4,top,right)+.1)
}

makefig("figxxx.eps")
plot
plot
dev.off()

The "onefile=F" = one-file-might-contain-multiple-figures argument is key
here. If each file is guarranteed to contain only one figure, then Splus
produces EPS.

---
Unfortunately, some of the optional arguments to the postscript function
vary between platforms (at least in some Splus versions).  Check your
manual page for spellings.
--------------------------------------------------------------------------
I'v created a function like:

EPS.bw.setup <-
function(width, height, pts = 10, file = "S.eps")
{
postscript(file = file, onefile = F, print.it = F, horizontal = F,
width = width, height = height, pointsize = pts)
invisible()
}

To create a 4 x 3 in EPS-file ('S.eps') with a plot:

S> EPS.bw.setup(4,3)
S> # Plot cmds.
S> dev.off()

In LaTeX I use the package 'graphicx and include the file with the
command: '\includegraphics{S.eps}'

To make the plot look nice it's a good idear to experiment with the
graphical parameters 'mar' and 'oma' (use 'ghostview' to display
'S.eps' on screen).

If you collect the plotting instructions in a S-function this should
start like:

EPS.bw.setup(4,3)
on.exit(dev.off())

If you want to include many plots in one postscript file then
'onefile' should be 'TRUE' in the call to 'postscript()'.  However, I
think then the postscript code is no longer encapsulated and I don't
know how '\includegraphics{S.eps}' will react.
--------------------------------------------------------------------------
I'm afraid I know nothing of Splus for Windows but may be able to help
with the
LaTeX end. I will assume that you have created a postscript file of the
graph you want.

The graphicx package is excellent for rotating, scaling and other manipulation
of graphics files, whereas to include Greek (or other) letters you need the
(literally)
and you want alpha (the Greek letter), you tell LaTeX to identify the text
string 'alpha' and replace it with $\alpha$. These packages, with full
documentation, and other packages are
available at the TeX archive at

http://www.tex.ac.uk
--------------------------------------------------------------------------
>  Also, a couple related questions:  Is it possible to include special
>  characters (eg. Greek letters) in S-Plus graphs?

If you are talking of a LaTeX'ed Postscript version only: yes.
Use the pstricks package. It essentially allows for replacing any
string in your postscript with whatever LaTeX code you want
(e.g. you label something 'sgma' in your plot and then replace
that string by a LaTeX \sigma)
--------------------------------------------------------------------------

---------------------------------------------------------------
| John Castelloe       phone: (319)335-2009                     |
| Computer RA            fax: (319)335-3017                     |
| Dept. of Statistics    web: http://www.stat.uiowa.edu/~jcaste |
| University of Iowa  office: 269 SH                            |
---------------------------------------------------------------
-----------------------------------------------------------------------
This message was distributed by s-news@wubios.wustl.edu.  To unsubscribe
send e-mail to s-news-request@wubios.wustl.edu with the BODY of the
message:  unsubscribe s-news
`