[R] Automatic adjustment of axis ranges

Jim Lemon bitwrit at ozemail.com.au
Fri Jul 26 12:56:06 CEST 2002


Thanks to Professor Ripley's help, here is a function that will add one or 
more points to the last plot call. There are a few weaknesses that may 
attract the attention of more experienced R programmers.

1) You can't keep adding points. If you specify point(s) to add, then 
specify some more, you will get the original plot with the _second_ lot of 
points added. If I was a better programmer, I would call this a feature 
and bank the proceeds.

2) The sub-function append.to.call() is probably an unnecessary kludge. 
Well, my brain hurts enough from working out the regular expressions for 
replacing existing xlim= and ylim= values. 

3) I did it in Linux (RedHat v7.2, X-Windows, R-1.5.1). There are probably 
a few places where I have unwittingly used system-specific code. I only 
have R on Linux.

4) These assumptions may not be important, but I have assumed that every 
plot() call has balanced parentheses and ends with a right parenthesis. I 
have also assumed that xlim= and ylim= will have the form:

ylim=c(min,max)

A final hint - avoid programming in R late at night when you have been 
programming in Tcl - especially when using strsplit()!

Jim

append.to.call<-function(appendage,old.call) {
 old.call<-paste(unlist(strsplit(old.call,""))[1:nchar(old.call)-1],sep="",
  collapse="")
 return(paste(old.call,",",appendage,")",sep="",collapse=""))
}

add.new.points<-function(x,y,last.plot.call="plot",look.back=10,...) {
 if(!missing(x) && !missing(y)) {
  current.range<-par("usr")
  new.x.range<-range(x)
  new.y.range<-range(y)
  new.plot<-0
  if(new.x.range[1] < current.range[1]) {
   new.plot<-1
   current.range[1]<-new.x.range[1]
  }
  if(new.x.range[2] > current.range[2]) {
   new.plot<-1
   current.range[2]<-new.x.range[2]
  }
  if(new.y.range[1] < current.range[3]) {
   new.plot<-1
   current.range[3]<-new.y.range[1]
  }
  if(new.y.range[2] > current.range[4]) {
   new.plot<-1
   current.range[4]<-new.y.range[2]
  }
  if(new.plot) {
   # grab the call history
   savehistory("snapshot.hst")
   tail.call<-paste("tail -n",look.back,"snapshot.hst",collapse=" ")
   last.calls<-system(tail.call,T)
   system("rm snapshot.hst")
   begin<-look.back
   found<-0
   lpc.length<-nchar(last.plot.call)
   # this finds the last call line that matches the last plot call
   while(begin >= 1 && !found) {
    if(last.plot.call != substr(last.calls[begin],1,lpc.length))
     begin<-begin-1
    else found<-1
   }
   # check that the last plot call was matched
   if(found) {
    # modify the old call and execute it here
    # first check for continuation lines
    lcb.vec<-unlist(strsplit(last.calls[begin],""))
    n.left.paren<-length(grep("[(]",lcb.vec))
    n.right.paren<-length(grep("[)]",lcb.vec))
    end<-begin
    while(n.left.paren > n.right.paren && end <= look.back) {
     end<-end+1
     lce.vec<-unlist(strsplit(last.calls[end],""))
     n.left.paren<-n.left.paren+length(grep("[(]",lce.vec))
     n.right.paren<-n.right.paren+length(grep("[)]",lce.vec))
    }
    new.call<-paste(last.calls[begin:end],sep="",collapse="")
    new.xlim<-paste("xlim=c(",current.range[1],",",current.range[2],")",
     sep="",collapse="")
    new.ylim<-paste("ylim=c(",current.range[3],",",current.range[4],")",
     sep="",collapse="")
    if(length(grep("xlim=.*)",new.call))) {
     # replace the old xlim=
     new.call<-sub("xlim=[^)]*)",new.xlim,new.call)
    }
    else {
     # tack it on to the end of the call
     new.call<-append.to.call(new.xlim,new.call)
    }
    if(length(grep("ylim=.*)",new.call))) {
     # replace the old ylim=
     new.call<-sub("ylim=[^)]*)",new.ylim,new.call)
    }
    else {
     # tack it on to the end of the call
     new.call<-append.to.call(new.ylim,new.call)
    }
    print(new.call)
    eval(parse(text=new.call))
   }
   else cat("Can't find the last plot call!\n")
  }
  return(points(x,y,...))
 }
 else cat("Usage: add.new.points(x,y)\n")
}
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
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