Reputation: 7784
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:
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:
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:
I tried varying all the parameters and could not get the labels to separate.
Upvotes: 4
Views: 461
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
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