dayne
dayne

Reputation: 7784

Custom axis with lines to labels

I am not sure how to phrase this question, but I am trying to add labels with lines to the corresponding point on a basic scatterplot. So far I have the following:

example <- data.frame(name=paste("label_",1:200,sep=""),plot=rep(FALSE,200),rank=c(1:200),score=exp(seq(6,0,length.out=200)))
example$plot[c(1:3,7,8,35,37,150:155,183)] <- TRUE

plot(x=example$score,y=example$rank,ylim=rev(range(c(1:nrow(example)))),axes=FALSE,ylab="",xlab="Score",frame.plot=FALSE)
axis(side=1,labels=TRUE)
axis(side=2,labels=example$name[which(example$plot==TRUE)],at=example$rank[which(example$plot==TRUE)],las=1,tick=FALSE)
points(x=example$score[which(example$plot==TRUE)],y=example$rank[which(example$plot==TRUE)],col="Red",cex=1.5,pch=16)

The code gives the following plot:

What I currently have.

This would work well for my purposes, except the labels overlap really badly. I am looking for a general method to make a graph like the following:

What I would like to have.

The code lies within a function, so it needs to work for any variation on the general dataset. I am looking into the code behind safeplot in the safe package, but so far I cannot replicate what they did to solve a similar problem.

I have now also tried using the linestack() function in the vegan package.

par(mar=c(5,10,4,2))
plot(x=example$score,y=example$rank,ylim=rev(range(c(1:nrow(example)))),axes=FALSE,ylab="",xlab="Score",frame.plot=FALSE)
axis(side=1,labels=TRUE)
points(x=example$score[which(example$plot==TRUE)],y=example$rank[which(example$plot==TRUE)],col="Red",cex=1.5,pch=16)
linestack(x=example$rank[which(example$plot==TRUE)],labels=example$name[which(example$plot==TRUE)],add=TRUE,side="left",air=1.1,at=0,hoff=2)

However, linestack() just gave me the following:

enter image description here

I tried varying all the parameters and could not get the labels to separate.

Upvotes: 4

Views: 461

Answers (2)

Greg Snow
Greg Snow

Reputation: 49650

Look at the spread.labs function in the TeachingDemos package and the spread.labels function in the plotrix package for ways of choosing where to position the labels.

Setting par(xpd=NA) will let you use text,lines,segments and other functions to draw outside of the plotting area.

Also the function grconvertX may be helpful in finding the horizontal position for labels and line segments.

Upvotes: 1

Gavin Simpson
Gavin Simpson

Reputation: 174853

There are several issues here, notably that normally you can't draw outside the plotting region as clipping obscures anything outside the limits (i.e. in the margins). You also need to leave a lot of space in that margin to accommodate the labels and the lines.

Whilst this is a bigger job than something I can get into now on SO, I can suggest that you look at the linestack() function in the vegan package and how it is used in the vegan:::plot.prc() method.

I recently used the `linestack() function to do something very similar to what you describe to improve some plots from the glmnet package. If you need more help comment back and I'll see about hacking an example together.

Upvotes: 2

Related Questions