5

Probably pretty simple but I am a newb to R (and to stack)...

Can't seem to get the car names to show on the x-axis of my barplot.

I tried pasting in the example given in the "How to display all x labels in R barplot?" Question but that didn't work

My code is below. Does that code work for anybody else?

#plot of efficiency of 4 cylinder cars
#get 4cylinder cars seperate
fourcyl <- subset(mtcars, cyl == "4")
#barplot in descending order... need to add in car names.
barplot(fourcyl$mpg[order(fourcyl$mpg, decreasing = TRUE)], 
        horiz=FALSE,
        ylab = "Miles per Gallon",
        main = "Efficiency for 4 cylinder vehicles",
        ylim = c(0,35))
Julian Tagell
  • 53
  • 1
  • 1
  • 5

1 Answers1

2

@Pascal's comment links to two possible solutions, but the bottom line is that you need to add the car names manually.

To know which car names to use takes a first step: if you look at mtcars, you'll see that they don't appear under a column header, meaning they are the row names. To get at them, simply:

carnames <- rownames(fourcyl)[ order(fourcyl$mpg, decreasing=TRUE) ]

From here, you need to know how and where to add them. Perhaps the first place many people look is to axis, where you'd do something like:

axis(side=1, at=1:length(carnames), labels=carnames)

But you'd be disappointed on at least two accounts: first, you don't see all of the names, since axis courteously ensures they don't overlap by omitting some; second, the ones that do show are not aligned properly under the corresponding vertical bar.

To fix the first, you can try rotating the text. You could use las (see help(par)) and do something like:

axis(side=1, at=1:length(carnames), labels=carnames, las=2)

But again you'll be a little disappointed in that many of the names will run over the default bottom margin (and disappear). You can fix with this a preceding par(mar=...) (again, see the help there and play with it some to find the right parameters), but there are solutions that provide slightly better methods (aesthetically), two of which are mentioned in @Pascal's link (really, go there).

The other problem -- where to put the labels -- is resolved by reading help(barplot) and noticing that the return value from barplot(...) is a matrix providing the mid-point of each of the bars. Odd, perhaps, but it is what it is (and it has a good reason, somewhere). So, capture this and you'll be nearly home-free:

bp <- barplot(fourcyl$mpg[order(fourcyl$mpg, decreasing = TRUE)], 
              horiz=FALSE, ylab = "Miles per Gallon",
              main = "Efficiency for 4 cylinder vehicles",
              ylim = c(0,35))

Now, to copy one of the link's suggestions, try:

text(x=bp[,1], y=-1, adj=c(1, 1), carnames, cex=0.8, srt=45, xpd=TRUE)

(No need for the axis command, just bp <- barplot(...), carnames <- ..., and text(...).)

r2evans
  • 141,215
  • 6
  • 77
  • 149
  • Many thanks for your thorough answer. It worked. Was struggling with that for most of the day. Your response is most appreciated. – Julian Tagell Aug 13 '15 at 05:24
  • Sometimes people prefer to have more control than `barplot` provides, so they need to revert to making the bars manually. I suggested (with more features) an answer to a different question here at [SO #30794373](http://stackoverflow.com/questions/30793211/align-barplot-with-boxplot-in-r/30794373#30794373) using `plot` and `rect`, if you're curious. – r2evans Aug 13 '15 at 05:28