[R] cex

Ross Ihaka ihaka at stat.auckland.ac.nz
Tue Feb 2 00:57:41 CET 1999

Simon  Bond writes:
 > Hi,
 > I was hoping someone could help me with this problem. I’m trying to produce
 > what can be referred to as L’Abbe plots, where a character (my preference
 > is a circle) is plotted at some specified co-ordinates and the size of the
 > character is proportional to a weighting variable. I’ve tried this
 > 	plot  (x, y, type="n")
 > 	size <- weight/mean(weight)
 > 	for ( i in 1:length(x) ) { points (x[i],y[i], pch=1, cex= 2* size[i])}
 > The problem is that there seems to be both an upper and lower bound for the
 > effect that the option cex has, about 0.5 and 2, so you get all the points
 > below or above a critical weight the same size, thus ruining the desired
 > effect. 
 > Is there some option to remove these bounds , the upper bound in
 > particular, or, is there a command to draw a circle of specified centre and
 > radius? Indeed, any other working alternative you can come up with.
 > I ought to mention that I’ve only recently set up R, but was fairly
 > competent with S-plus the last time I had access to it.

The problem is that plotting symbols are restricted to sizes which
match the available fonts on the device.  You get slightly more
consistent appearance that way.

Completely flexible sizing for symbols is obviously pretty important
too and I will put it on my list.  In the meantime, here is a quick
function which you can use to draw circles.

    circles <- function(x, y, radius, col=NA, border=par("fg"))
        nmax <- max(length(x), length(y))
        if (length(x) < nmax) x <- rep(x, length=nmax)
        if (length(y) < nmax) y <- rep(y, length=nmax)
        if (length(col) < nmax) col <- rep(col, length=nmax)
        if (length(border) < nmax) border <- rep(border, length=nmax)
        if (length(radius) < nmax) radius <- rep(radius, length=nmax)
        theta <- 2* pi * seq(0, 355, by=5) / 360
        ct <- cos(theta)
        st <- sin(theta)
        for(i in 1:nmax)
            polygon(x[i] + ct * xinch(radius[i]), y[i] + st * yinch(radius[i]),
                col=col[i], border=border[i])

"x" and "y" give the coordinates of the centers of the circles,
"radius" gives the circle radius in inches, "col" gives a vector of
colors to fill the circles and "border" gives a vector of colors to
draw the borders.  Note that "col" and "border can both be set to NA.
Doing this respectively disables filling and border drawing.
(Shorter vectors are recycled according to the usual rule).

There are couple of problems to note.  If you resize a window, the
circles are resized (becoming ellipses).  If you use to dev.print() to
get hardcopy, you will probably end up with ellipses (unless you are
careful about preserving plot aspect ratios).  To get hardcopy start
the printing device by hand and redraw the plot.

A "real" implementation of circles (and similar shapes) should not
suffer from these problems.  I think I know how to do it, but don't
hold your breath.
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