[R] Barplot2 using for loop, how to adjust margins?

Marc Schwartz marc_schwartz at comcast.net
Thu Aug 30 20:51:52 CEST 2007


On Thu, 2007-08-30 at 20:13 +0300, Lauri Nikkinen wrote:
> Hi R-users,
> 
> I inted to make multiple plots using for loop. The question is how can
> I adjust the left hand side margin of the plot according to the
> names.arg argument in barplot2. In every plot I have different
> annotations in the y axis and they vary in length. Now when I have
> fixed margins
> 
> opar <- par(mar=c(3,15,0,2)...
> 
> I get the same margins in all of the plots. That leaves lots of white
> space in plots where the annotations are short.
> 
> Here is the code I'm using:
> 
> library(gplots)
> opar <- par(mar=c(3,15,0,2), bg="white", cex=1, oma = c(0, 0, 2, 0),
> mgp=c(3,0.5,0))
> for (i in names(spl)) {
>           .order <- order(spl[[i]]$x)
>           barplot2(spl[[i]]$x[.order],
>                   names.arg=as.character(spl[[i]]$os[.order]),
>                   horiz=TRUE,
>                   las=1,
>                   cex.names=0.7,
>                   cex.main=0.9,
>                   cex.axis=0.7,
>                   xlim=c(0, max(spl[[i]]$x)+10),
>                   col=as.character(spl[[i]][1,7]),
>                   plot.grid = TRUE,
>                   )
>           box()
>           mtext(paste(paste(as.character(spl[[i]][1,2]), ":", sep=""),
> "texthere", "(texthere)", as.character(spl[[i]][1,3])), outer=T, line
> = 0.5, cex=1.1)
>           mtext("texthere", side=1, line=1.5, adj=0.5)
>           dev.copy(png, filename=paste(i, ".png", sep=""), height=400,
> width=480)
>           dev.off()
> }
> 
> Thanks in advance
> Lauri

Lauri,

Without your actual data or a sample, it is difficult to give you a
specific solution.

However, a general approach would be to ascertain the longest label that
you would be using for each plot and then adjust par("mar") accordingly
WITHIN the loop before calling barplot2().

You can use the following to get the longest value in a vector:

Vec <- c("Male", "Female")

> Vec[which.max(nchar(Vec))]
[1] "Female"


Presumably in your case, you would replace 'Vec' with
'as.character(spl[[i]]$os[.order])'

Once you know which value is the longest, you could also use strwidth()
to get a sense for the amount of space the label would take and further
fine tune par("mar"). This step may be optional depending your specific
needs.

See ?nchar, ?which.max and ?strwidth for more information.

HTH,

Marc Schwartz



More information about the R-help mailing list