3

I have the following plot

xleft<-c(1,2,3)
xright<-c(2,3,4)
ybottom<-c(1,2,3)
ytop<-c(2,3,4)

plot(c(1,4),c(1,4),type="n",main="title",xlab="site.x",ylab="ylab")
rect(xleft,ybottom,xright,ytop,col=c("blue","red","green"))

I would like to add rather long species names to both axes using these positions and labels

#Label position along  axes
x.label.position<-(xleft+xright)/2
y.label.position<-(ybottom+ytop)/2

#Labels
x.label<-c("Long species Name1","Long species Name2","Long species Name3")
x.label<-c("Long species Name4","Long species Name5","Long species Name5")

I would like to have the numerical axes, and axes titles left in place. I would also like to add a legend. So the final product would look something like this

enter image description here

What is the best way to go about this without having to clear the axes entirely using

par(xaxt = "n", yaxt = "n")

and adding text? Thanks for you advice.

Elizabeth
  • 6,391
  • 17
  • 62
  • 90

2 Answers2

5

I think the way to do it, and R FAQ 7.27 "How can I create rotated axis labels?" agrees, is to make space in the margin and then add the long label text.

 mx=12
 my=12
 par(mar = c(mx,my, 4, 2) + 0.1)
 plot(c(1,4),c(1,4),type="n",main="title",xlab="site.x",ylab="ylab")
 rect(xleft,ybottom,xright,ytop,col=c("blue","red","green"))
 text(par()$usr[1]-0.5,y.label.position,y.label,xpd=TRUE,adj=1)
 text(y=par()$usr[3]-0.5,x=x.label.position,x.label,xpd=TRUE,adj=1,srt=90)

You'll need to tweak mx and my for the length of your strings, and maybe also adjust the negative offsets in the text to stop it clashing with the labels. Note also the use of xpd=TRUE to stop drawing being clipped to the figure region. This is also the key to getting the legend in place:

 par(xpd=TRUE)
 legend(locator(1),legend=c("Species A","Species B","Species C"),
                             fill=c("blue", "red", "green"))

Then click where you want the legend - or replace locator(1) with list(x=-0.7,y=0.6)

You might find an easier approach with the ggplot package.

Spacedman
  • 92,590
  • 12
  • 140
  • 224
3

The answer from @Spacedman is great, but I just wanted to provide one update. His code (at least for me) plots the axis labels over the tick labels. To change where the labels are positioned, you need to look at par("mfg"). I think the following code does what you want, more or less:

par(mai=c(2.5, 2.25, 0.82, 0.42), mgp=c(9, 1, 0))
plot(c(1,4), c(1,4), xaxp=c(1,4,3), yaxp=c(1,4,3), type="n", 
  main="title", xlab="site.x", ylab="ylab")
rect(xleft, ybottom, xright, ytop, col=c("blue","red","green"))
axis(1, at=x.label.position, labels=x.label, las=2)
axis(2, at=y.label.position, labels=y.label, las=2)
par(xpd=TRUE)
legend(x=0.25, y=0.75, 
  legend=c("Text", "Text", "Text"),
  fill=c("blue", "red", "green"),
  title="Legend")

which produces the following plot:

enter image description here

As @Spacedman suggested, many of these alterations to the margins and axes are a bit more straight-forward in the ggplot2 package (once you get used to it...!).

smillig
  • 5,073
  • 6
  • 36
  • 46
  • I have played with ggplot2 a little bit in the past. What would be the general approach to this problem using ggplot2 do you think? – Elizabeth Aug 25 '12 at 11:57
  • For playing with the margin characteristics, I'd start by looking here: http://had.co.nz/ggplot2/docs/opts.html. For the plotted items, I'd look either start here: http://had.co.nz/ggplot2/docs/geom_rect.html or in this great answer to a question you asked here: http://stackoverflow.com/a/11954983/1088647. – smillig Aug 25 '12 at 12:13