Legend
Legend

Reputation: 116820

Getting a dodged bar chart?

I just came across this code that lets me plot multiple ordinates (I know it is a bad notion in the community but I need to do it to compare different metrics). Since this cannot be done inherently in ggplot2, I was wondering if I can adapt the following code to do what I need:

twoord.plot(2:10,seq(3,7,by=0.5)+rnorm(9),
  1:15,rev(60:74)+rnorm(15),xlab="Sequence",
  ylab="Ascending values",rylab="Descending values",
  main="Plot with two ordinates - bars on the left",
  type=c("bar","l"),lcol=3,rcol=4)

plots the following:

enter image description here

What I am looking for is to plot multiple bars side to side. I tried replacing type=c("bar", "l") with type=c("bar", "bar") but that gave me overlapping bars. The exact data I want to plot is the following:

Category    SubCat  Value
A           Cat1    0.1
B           Cat1    0.2
A           Cat2    0.3
B           Cat2    0.24
A           Cat3    13
B           Cat3    41
A           Cat4    60
B           Cat4    146

I want (A,B) under (Cat1,Cat2) to have the scale on the left, and (A,B) under (Cat3, Cat4) to have the scale on the right and all bars under A and B to be grouped together respectively. Can someone please tell me how to do this?

Upvotes: 3

Views: 857

Answers (1)

joran
joran

Reputation: 173577

The following is probably as close as you're going to get using ggplot2:

d <- read.table(textConnection("Category    SubCat  Value
A           Cat1    0.1
B           Cat1    0.2
A           Cat2    0.3
B           Cat2    0.24
A           Cat3    13
B           Cat3    41
A           Cat4    60
B           Cat4    146"),header = TRUE, sep="")

d$grp <- rep(c('Cat1 - Cat2','Cat3 - Cat4'), each = 4)
ggplot(d,aes(x = Category, y = Value)) + 
    facet_wrap(~grp, scales = "free_y") + 
    geom_bar(aes(fill = SubCat), position = "dodge")

enter image description here

This achieves a "dual y axis" by faceting and allowing ggplot2 to set the axes separately. I'm sure it's possible to get something closer to what you want using base graphics, but it will take some more thought.

EDIT

And here's a hack using the twoord.plot. Took quite a bit of fiddling, but I've never used that function, so there may be an easier way:

par(xaxt = "n") 
twoord.plot(ly = d$Value[1:4],ry = d$Value[5:8], rx = c(9,11,13,15), lx = c(1,3,5,7),
            type = c('bar','bar'), 
            xlim = c(0,16),
            lylim = c(0,0.35),rylim = c(12,150))
par(xaxt="s")           
axis(1, at = c(1,3,5,7,9,11,13,15),
        labels = paste(d$Category,d$SubCat,sep=""),
        las = 3)

enter image description here

Upvotes: 4

Related Questions