[R] Changing a plot

Jim Lemon jim at bitwrit.com.au
Thu Sep 25 12:42:29 CEST 2008


R Help wrote:
> Hello list,
>
> I've been working on this problem for a while and I haven't been able
> to come up with a solution.
>
> I have a couple of functions that plot a bunch of data, then a single
> point on top of it.  What I want is to be able to change the plot of
> the point without replotting all the data.  Consider the following
> example:
>
> x = rnorm(100,1,0.5)
> y = rnorm(100,1,0.5)
> plot(x,y,pch=16)
> points(x[35],y[35],pch=19,col=6,cex=3)
>
> What I want to be able to do is to change the purple point to a
> different value without replotting everything.
>
> I know this seems like an odd suggestion, but it comes up a lot with
> the work I'm doing.  I've prepared a package on CRAN called
> ResearchMethods for a course I'm working on, and there are several
> functions in there who's GUIs could work better if I could figure this
> out.
>
> If anyone has any ideas, or needs some further explanation, feel free
> to contact me.
>   
Hi Sam,
An interesting question. Here's a way to erase a point while redrawing 
any points within a certain proportion of the plot extent. It wouldn't 
be hard to extend this to draw a new point somewhere else if you wanted 
it all in one function.

erase.point<-function(x,y,pch=1,col=par("fg"),cex=1,tol=0.02*cex,
 erase.index,erase.pch=1,erase.col=par("bg"),erase.cex=1) {
 
 # erase the point
 points(x[erase.index],y[erase.index],pch=pch,col=erase.col,cex=1.1*erase.cex)
 # repeat the point parameters so that they can be indexed
 if(length(pch) < length(x)) pch<-rep(pch,length.out=length(x))
 if(length(col) < length(x)) col<-rep(col,length.out=length(x))
 if(length(cex) < length(x)) cex<-rep(cex,length.out=length(x))
 # work out the x and y differences within which the remaining points
 # will be redrawn
 xylim<-par("usr")
 xtol<-diff(xylim[1:2])*tol
 ytol<-diff(xylim[3:4])*tol
 for(i in 1:length(x)) {
  if(i != erase.index) {
   # if this point is within the specified tolerance, redraw it
   if(abs(x[i]-x[erase.index]) < xtol && abs(y[i]-y[erase.index]) < ytol)
    points(x[i],y[i],pch=pch[i],col=col[i],cex=cex[i])
  }
 }
}

x = rnorm(100,1,0.5)
y = rnorm(100,1,0.5)
plot(x,y,pch=16)
points(x[35],y[35],pch=19,col=6,cex=3)
erase.point(x,y,pch=19,erase.index=35,erase.pch=19,erase.col="white",erase.cex=3)

Jim



More information about the R-help mailing list