Dear R-users, As noted by Paul Murrell < p.murrell at auckland.ac.nz > there is errors in the code for polar plotting I send to R-help under the title "Polar plot, circular plot (angular data)" at Thu Oct 17 2002 - 12:18:20 CEST. Thanks! I have reorganized the code into a structure ('pp'). This allows plots to be modified to a greater extent by passing arguments by ... argument of the R graphics functions: lines(), polygon() and text(). However, the use of the 'pp' structure is quite different from the use of standard plotting functions of R. In order to modify plots the fields of the 'pp' object must be modified directly. Probably, it could benefit from furter restructuring. Again, thanks to Ross Ihaka at R-help (Mon May 28 2001) for some of the code used here. Best wishes, Karsten ### Examples ## data div<-50 pp$theta <- seq(0, 2 * pi, length = div + 1)[-(div+1)] pp$r<-1:div rm(div) ## Plotting # source("polar.plot.object.0.86.R") pp$default.plot() pp$standard.plot() pp$wind.plot() # will not execute unless pp$default() has been called (in this case by the proceeding plot-commands) pp$grid.circle.pos<-c(0,25,50) pp$wind.plot() # overlay polygons and lines pp$r <- rnorm(50,35) pp$default() pp$rupper<-50 pp$basis() pp$newplot() pp$plot.polygon(col="darkgreen", border="darkgreen") pp$r <- rnorm(50,15) pp$plot.polygon(col="white", border="white") pp$r <- rnorm(50,0) * 4 + 28 pp$plot.lines(lwd = 2, type="o", col="red") pp$plot.grid.labels() title(main="Overlay red points on white polygon on blue polygon") ############################# ### Fields of object "pp" ### ############################# pp$r <- NULL # (vector of) radial data. pp$theta<- NULL # (vector of) angular data (in radians). ## function "pp$default()" set values of several fields: pp$default <- function() { pp$theta.zero <<- 0 # origin of angular axis (as direction on the output plot). pp$theta.clw <<- FALSE # clockwise oritation of angular axis. pp$text.lab<<- expression(0, pi/2, pi, 3*pi/2) # default text for angular axis labels pp$num.lab <<- NULL # (pretty) numeric angular axis labels in interval [0;num.lab[. If num.lab is a vector longer than 1 these are used as labels except the last value. (default = NULL). pp$rlabel.axis <<- 0 # angular orientation of radial axis (tick marks and labels) on the output plot. # # pp$radial.axis.labels: _method_ (plotting of radial axis labels): # NULL: no radial labels. # 1: labels at pretty radial distances (default). # 2: exclude label at radial distace 0. # 3: exclude label at maximum radial distance. # 4: exclude radial labels at distance 0 and at maximum radial distance. pp$rupper <<- NULL # Upper value for radial axis. May be increased by the default use of pretty()-function for positioning of grid circles and radial axis labels. (default = NULL). pp$grid.circle.pos <<- NULL # radial axis position of grid circles as numeric vector of minimum length 2. Overrides the default positioning of grid circles and radial axis labels by pretty()-function. (default = NULL). pp$tlabel.offset<<-0.2 # radial offset for angular axis labels in fraction of maximum radial value. pp$dir<<-8 # number of radial grid lines. } ################################### ### object pp (version. 0.86) ### ################################### # dump(ls(), file = "polar.plot.object.0.86.R") "pp" <- structure(list(default = function () { pp$theta.zero <<- 0 pp$theta.clw <<- FALSE pp$text.lab <<- expression(0, pi/2, pi, 3 * pi/2) pp$num.lab <<- NULL pp$rlabel.axis <<- 0 pp$rupper <<- NULL pp$grid.circle.pos <<- NULL pp$tlabel.offset <<- 0.2 pp$dir <<- 8 }, default.plot = function () { pp$default() pp$basis() pp$newplot() pp$radial.grid() pp$inner.circular.grid() pp$outer.circular.grid() pp$radial.axis.labels() pp$angular.labels() pp$angular.tick.marks() pp$radial.tick.marks() pp$plot.lines() print("Made new default plot.") }, standard.plot = function () { lwd <- 1 pp$default() pp$basis() pp$newplot() pp$radial.grid(lty = 3, lwd = lwd) pp$inner.circular.grid(lty = 3, lwd = lwd) pp$outer.circular.grid(lwd = lwd) pp$radial.axis.labels(pos = 3) pp$angular.labels(cex = 1.5) pp$angular.tick.marks(lwd = lwd) pp$radial.tick.marks(lwd = lwd, len = 0.03) pp$plot.lines(t = "p", pch = 21, lwd = lwd) print("Made new standard plot.") }, wind.plot = function () { lwd <- 2 pp$theta.zero <<- pi/2 pp$theta.clw <<- TRUE pp$num.lab <<- 360 pp$dir <<- 12 pp$basis() pp$newplot() pp$radial.grid(lty = 3, lwd = 1) pp$inner.circular.grid(lty = 3, lwd = 1) pp$outer.circular.grid(lwd = lwd) pp$radial.axis.labels(pos = 3, method = 2, cex = 1.5) pp$angular.labels(cex = 1.8) pp$angular.tick.marks(lwd = lwd) pp$radial.tick.marks(lwd = lwd, len = 0.03) pp$plot.lines(t = "l", pch = 21, lwd = lwd + 1) cat("Made new wind plot.\nr-range: ", range(pp$r)) }, plot.grid.labels = function () { pp$radial.grid() pp$inner.circular.grid() pp$outer.circular.grid() pp$radial.axis.labels() pp$angular.labels() pp$angular.tick.marks() pp$radial.tick.marks() print("Made my grid & labels (pp$plot.grid.labels).") }, fit.rad = function (x, twop = 2 * pi) { for (i in 1:length(x)) { while (x[i] < 0) x[i] <- x[i] + twop while (x[i] >= twop) x[i] <- x[i] - twop } return(x) }, fit.rad2 = function (th) pp$fit.rad(pp$theta.zero + (!pp$theta.clw) * th - (pp$theta.clw) * th), cartesian = function (r, th) { return(cbind(r * cos(th), r * sin(th))) }, basis = function () { if (is.null(pp$rupper)) pp$rpretty <<- pretty(0:ceiling(max(pp$r))) if (is.numeric(pp$rupper)) pp$rpretty <<- pretty(0:pp$rupper) if (is.numeric(pp$grid.circle.pos) & length(pp$grid.circle.pos) > 1) pp$rpretty <<- pp$grid.circle.pos pp$lab.dist <<- max(pp$rpretty) if (!is.null(pp$text.lab) || is.numeric(pp$num.lab)) { pp$lab.dist <<- max(pp$rpretty) * (1 + pp$tlabel.offset) } pp$rDir <<- seq(0, 2 * pi, length = pp$dir + 1)[-(pp$dir + 1)] print("pp$basis") }, newplot = function () { plot.new() ps <- max(pp$lab.dist, max(pp$rpretty)) plot.window(xlim = c(-ps, ps), ylim = c(-ps, ps), asp = 1) }, radial.grid = function (...) { if (pp$dir > 0) segments(0, 0, max(pp$rpretty) * cos(pp$rDir), max(pp$rpretty) * sin(pp$rDir), ...) }, inner.circular.grid = function (...) { grid <- seq(0, 2 * pi, length = 360/4 + 1) for (rad in pp$rpretty) { if (rad > 0 & rad < max(pp$rpretty)) lines(pp$cartesian(rad, grid), ...) } }, outer.circular.grid = function (...) { grid <- seq(0, 2 * pi, length = 360/4 + 1) lines(pp$cartesian(max(pp$rpretty), grid), ...) }, radial.axis.labels = function (method = 1, ...) { if (!is.null(method)) { if (method == 1) radLabels <- 1:length(pp$rpretty) if (method == 2) radLabels <- 2:length(pp$rpretty) if (method == 3) radLabels <- 1:(length(pp$rpretty) - 1) if (method == 4) { if (length(pp$rpretty) > 2) radLabels <- 2:(length(pp$rpretty) - 1) else radLabels <- NULL } if (!is.null(radLabels)) { text(pp$cartesian(pp$rpretty[radLabels], pp$rlabel.axis), labels = pp$rpretty[radLabels], ...) } } }, radial.tick.marks = function (len = 0.02, ...) { fpos <- pp$cartesian(pp$rpretty, pp$rlabel.axis) if (len != 0) { tick <- max(pp$rpretty) * pp$cartesian(len, pp$rlabel.axis + pi/2) segments(fpos[, 1], fpos[, 2], fpos[, 1] + tick[1], fpos[, 2] + tick[2], ...) } }, angular.labels = function (...) { labDir <- NULL t.lab <- NULL if (!is.null(pp$text.lab)) { t.lab <- pp$text.lab labDir <- seq(0, 2 * pi, length = length(t.lab) + 1)[-(length(t.lab) + 1)] } if (is.numeric(pp$num.lab)) { if (length(pp$num.lab) == 1 && pp$num.lab%%1 == 0) { labDir <- seq(0, 2 * pi, length = pp$dir + 1)[-(pp$dir + 1)] t.lab <- labDir/(2 * pi) * pp$num.lab } if (length(pp$num.lab) == 1 && pp$num.lab%%1 != 0) { t.lab <- pretty(0:(1 + pp$num.lab%/%1)) while (max(t.lab) > pp$num.lab) { t.lab <- t.lab[-length(t.lab)] } labDir <- 2 * pi * t.lab/pp$num.lab } if (length(pp$num.lab) > 1 && pp$num.lab >= 0) { labDir <- 2 * pi * pp$num.lab/pp$num.lab[length(pp$num.lab)] t.lab <- pp$num.lab[-length(pp$num.lab)] } } pp$labDir2 <<- pp$fit.rad2(labDir) if (!is.null(pp$text.lab) || is.numeric(pp$num.lab)) text(pp$cartesian(pp$lab.dist, pp$fit.rad2(labDir)), labels = t.lab, ...) else return(NULL) }, angular.tick.marks = function (len = 0.05, ...) { if (len != 0) { if (!is.null(pp$text.lab) || is.numeric(pp$num.lab)) dd <- pp$labDir2 else dd <- pp$rDir fpos <- pp$cartesian(max(pp$rpretty), dd) spos <- pp$cartesian((1 + len) * max(pp$rpretty), dd) segments(fpos[, 1], fpos[, 2], spos[, 1], spos[, 2], ...) } else return(NULL) }, plot.lines = function (...) points(pp$cartesian(pp$r, pp$fit.rad2(pp$theta)), ...), plot.polygon = function (...) polygon(pp$cartesian(pp$r, pp$fit.rad2(pp$theta)), ...)), .Names = c("default", "default.plot", "standard.plot", "wind.plot", "plot.grid.labels", "fit.rad", "fit.rad2", "cartesian", "basis", "newplot", "radial.grid", "inner.circular.grid", "outer.circular.grid", "radial.axis.labels", "radial.tick.marks", "angular.labels", "angular.tick.marks", "plot.lines", "plot.polygon")) -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- 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 _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._