4

I'm trying to do a simple plot using ggplot2:

library(ggplot2)

ggplot(diamonds, aes(x = cut, y = depth)) + 
  geom_bar(stat = "identity", color = "blue") +
  facet_wrap(~ color) +
  geom_text(aes(x = cut, y = depth, label = cut, vjust = 0))

ggplot2 plot

How can I annotate this plot so that I get annotations above bars? Now geom_text puts labels at the bottom of the bars, but I want them above these bars.

jrara
  • 16,239
  • 33
  • 89
  • 120
  • possible duplicate of http://stackoverflow.com/questions/10112587/re-alignment-of-numbers-on-the-individual-bars-with-ggplot2 – Ananta Nov 26 '13 at 19:48
  • @jrara if i knew this to be the final version, I would export the plot and annotate in a program like publisher. – user1738753 Nov 26 '13 at 19:58

1 Answers1

8

You can use stat_summary() to calculate position of y values as sum of depth and use geom="text" to add labels. The sum is used because your bars shows the sum of depth values for each cut value.

As suggest by @joran it is better to use stat_summary() instead of geom_bar() to show sums of y values because stat="identity" makes problems due to overplotting of bars and if there will be negative values then bar will start in negative part of plot and end in positive part - result will be not the actual sum of values.

ggplot(diamonds[1:100,], aes(x = cut, y = depth)) + 
  facet_wrap(~ color) + 
  stat_summary(fun.y = sum, geom="bar", fill = "blue", aes(label=cut, vjust = 0)) + 
  stat_summary(fun.y = sum, geom="text", aes(label=cut), vjust = 0) 

enter image description here

You can also precalculate sum of depth values and the you can use geom_bar() with stat="identity" and geom_text().

library(plyr)
diamonds2<-ddply(diamonds,.(cut,color),summarise,depth=sum(depth))

ggplot(diamonds2,aes(x=cut,y=depth))+
  geom_bar(stat="identity",fill="blue")+
  geom_text(aes(label=cut),vjust=0,angle=45,hjust=0)+
  facet_wrap(~color)
Didzis Elferts
  • 95,661
  • 14
  • 264
  • 201
  • I was confused at first because they are using `color` for the bars rather than `fill` and overplotting thousands of them because of `stat = "identity"`. They look solid, but I think that's an illusion because there are so many of them. Not sure if that was intended or not... – joran Nov 26 '13 at 19:58
  • Yes, if you subset first 100 rows of diamonds it can be seen that bars consist of many small parts with blue outline. I think OP should clarify this. – Didzis Elferts Nov 26 '13 at 20:03
  • Yes, that was unintentional, what is the correct way to create this graph? Maybe using stat_summary and geom_text? – jrara Nov 26 '13 at 20:07
  • @DidzisElferts sum of depth values – jrara Nov 26 '13 at 20:09
  • @DidzisElferts I suggest that you rotate the text. – agstudy Nov 26 '13 at 20:15
  • @jara ...but for the sum of the depth values, you can't use `stat = "identity"`. Either replace `geom_bar` with another `stat_summary` or aggregate the data ahead of time. You're still getting the sum sort of by accident due to overplotting. – joran Nov 26 '13 at 20:15
  • @joran yes, that is what I understood from you first comment. I'm trying to do that. – jrara Nov 26 '13 at 20:18
  • 2
    This seems to work: ggplot(diamonds, aes(x = cut, y = depth)) + facet_wrap(~ color) + stat_summary(fun.y = sum, geom="bar", fill = "blue", aes(label=cut, vjust = 0)) + stat_summary(fun.y = sum, geom="text", aes(label=cut), vjust = 0) – jrara Nov 26 '13 at 20:19
  • @joran Updated my answer - didn't notice the problem with stat="identity" because it gives the same result as with stat_summary(). – Didzis Elferts Nov 26 '13 at 20:24