0

Drawing bars with variable widths is a common request and I found many solutions here at SO, but they all seem to work only when the plot consists of individual bars while I have them in groups:

set.seed(1)
dat <- data.frame(group=c('foo', 'foo', 'foo', 'bar', 'xyz', 'xyz'), 
                  indiv=c('foA', 'foB', 'foC', 'baD', 'xyE', 'xyF'),
                  val=sample(30:90, 6),
                  wid=sample(2:8, 6)
                  )

ggplot(dat, aes(x=group, y=val)) + 
  geom_bar(aes(fill=indiv), stat="identity", position="dodge") +
  theme_bw() # btw this also doesn't work as expected but that's another question

Here is what I get: what I get

And what I need is something like this: desired result

(this picture is the result of my workaround shown in the answer below)

Vasily A
  • 8,256
  • 10
  • 42
  • 76
  • You need to group the data into different bins. See: http://stackoverflow.com/questions/9556359/different-width-for-each-bar-using-geom-bar-with-position-fill-in-ggplot2. And see: http://stackoverflow.com/questions/5948604/variable-width-bars-in-ggplot2-barplot-in-r/5948998#5948998 – Jean-Paul Nov 26 '14 at 22:56
  • @Jean-Paul, thanks for the answer but but for the moment I don't understand how I can apply those examples in my situation. I am trying to find out what is the idea of the first post (the second one, which you suggest as a duplicate, I've read before and it definitely doesn't help me - it's not about groups). – Vasily A Nov 26 '14 at 23:10
  • (I added pictures to be more clear) – Vasily A Nov 26 '14 at 23:27
  • 1
    I misread the answer to the second post. You are right, you are facing a different problem. Let me try to help you. – Jean-Paul Nov 26 '14 at 23:32
  • I've submitted an answer. I wrote this by heart (without checking any results), so there might be some errors. Anyway, you should get the general idea. Good luck :) – Jean-Paul Nov 26 '14 at 23:51

1 Answers1

1

I will put here my solution but I find it rather ugly and will be glad if someone can suggest better one.

# convert to data.table -
# just because I'm more familiar with it, otherwise just use `plyr`
dat <- data.table(dat)

# assign number to each group:
dat[, grp:=.GRP, by=group]

gap <- 2 # gap width

# coordinate of each bar:
dat$pos <- dat$grp*gap + 0.5 * (cumsum(dat$wid) + cumsum(c(0, dat$wid[-length(dat$wid)])))

#coordinate of each group's label:
grppos <- dat[, (min(pos-wid/2)+max(pos+wid/2))/2, by=group]

# draw plot
ggplot(dat, aes(x=pos, y=val)) + 
  geom_bar(aes(width=wid), stat="identity", col='black') +
  scale_x_continuous(labels=grppos$group, breaks=grppos$V1)
Vasily A
  • 8,256
  • 10
  • 42
  • 76