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 ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.