[R] offset labeling boxplots
Paul Murrell
p.murrell at auckland.ac.nz
Wed Jun 12 03:25:45 CEST 2002
Hi
> often I plot boxplots with different number of boxes (up to 200 boxes).
> I'd like to give every box a readable label on the x-axis. Therefore, I
> decrease the fontsize of the names and plot them vertical.
> But if you zoom into the plot (pdf) you will find an offset between the
> tickmark and the label - the label is shifted to the right.
>
> If you vary the box.count in the following example (without changing
> the fontsize) you will find every time this right shifted labels.
> (Finaly, for large box.counts the label will be shifted to the next right
> label!)
>
> Question 1: How can I avoid the right shift of the x-axis label?
> Question 2: Is it possible to scale the fontsize depending of the box.count
> (So that I can read every single label)?
The problem here is with mtext(). A simpler demonstration of the
problem is as follows ...
plot(1:10)
abline(v=1:10, col="grey")
axis(3, at=1:10, las=3)
axis(3, pos=9, at=1:10, las=3, cex.axis=.5)
axis(3, pos=8, at=1:10, las=3, cex.axis=2)
... basically mtext() is using a hardcoded adjustment to position the
text in some cases. It looks ok for the default text size, but gets it
wrong if the text size is modified. (I will submit a bug report about
this problem).
The temporary hack solution requires using text() instead of mtext() to
draw the axis labels. Here's one way to do it ...
# Make sure that the text() output is not clipped
par(xpd=NA)
# Create the boxplot information
b <- boxplot(list(rnorm(10), rnorm(10), rnorm(10), rnorm(10),
rnorm(10), rnorm(10), rnorm(10),
rnorm(10),
rnorm(10), rnorm(10)),
plot=FALSE)
# Draw the boxplot
# We control the y-axis scale so that we have some hope of
# positioning the text() output later
bp <- bxp(b, ylim=c(-4, 4), axes=FALSE)
axis(2)
box()
# Draw the x-axis ticks
axis(1, at=bp, labels=FALSE)
# Draw the x-axis tick labels using trial-and-error to
# get the value -4.7
text(bp, -4.7, letters[1:10], srt=90, adj=c(1, .5), cex=.5)
.. The disadvantage is that it requires trial-and-error to position the
labels. This is maybe not too much pain for a one-off boxplot, but may
get tiresome if many boxplots are to be produced.
Another approach which is not dependent on the y-axis scale is a bit
more complicated, but for the brave of heart here goes ...
# First split the page into two figure regions
# The lower region is .5cm high for the axis we will draw
# plus .5in high for the axis labels -- change this second
# amount to allow for longer labels
layout(matrix(c(1, 2), ncol=1),
heights=c(1, lcm(.5 + 2.54/2)))
# Prepare to draw the main boxplot
# We make the bottom margin 0 so that the bottom of
# the boxplot is flush with the top of the axis we will draw
# We make the left and right margins something that we can
# reproduce when we come to drawing the axis
par(mai=c(0, 1, 1, .5))
# Create the boxplot information
b <- boxplot(list(rnorm(10), rnorm(10), rnorm(10), rnorm(10),
rnorm(10), rnorm(10), rnorm(10),
rnorm(10),
rnorm(10), rnorm(10)),
plot=FALSE)
# Draw the boxplot, but not any axes
bp <- bxp(b, axes=FALSE)
# Draw the default y axis
axis(2)
box()
# Save the axis scales -- we want the x-axis scale for later
savedusr <- par("usr")
# Prepare to draw the axis
# We make the top margin 0 so that the top of the axis
# will be flush with the bottom of the boxplot
# We replicate the left and right margins from the boxplot
# The bottom margin is .5in -- the amount of room we allowed
# for in the layout
# We set xpd=NA so that the text drawn for the axis tick
# labels will not get clipped
par(mai=c(.5, 1, 0, .5), xpd=NA)
# Start a new plot -- the text() function draws in the
# "data region" of a plot, so we will draw the axis as a
# complete plot
plot.new()
# Set up the scales on the new plot
# We replicate the x-axis scale from the boxplot
# The choice of y-axis scale is arbitrary
plot.window(savedusr[1:2], c(1, 10), xaxs="i", yaxs="i")
# Draw the axis ticks -- note that this axis is drawn at
# the very top of the new plot (pos=10)
axis(1, at=bp, pos=10, labels=FALSE)
# Draw the axis tick labels
text(bp, 1, letters[1:10], srt=90, adj=c(1, .5), cex=.5)
... anyway, that's a couple of ideas :)
Hope there's something useful in there somewhere.
Paul
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
More information about the R-help
mailing list