Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R barplot axis scaling

I want to plot a barplot of some data with some x-axis labels but so far I just keep running into the same problem, as the axis scaling is completely off limits and therefore my labels are wrongly positioned below the bars. The most simple example I can think of:

x = c(1:81)
barplot(x)
axis(side=1,at=c(0,20,40,60,80),labels=c(20,40,60,80,100))

As you can see, the x-axis does not stretch along the whole plot but stops somewhere in between. It seems to me as if the problem is quite simple, but I somehow I am not able to fix it and I could not find any solution so far :(

Any help is greatly appreciated.

like image 555
bontus Avatar asked Nov 27 '11 13:11

bontus


2 Answers

The problem is that barplot is really designed for plotting categorical, not numeric data, and as such it pretty much does its own thing in terms of setting up the horizontal axis scale. The main way to get around this is to recover the actual x-positions of the bar midpoints by saving the results of barplot to a variable, but as you can see below I haven't come up with an elegant way of doing what you want in base graphics. Maybe someone else can do better.

x = c(1:81)
b <- barplot(x)
## axis(side=1,at=c(0,20,40,60,80),labels=c(20,40,60,80,100))
head(b)

You can see here that the actual midpoint locations are 0.7, 1.9, 3.1, ... -- not 1, 2, 3 ...

This is pretty quick, if you don't want to extend the axis from 0 to 100:

b <- barplot(x)
axis(side=1,at=b[c(20,40,60,80)],labels=seq(20,80,by=20))

This is my best shot at doing it in base graphics:

b <- barplot(x,xlim=c(0,120))
bdiff <- diff(b)[1]
axis(side=1,at=c(b[1]-bdiff,b[c(20,40,60,80)],b[81]+19*bdiff),
              labels=seq(0,100,by=20))

You can try this, but the bars aren't as pretty:

plot(x,type="h",lwd=4,col="gray",xlim=c(0,100))

Or in ggplot:

library(ggplot2)
d <- data.frame(x=1:81)
ggplot(d,aes(x=x,y=x))+geom_bar(stat="identity",fill="lightblue",
                   colour="gray")+xlim(c(0,100))

Most statistical graphics nerds will tell you that graphing quantitative (x,y) data is better done with points or lines rather than bars (non-data-ink, Tufte, blah blah blah :-) )

like image 166
Ben Bolker Avatar answered Nov 03 '22 08:11

Ben Bolker


Not sure exactly what you wnat, but If it is to have the labels running from one end to the other evenly places (but not necessarily accurately), then:

x = c(1:81)
bp <- barplot(x)
axis(side=1,at=bp[1+c(0,20,40,60,80)],labels=c(20,40,60,80,100))

The puzzle for me was why you wanted to label "20" at 0. But this is one way to do it.

like image 26
IRTFM Avatar answered Nov 03 '22 08:11

IRTFM