Re: [R] Plotting labeled impulses: label collision

2008-01-09 Thread Johannes Graumann
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(1,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




signature.asc
Description: This is a digitally signed message part.
__
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.


Re: [R] Plotting labeled impulses: label collision

2008-01-05 Thread Jim Lemon
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(1,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.