20

Possible Duplicate:
add text to horizontal barplot in R, y-axis at different scale?
Annotate values above bars (ggplot faceted)

Using the code below, I'm hoping to display a number above each column that corresponds to the y-value for that column. In other words, I'm trying to get "QnWeight_initial" to display 593 at the top of the gray bar and so and...

My data:

data<-structure(list(V1 = structure(c(2L, 1L), .Label = c("593", "QnWeight_initial"
), class = "factor"), V2 = structure(c(2L, 1L), .Label = c("566", 
"Head"), class = "factor"), V3 = structure(c(2L, 1L), .Label = c("535", 
"V1"), class = "factor"), V4 = structure(c(2L, 1L), .Label = c("535", 
"V2"), class = "factor"), V5 = structure(c(2L, 1L), .Label = c("535", 
"V3"), class = "factor"), V6 = structure(c(2L, 1L), .Label = c("482", 
"Left_Leg"), class = "factor"), V7 = structure(c(2L, 1L), .Label = c("474", 
"Left_Antenna"), class = "factor"), V8 = structure(c(2L, 1L), .Label = c("237", 
"Qn_Weight_Loss"), class = "factor"), V9 = structure(c(2L, 1L
), .Label = c("230", "Days_wrkr_eclosion"), class = "factor"), 
    V10 = structure(c(2L, 1L), .Label = c("81", "Growth_all"), class = "factor"), 
    V11 = structure(c(2L, 1L), .Label = c("79", "Growth_1_2"), class = "factor"), 
    V12 = structure(c(2L, 1L), .Label = c("62", "Growth_1_3"), class = "factor"), 
    V13 = structure(c(2L, 1L), .Label = c("60", "Growth_2_3"), class = "factor"), 
    V14 = structure(c(2L, 1L), .Label = c("51", "Right_Antenna"
    ), class = "factor"), V15 = structure(c(2L, 1L), .Label = c("49", 
    "Left_Leg_Remeasure"), class = "factor"), V16 = structure(c(2L, 
    1L), .Label = c("49", "Right_Leg"), class = "factor"), V17 = structure(c(2L, 
    1L), .Label = c("47", "Head_Remeasure"), class = "factor"), 
    V18 = structure(c(2L, 1L), .Label = c("46", "Left_Antenna_Remeasure"
    ), class = "factor")), .Names = c("V1", "V2", "V3", "V4", 
"V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", 
"V15", "V16", "V17", "V18"), class = "data.frame", row.names = c(NA, 
-2L))
dat<-data.frame(fac=unlist(data[1,, drop=FALSE]), freqs=unlist(data[2,, drop=FALSE]))

The plot:

barplot( as.numeric( as.character(dat$freqs)) , main="Sample Sizes of Various Fitness Traits", xaxt='n', xlab='', width=0.85, ylab="Frequency")
par(mar=c(5,8,4,2))
labels<-unlist(data[1,,drop=FALSE])
text(1:18, par("usr")[3] -0.25, srt=90, adj=1,labels=labels,xpd=TRUE, cex=0.6)
Community
  • 1
  • 1
Atticus29
  • 4,190
  • 18
  • 47
  • 84
  • Surely this question has been asked before on SO. This one's close: http://stackoverflow.com/questions/4217207/add-text-to-horizontal-barplot-in-r-y-axis-at-different-scale – IRTFM Sep 18 '12 at 17:46
  • So, I looked at both of these, and I'm still having some difficulty. I tried with no success a few varieties like: text(x=as.character(dat$fac), y=as.numeric(as.character(dat$freqs)), labels=as.numeric(as.character(dat$freqs)), pos=3) – Atticus29 Sep 18 '12 at 19:06
  • Nothing is showing up at all. Does one instantiation of text() interfere with another? – Atticus29 Sep 18 '12 at 19:07
  • You were offering character values to the x (a coordinate) argument of text. That should have thrown an informative error message: `Warning message: In xy.coords(x, y, recycle = TRUE) : NAs introduced by coercion` – IRTFM Sep 18 '12 at 20:43

1 Answers1

65

You are having problems because dat$freqs is a factor, even though it's printed representation 'looks like' it's numeric. (It's almost always helpful to type str(foo) -- here str(dat) or str(dat$freqs) -- to have a look at the real structure of the data you're working with.)

In any case, once you've converted dat$freq to class "numeric", constructing the plot becomes straightforward:

## Make the frequencies numbers (rather than factors)
dat$freqs <- as.numeric(as.character(dat$freqs))
## Find a range of y's that'll leave sufficient space above the tallest bar
ylim <- c(0, 1.1*max(dat$freqs))
## Plot, and store x-coordinates of bars in xx
xx <- barplot(dat$freqs, xaxt = 'n', xlab = '', width = 0.85, ylim = ylim,
              main = "Sample Sizes of Various Fitness Traits", 
              ylab = "Frequency")
## Add text at top of bars
text(x = xx, y = dat$freqs, label = dat$freqs, pos = 3, cex = 0.8, col = "red")
## Add x-axis labels 
axis(1, at=xx, labels=dat$fac, tick=FALSE, las=2, line=-0.5, cex.axis=0.5)

enter image description here

Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • Thank you so much! I just learned quite a bit. Much appreciated. – Atticus29 Sep 18 '12 at 21:22
  • Hi Is there a way to add those numbers at the top of the bar but in parallel to y axis?? I tried las option on text but it did not work – user3138373 Apr 08 '16 at 20:22
  • @user3138373 You should be able to adapt one of the answers [here](http://stackoverflow.com/q/9981929/980833), probably the first one, which employs the `srt=` argument to `text()`. (You'll probably also need to mess around a bit with `offset=` and `pos=`, and set `xpd=TRUE` to get everything as you'd like it.) Cheers. – Josh O'Brien Apr 08 '16 at 20:46