You are here:
Vanderbilt Biostatistics Wiki
>
Main Web
>
StatComp
>
RS
>
SgraphicsHints
(07 Apr 2012,
FrankHarrell
)
(raw view)
E
dit
A
ttach
---+ S Graphics Hints and Tricks * [[#RGraphSetups][Graphics Setup Templates]] * [[#RGraphPanelNos][Adding panel numbers in margins of multi-panel graphs]] * [[#EmbedFonts][Embedding fonts for certain journal submissions]] * [[#TwoAxes][Making plots with Two Y-axes]] * [[#CompressPdf][Compressing PDF Files]] * [[#SmallPostscript][Making Small Postscript Files]] * [[#ModPstree][Modifying Postscript Files for Customizing Trees]] * [[#TrellislatticeStrips][Changing Trellis/Lattice Strip Characteristics]] * [[PsFrag][Putting !LaTeX typesetting inside graphics]] * [[http://rwiki.sciviews.org/doku.php?id=tips:graphics-misc:export Exporting graphics to office documents]] | [[#ExportGraphOffice][More Information]] | [[http://stats.stackexchange.com/questions/21380/in-r-what-is-the-best-graphics-driver-for-using-the-graphs-in-microsoft-word StackExchange]] * Several ways to graph [[http://wiki.r-project.org/rwiki/doku.php?id=tips:graphics-base:errbars error bars]] #RGraphSetups ---+++ R Graphics Setup Templates Besides the Hmisc package's =setpdf= and =setps= functions, you can use commands like the following to make publication-ready graphics. <highlight> pdf('/tmp/z.pdf', pointsize=16) par(mar=c(3.5, 3.5,.5,.5), lwd=2, mgp = c(2.2, 0.45, 0), tcl = -0.4) for(i in 1:2)plot(runif(100),xlab='Label for X',ylab='Label for Y') dev.off() postscript('/tmp/z.ps', pointsize=24) par(mar=c(2.825, 3, .125, 1.5), lwd=2, mgp = c(2, 0.45, 0), tcl = -0.4) for(i in 1:2)plot(runif(100),xlab='Label for X',ylab='Label for Y') dev.off() postscript('/tmp/z.eps', pointsize=14, onefile=FALSE, paper='special', horizontal=FALSE, height=4, width=5) par(mar=c(3, 3.25, .25, .5), lwd=2, mgp = c(2, 0.45, 0), tcl = -0.4) plot(runif(100),xlab='Label for X',ylab='Label for Y') dev.off() </highlight> The following function sets up for single low-level plots and matrices of plots in a way that is useful with Sweave. Note that =par= parameters have only been optimized for single and 2x2 plots. <highlight> spar <- function(mar=if(!axes) c(2.25+bot-.45*multi,1.5+left,.5+top+.25*multi,.5+rt) else c(3.25+bot-.45*multi,3.5+left,.5+top+.25*multi,.5+rt), lwd = if(multi)1 else 1.75, mgp = if(!axes) mgp=c(.75, .1, 0) else if(multi) c(1.5, .365, 0) else c(2.4-.4, 0.475, 0), tcl = if(multi)-0.25 else -0.4, bot=0, left=0, top=0, rt=0, ps=if(multi) 14 else 10, mfrow=NULL, axes=TRUE, ...) { multi <- length(mfrow) > 0 par(mar=mar, lwd=lwd, mgp=mgp, tcl=tcl, ps=ps, ...) if(multi) par(mfrow=mfrow) } </highlight> Example calls: <highlight> spar() # single plot spar(mfrow=c(2,2)) # 2x2 matrix of plots, minimal space between panels spar(top=1) # single plot, leave room for title </highlight> Under Sweave you might invoke =spar= right after <<fig=T>>=. If not using Sweave, =spar= might be called right after =postscript= or =pdf=. ---++++ Customizing Lattice Axis Spacing Like the =mgp= =par= element in base graphics, you can set the spacing between tick marks and the axis numbers using the following model: <highlight> xyplot(y ~ x, data=d, par.settings=list(axis.components=list(left=list(pad1=.3), bottom=list(pad1=.4)))) </highlight> #RGraphPanelNos ---+++ Adding panel numbers in margins of multi-panel graphs For submitting multi-panel graphs made with low-level S graphics for publication, journals often request that panel numbers be placed on each panel. The following setup provides good margin settings for this and shows how to add the panel descriptors outside the top left corner of each graph. <highlight> Panel <- function(panel) { par(xpd=NA) u <- par('usr') text(u[1]-(u[2]-u[1])*.125, u[4]+(u[4]-u[3])*.1, panel) par(xpd=FALSE) } par(mfrow=c(2,2), mar=c(3.5, 3.75, 1.75, .75)) plot( ) Panel('1A') hist( ) Panel('1B') plot( ) Panel('1C') hist( ) Panel('1D') </highlight> #EmbedFonts ---+++ Embedding fonts Certain journals require all fonts (including Helvetica) to be embedded when depositing =pdf= or =eps= files with them. According to Brian Ripley, the problem is "having a legitmately licensed version of those copyright fonts that allows you to send them (or subsetted versions)" to the journal. If the journal really feels that way, the journal should supply the fonts. "One possible way out is to use Nimbus Sans aka URW Helvetica, which =embedFonts= can embed." Here is an example. If using =postscript()= instead of =pdf()= be sure to specify a =paper= argument equal to ='special'=. <highlight> pdf('my.pdf', onefile=FALSE, pointsize=18, family="NimbusSan",height=6,width=8,paper="special") ... dev.off() embedFonts('my.pdf') </highlight> See http://colinm.org/tips/latex for some useful information. If the journal requires you to use Microsoft =.ttf= fonts, see http://corefonts.sourceforge.net (note that Microsoft forgot to copyright these fonts) or do =sudo apt-get install msttcorefonts=. This will provide the arial font to linux. According to !PLoS Guidelines one must generate =.afm= files before using them in R, along the lines of: <verbatim> ttf2afm /usr/share/fonts/msttcorefonts/arial.ttf > /foo/arial.afm ttf2afm /usr/share/fonts/msttcorefonts/ariali.ttf > /foo/ariali.afm ttf2afm /usr/share/fonts/msttcorefonts/arialbd.ttf > /foo/arialbd.afm ttf2afm /usr/share/fonts/msttcorefonts/arialbi.ttf > /foo/arialbi.afm </verbatim> and then one can use them in R's postscript() with the =family= argument on the lines of <highlight> postscript(file="try.ps", horizontal=F, onefile=F, width=4, height=4, family=c("/foo/arial.afm", "/foo/arialbd.afm", "/foo/ariali.afm", "/foo/arialbi.afm"), pointsize=12) </highlight> You will need the =texlive-font-utils= package on your system. =ttf= and =arial= information is thanks to Ted Harding, Deepayan Sarkar, Dirk Eddelbeutel. Sarkar also pointed out the following potentially simpler solution: <highlight> cairo_ps() par(family = "Arial") # or par(family = "Andale mono") to be really sure this works plot(1:10) dev.off() </highlight> He also said to see the 2006 article in Rnews referenced in the help file for =postscript()=. #TwoAxes ---+++ Making plots with Two Y-axes Someone posted this to S-news, with the following note. I would like to thank Naomi Robbins, Luciano Molinari, Samantha Choy, Melanie Cox, Z. Todd Taylor, Anne York and Ronald Fehd for their replies. I ended up using the function that Anne York sent me. I have modified it somewhat and will post the modifed version latter. Here is the original form: <highlight> Twoplots <- function(x1, y1, x2, y2, type = "l", xlim = NULL, ptitle = "Twoplots", xlab = "x", ylab1 = "y1", ylab2 = "y2", ...) { # Written by AE York Sept. 1996 # Plots y1 vs x1 and y2 vs x2 on the same plot # Labels for y1 are on the left and labels for y2 on the right oldpar <- par() par(mar = rep(6, 4)) # if(missing(xlim)) xlim <- range(pretty(range(c(x1, x2)))) plot(x1, y1, lty = 1, pch = 1, type = type, xlim = xlim, xlab = xlab, ylab = ylab1, ...) par(new = T) plot(x2, y2, lty = 2, pch = 16, type = type, axes = F, xlim = xlim, xlab = "", ylab = "") axis(side = 4) mtext(ylab2, side = 4, line = 2, outer = F) par(oldpar) title(ptitle) } </highlight> #CompressPdf ---+++ Compressing PDF Files PDF files produced by R are uncompressed. In may cases you can get an almost 10-fold reduction in file size by compressing the PDF graphics files. To to this, first make sure the =pdftk= package is installed in your system, then define the following =bash= script in your =~/bin= directory and name it =cmpdf=: <verbatim> #! /bin/bash for f in $@ do pdftk $f output /tmp/$f compress mv -f /tmp/$f . done </verbatim> To use it, here are some examples: <verbatim> cmpdf mygraph.pdf # compress one file cmpdf a.pdf b.pdf # compress two files cmpdf *.pdf # compress all .pdf files cmpdf a*.pdf # compress all .pdf files beginning with the letter a </verbatim> #SmallPostscript ---+++ Making Small Postscript Files Tim Hesterberg of Insightful Corp. in 2000 provided the following examples: <highlight> postscript(file="CLT2.ps", height=2.2, width=6.5, horizontal=F, onefile=F) par(mfrow=c(1,3), mar=c(2.1,2.1,4.1,2.1)) postscript(file="CLT3.ps", height=2.2*2, width=3, horizontal=F, onefile=F) par(mfrow=c(2,1), mar=c(2.1,2.1,1.1,0.1)) par(cex=.7, mex=.7) postscript(file="misc-three1.ps", height=2.2, width=6.5/3, horizontal=F, onefile=F) par(mar=c(2.1,2.1,1.1,0.1)) par(cex=.6, mex=.6) </highlight> Note that sometimes it is necessary to use two calls to =par()=, that combining the calls into a single call to =par()= fails. I believe this is because changing some graphical options changes others, so to get what you want for the latter they must be set in a later call to =par()=. #ModPstree ---+++ Modifying Postscript Files for Customizing Trees Samuel Buttrey (sebuttre@monterey.nps.navy.mil) wrote on 04May99 the following. Here is a simple Splus function that takes in a Postscript file written by post.tree, plus the (regression) tree object itself, and writes a new Postscript file in which the number under each leaf is the number of observations, not the deviance. If anyone is interested I have a couple of these manipulation-type functions for classification trees, too. Warning: they rely very heavily on the particular Postscript layout that I've observed Splus to use. If post.tree ever changes, I presume these functions will have to, too. I don't have a function that will add the standard error, but this technique can be adapted. <highlight> fix.ps.reg <- function(file.in, tree.in, file.out) { # # Fix.ps.reg: function to change the labels below the nodes of # a regression tree. # # Arguments: file.in: file with Postscript (output from post.tree) # tree.in: Splus tree # file.out: new Postscript file # # Read in the file.in file. Find the lines with "centershow" in # them; these come in pairs. Replace the first line of each pair # with a line of the form "(n) centershow" where n is the number # of items in the node. We get n from tree.in. # strs <- scan(file.in, what = "", sep = "\n", strip.white = T) rights <- regexpr(")", strs) lefts <- regexpr("(", strs) shows <- regexpr("centershow", strs) goods <- (1:length(strs))[shows > 0 & rights > 0 & lefts > 0] goods <- goods[-1] # Skip over title goods <- goods[seq(1, by = 2, length = length(goods)/2)] # # # Okay. Goods now holds the numbers of the relevant lines. # devs <- strs[goods] # first.occurrence <- function(str, char) { # # first.occurrence: function to find the number of the first occurrence # of character "char" in string "str" # # Arguments: str: string in which to find character # char: character to be found # Return value: number giving the position of the first occurrence # of "char" in "str." If char isn't found, return 0. # all.chars <- substring(str, 1:nchar(str), 1:nchar(str)) first <- (1:nchar(str))[all.chars == char][1] return(ifelse(length(first) == 0, 0, first)) } for(i in 1:length(devs)) { left.paren <- first.occurrence(devs[i], "(") right.paren <- first.occurrence(devs[i], ")") devs[i] <- paste("(", tree.in$frame[i, "n"], ") centershow") } strs[goods] <- devs if(!missing(file.out)) sink(file.out) cat(paste(strs, "\n")) if(!missing(file.out)) sink() invisible() } </highlight> #TrellislatticeStrips ---+++ Changing Trellis/Lattice Strip Characteristics You can turn off the shading in the strip labels as well as tell =lattice= to use black and white with <highlight> ltheme <- canonical.theme(color = FALSE) ltheme$strip.background$col <- "transparent" lattice.options(default.theme = ltheme) ## set as default </highlight> Here is another approach: <highlight> trellis.par.set(strip.background = list(col = 'transparent')) </highlight> or <highlight> strip <- function(...) strip.default(..., style=1) </highlight> Another function posted to S-news is: <highlight> "trellis.strip"<- function(b = 0, s = 0) { # Sets trellis parameters for strip colors # Default will eliminate shading from trellis strips # Use trellis.strip(5,12) for trellis defaults if(is.null(attr(get(".Device", where = 0), "trellis.settings"))) stop( "Current device is not a trellis device") s.b <- trellis.par.get("strip.background") s.b$col[1] <- b trellis.par.set("strip.background", s.b) s.s <- trellis.par.get("strip.shingle") s.s$col[1] <- s trellis.par.set("strip.shingle", s.s) } </highlight> Here's some other postings: <highlight> strip.back<- trellis.par.get("strip.background") strip.back$col<-rep(0,7) trellis.par.set("strip.background",strip.back) remove.shading <- function() { # Removes shading on shingles above Trellis plots strip.background <- trellis.par.get("strip.background") strip.background$col <- 0 trellis.par.set("strip.background", strip.background) strip.shingle <- trellis.par.get("strip.shingle") strip.shingle$col <- 0 trellis.par.set("strip.shingle", strip.shingle) } stripplot(Sut ~ lpelong | Knottype, jitter=T, strip=remove.shading(), par.strip.text = list(cex=1.2), scale = list(x=list(cex=1.2), y=list(cex=1.4)), xlab=list("Loop elongation (mm)", cex=1.6) ) </highlight> #ExportGraphOffice ---+++ More Hints About Exporting R Graphics to Office To make a high resolution graph in R that can be pasted into word, you can use the png function. If you make it a large size with high resolution, if it is resized, it will still have good quality. <highlight> png("name.png", pointsize = 10, width = 6, height = 6, units = "in", res = 1600) ... dev.off() </highlight> Sometimes it's simplest just to create a high enough resolution =png= file once you've created a =pdf= file in R. To easily control the resolution of the resulting =png= file and to scale text accordingly, use the =ImageMagick= =convert= command, e.g. =convert -density 300x300 myplot.pdf myplot.png= . Another =ImageMagick= command that has worked well is =convert -verbose -density 150 -trim my.pdf -quality 100 /tmp/my.png= . Note that the output file =my.png= is put in a different directory than the one holding =my.pdf= to keep !LaTeX from being confused with two graphics files with the same base name. ----- * [[http://www.stat.auckland.ac.nz/~paul/R/CM/CMR.html Using computer modern fonts in R]]
E
dit
|
A
ttach
|
P
rint version
|
H
istory
: r22
<
r21
<
r20
<
r19
|
B
acklinks
|
V
iew topic
|
Edit
w
iki text
|
M
ore topic actions
Topic revision: r22 - 07 Apr 2012,
FrankHarrell
Main
Department Home Page
Biostatistics Graduate Program
Vanderbilt University Medical Center
Main Web
Main Web Home
Search
Recent Changes
Changes
Topic list
Biostatistics Webs
Archive
Main
Sandbox
System
Register
|
Log In
Copyright © 2013-2022 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Vanderbilt Biostatistics Wiki?
Send feedback