Bars in geom_bar are not of equal width

1k views Asked by At

For the following data frame I want to make several bar plots using ggplot.

df <- data.frame(Disease = c("Disease1","Disease2","Disease3","Disease3","Disease3","Disease4","Disease5","Disease5","Disease6","Disease4","Disease2","Disease2","Disease1","Disease7","Disease1","Disease1","Disease7","Disease6","Disease3","Disease6"),
                   Week = c(3,52,46,47,19,39,42,46,44,45,46,42,45,48,44,44,43,42,45,47),
                   Year = c(2015,2015,2015,2016,2015,2015,2016,2016,2015,2015,2015,2015,2016,2016,2016,2015,2016,2016,2016,2015),
                   Number = c(1,1,6,5,1,1,4,12,4,15,6,15,6,11,4,2,9,1,4,1))

I use the following syntax which gives me several bar plots.

ggplot(df, aes(factor(Week), Number )) + 
  geom_bar(stat="identity" , aes(fill = factor(Year)), position = "dodge") + 
  facet_wrap(~ Disease, ncol = 2, scales = "free_y") +
  labs(x = "Week", y = "Number") +
  scale_fill_discrete(name = "Year")

enter image description here

However, I would like all bars to have the same width (see Disease 1 for differences in width). I have already found an answer here Bars in geom_bar have unwanted different widths when using facet_wrap but I cannot get this to work in my example. Does anyone have a solution to my problem? Obviously, my original dataset is much larger and the problem of different bar widths occurs much more often than in my example above.

2

There are 2 answers

1
Marius On BEST ANSWER

You can fix this by filling out the dataset with a 0 for each Disease + Week + Year:

library(tidyverse)
df2 = df %>%
    complete(Disease, Week, Year, fill = list(Number = 0))

ggplot(df2, aes(factor(Week), Number )) + 
    geom_bar(stat="identity" , aes(fill = factor(Year)), position = "dodge") + 
    facet_wrap(~ Disease, ncol = 2, scales = "free_y") +
    labs(x = "Week", y = "Number") +
    scale_fill_discrete(name = "Year")

You could also try filling with a small number like 0.1 so you get some tiny bars at each x-axis location - I think this can help make clear that there is a space there for each bar, but you are introducing potentially confusing fake values:

df2 = df %>%
    complete(Disease, Week, Year, fill = list(Number = 0.1))
0
Colin FAY On

That's normal: on the x axis, every unit has the same space on the axis (here, 1 week).

There are weeks where there are just 2015, just 2016, none, or both. When there are both years, the week unit is the same as when there are just one year. So when there are both years to be plotted, the "space for a unit" is splitted in two, hence the bar which are twice smaller.

The "problem" is then not on the facet_wrap, but due to position = "dodge", which puts bar side to side.

Colin