2

I want to plot stacked bar plot with ggplot2 and am having difficulty getting the colour mapping and stack order right. The following example has been developed from this SO answer to achieve a non-zero y-axis origin, but as you can see it creates other problems. The colours don't map properly and the plot order is wrong. Grateful for any pointers on the best way to handle this. The desired output should scale colours as per the factor levels for rating, with colours in the order specified.

require(ggplot2)
d = data.frame(grp = rep(c('A','B'), each = 4), 
               rating = rep(c('bad','poor','ok','good'), 2),
               value = c(15,45,35,5,5,15,55,30), stringsAsFactors = F)

if(require(reshape2)) reshape2::dcast(d, grp ~ rating) # show structure

d$rating = ordered(d$rating, levels=c('bad','poor','ok','good'))
d$grp = ordered(d$grp, levels=c('B','A'))

# split datsets so we can plot 'negative' bars
d1 = subset(d, rating %in% c('ok','good'))
d2 = subset(d, rating %in% c('poor','bad'))

ggplot() + 
  geom_bar(data = d1, aes(x=grp, y=value, fill=rating), stat='identity', position='stack') + 
  geom_bar(data = d2, aes(x=grp, y=-value, fill=rating), stat='identity', position='stack') + 
  scale_fill_manual(values=c('red','pink','lightgreen','green')) +
  geom_line(data=d1, aes(x=c(.5,2.5), y=c(0,0)), size=2, linetype='dashed') +
  coord_flip()

enter image description here

Community
  • 1
  • 1
geotheory
  • 22,624
  • 29
  • 119
  • 196

1 Answers1

2

Perhaps a bit of reordering and using limits() will help:

d2 <- d2[order(d2$rating, decreasing =T),]

ggplot() + 
     geom_bar(data = d1, aes(x=grp, y=value, fill=rating), stat='identity',
               position='stack') + 
     geom_bar(data = d2, aes(x=grp, y=-value, fill=rating), stat='identity', 
               position='stack') + 
     scale_fill_manual(values=c('red','pink','lightgreen','green'),
                       limits=c("bad","poor","ok","good"))+
     geom_line(data=d1, aes(x=c(.5,2.5), y=c(0,0)), size=2, linetype='dashed') +
     coord_flip()

enter image description here

For anyone who wishes to learn ggplot2, I strongly recommend getting the Winston Chang's R Graphics Cookbook.

Serban Tanasa
  • 3,592
  • 2
  • 23
  • 45
  • Many thanks Serban. So am I right to understand that ranking by factor levels isn't implemented for graphical sub-elements? Bit surprising that ggplot doesn't map colour to factor levels automatically. – geotheory Jan 20 '15 at 09:33
  • 1
    I see. Use reroder() or see answer here: http://stackoverflow.com/questions/17331892/order-and-color-of-bars-in-ggplot2-barplot?rq=1 – Serban Tanasa Jan 20 '15 at 12:07
  • Handy tip. Yes we clearly have working options which is good. – geotheory Jan 20 '15 at 12:13