[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