4

I would like to display the percentage figures in the stacked bar. However, one group has a really low percentage. Two values are overlapping each other. I change to 'postion='identity'. It still wont work.....any thoughts?

x4.can.m <- structure(list(canopy = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("0%", "1 to 84%", 
"85% +"), class = "factor"), YearQuarter = structure(c(1L, 1L, 
1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L), .Label = c("2011-09-01", 
"2011-12-01", "2012-03-01", "2012-06-01", "2012-09-01"), class = "factor"), 
    value = c(0.51, 0.01, 0.48, 0.52, 0.01, 0.47, 0.53, 0.01, 
    0.47, 0.57, 0.01, 0.41, 0.61, 0.01, 0.38)), .Names = c("canopy", 
"YearQuarter", "value"), row.names = c(NA, -15L), class = "data.frame")


x4.can.bar <- ggplot(data=x4.can.m, aes(x=factor(YearQuarter), y=value,fill=canopy)) + geom_bar(stat="identity",position = "stack",ymax=100)

x4.can.bar+scale_y_continuous(formatter='percent')+
 labs(y="Percentage",x="Year Quarter") + 
 geom_text(aes(label =paste(round(value*100,0),"%",sep="")),size = 3, hjust = 0.5, vjust = 4,position ="identity")
mnel
  • 113,303
  • 27
  • 265
  • 254
Luo Lei
  • 649
  • 2
  • 9
  • 19

2 Answers2

11

You need to specify reasonable values for the placement of the labels - if you do this outside the ggplot call, it will be far easier than trying to do so within the call.

You can do this by taking the midpoint of each stacked component.

Using plyr and ddply this is a simple as taking the cumulative sum and subtracting half the current value within each YearQuarter

library(plyr)
x4.can.m <- ddply(x4.can.m, .(YearQuarter), mutate, csum = cumsum(value)-value/2)

x4.can.bar <- ggplot(data=x4.can.m, aes(x=factor(YearQuarter), y=value,fill=canopy)) +  
 geom_bar(stat="identity",position = "stack",ymax=100)

x4.can.bar + 
 scale_y_continuous(expand = c(0,0), labels = percent) +
 labs(y="Percentage",x="Year Quarter")+
 geom_text(aes(y = csum,label =paste(round(value*100,0),"%",sep="")),
           size = 3, hjust = 1, vjust = 0)

Note that I am using ggplot2_0.9.2.1, so formatter is no longer a valid argument to scale_y_continuous, replaced with label = percent. See this question and related links

enter image description here

Community
  • 1
  • 1
mnel
  • 113,303
  • 27
  • 265
  • 254
  • @mnel, thanks. what's the easiest to way to upgrade to ggplot2_0.9.2.1. I am using R_2.15.1 still..... – Luo Lei Nov 27 '12 at 03:50
  • in a new R session run `install.packages('ggplot2')` – mnel Nov 27 '12 at 03:51
  • did melt() funciton disappear in R_2.15.0.2? – Luo Lei Nov 28 '12 at 01:41
  • No. `ggplot2` used to load `reshape2` onto the search path, the newer versions `import` `reshape2` so the functions are available for `ggplot2`. run `library(reshape2)` to load explicitly. – mnel Nov 28 '12 at 01:44
8

one solution is to change the stack bar to a dodge one

x4.can.bar <- ggplot(data=x4.can.m, aes(x=factor(YearQuarter), y=value,fill=canopy)) + 
                    geom_bar(stat="identity",position = "dodge",ymax=100) +
             geom_text(aes(label =paste(round(value*100,0),"%",sep=""),ymax=0), 
                       position=position_dodge(width=0.9), vjust=-0.25)
x4.can.bar

enter image description here

agstudy
  • 119,832
  • 17
  • 199
  • 261