Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"axis" won't add x-axis to boxplot

I'm trying to make a boxplot with custom axis labels, but I can't seem to add an x-axis to the plot.

For example:

test <- data.frame(year=as.integer(rep(1963:2014, each=10)),
       response=rnorm(520))
boxplot(response~year, data=test, ylim=c(-3,3), xlab="", ylab="", 
    range=0, xaxt="n", yaxt="n")
responselabs <- as.numeric(c(-3:3, by=1))
yearlabs <- as.integer(seq(1965,2015, by=5))
axis(2, at=responselabs, tck=0.03, las=1)
axis(1, at=yearlabs, tck=0.03)

returns the boxplot, but no x-axis labels:

boxplot with no x axis

Trying to hack it the other way by making an empty plot first, I can get the axes, but it won't add the boxplot:

plot(NA, ylim=c(-3, 3), xlim=c(1962, 2015), xaxt="n", yaxt="n", ylab="", xlab="")
axis(2, at=responselabs, tck=0.03, las=1)
axis(1, at=yearlabs, tck=0.03)
boxplot(response~year, data=test, ylim=c(-3,3), xlab="", ylab="", 
    range=0, xaxt="n", yaxt="n", add=T)

empty plot

What's going on here?

like image 561
Patrick Avatar asked Mar 03 '26 16:03

Patrick


2 Answers

I think what's happening is that boxplot converts year to a factor. We can get around this by using the labels argument in axis:

boxplot(response~year, data=test, ylim=c(-3,3), xlab="", ylab="", 
    range=0, xaxt="n", yaxt="n")
responselabs <- as.numeric(c(-3:3, by=1))
yearlabs <- as.integer(seq(1965,2015, by=5))
axis(2, at=responselabs, tck=0.03, las=1)
axis(1, at = yearlabs - 1962, labels = yearlabs)

enter image description here

like image 142
bouncyball Avatar answered Mar 06 '26 06:03

bouncyball


Why not use ggplot2?

library(ggplot2)
p<-ggplot(test,aes(x=year,y=response,group=year))+
geom_boxplot()+
scale_x_continuous(breaks=round(seq(min(test$year),max(test$year),by=5),1))

enter image description here

If you want to be rounded to the nearest 5 then the code is fairly easy to adjust in the scale_x_continuous() argument.

p<-ggplot(test,aes(x=year,y=response,group=year))+
   geom_boxplot()+
   scale_x_continuous(breaks = round(seq(round(min(test$year)/5,0)*5,round(max(test$year)/5,0)*5, by = 5),1))

enter image description here

like image 22
Travis Gaddie Avatar answered Mar 06 '26 05:03

Travis Gaddie