[R] Plotting labeled impulses: label collision

Johannes Graumann johannes_graumann at web.de
Wed Jan 9 14:51:26 CET 2008


Jim,

I finally got back to this implementation of mine and dude, this function is 
amazing! Thank you so much!

Joh

On Saturday 05 January 2008 11:42:30 Jim Lemon wrote:
> Johannes Graumann wrote:
> > Dear all,
> >
> > As you can see from the attachment I'm using R to automatically annotate
> > peptide fragmentation mass spectra, which are represented by impulse
> > plots. I'd like to poll you on approaches of how to deal as generally as
> > possible with the two biggest annotation issues I run into:
> > 1) very close annotated masses (impulses) with similar y-axis dimensions
> > - resulting in overlapping labels
> > 2) very close annotated masses with widely differing y-axis dimensions -
> > resulting in the label for the smaller one partially overplotting the
> > impulse of the larger one
> >
> > Both cases can be seen in the appended png: for 1) see x of aprox. 1100,
> > for 2) x of aprox. 575
> >
> > If one does this manually one would write the labels somewhere where
> > there's plenty of space and then connect them with lines to the
> > impulses/masses they actually represent ...
> >
> > Any insight in how to make this pretty(er) automatically is highly
> > appreciated.
>
> Hi Joh,
> I would have loved to say that you could do this with the prettyR
> package, but I'll have to settle for plotrix. I realized that the
> spread.labels function would almost do what you want. With a minor
> change, as in the function below, I think it might get you there.
>
> spread.labels<-function (x,y,labels=NULL,spready=NA,
>   offsets,bg="white",border=FALSE,between=FALSE,
>   linecol=par("fg"),...) {
>
>   if(missing(x))
>    stop("Usage: spread.labels(x,y,labels,...)")
>   ny<-length(y)
>   if(between) {
>    if(length(linecol)==1) linecol<-rep(linecol,2)
>    nlabels<-length(labels)
>    newy<-seq(y[1],y[ny],length=nlabels)
>    # put the labels in the middle
>    labelx<-rep(mean(x),nlabels)
>    # do the left lines
>    segments(x[1:nlabels],y[1:nlabels],
>     labelx-strwidth(labels)/2,newy,col=linecol[1])
>    # now the right lines
>    segments(x[(nlabels+1):ny],y[(nlabels+1):ny],
>     labelx+strwidth(labels)/2,newy,col=linecol[2])
>    boxed.labels(labelx,newy,labels,bg=bg,
>     border=border,...)
>   }
>   else {
>    if(is.na(spready))
>     spready<-diff(range(x))<diff(range(y))
>    if(spready) {
>     sort.index<-sort.list(y)
>     x<-x[sort.index]
>     y<-y[sort.index]
>     newy<-seq(y[1],y[ny],length=length(labels))
>     if(missing(offsets)) {
>      offset<-diff(par("usr")[1:2])/4
>      offsets<-rep(c(offset, -offset), ny/2 + 1)[1:ny]
>     }
>     segments(x+offsets,newy,x,y)
>     boxed.labels(x+offsets,newy,labels[sort.index],
>      bg=bg,border=border,...)
>    }
>    else {
>     sort.index<-sort.list(x)
>     x<-x[sort.index]
>     y<-y[sort.index]
>     nx<-length(x)
>     newx <- seq(x[1],x[nx],length=length(labels))
>     if(missing(offsets)) {
>      offset<-diff(par("usr")[3:4])/4
>      offsets<-rep(c(offset,-offset),nx/2+1)[1:nx]
>     }
>     segments(newx,y+offsets,x,y)
>     boxed.labels(newx,y+offsets,labels[sort.index],
>      bg=bg,border=border,...)
>    }
>   }
> }
>
> Try calling it like this:
>
> spread.labels(x=<x values>,y=<y values>,
>   labels=<your labels>,spready=FALSE,
>   offsets=rep(10000,<number of labels>),
>   srt=90)
>
> By passing different offsets you may be able to fix some of the really
> bad crowding on the labels.
>
> Jim


-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: This is a digitally signed message part.
Url : https://stat.ethz.ch/pipermail/r-help/attachments/20080109/6c0a4824/attachment-0002.bin 


More information about the R-help mailing list