3

I'm using ggplot (v1.0.1) to plot histograms with bar fill mapped to a binary State factor and using position = "dodge". The histograms are facetted by a second Group factor. When one level of the State factor is absent from a group, the plot for that facet differs from those where both levels are present. The following toy example illustrates this:

set.seed(1234)
states <- c("Alive", "Dead")
dat <- data.frame(Group = rep(LETTERS[1:2], each=100), 
              Measure = rnorm(200, 50, 10),
              State = c(rep(states, 50), rep("Alive", 100)))

ggplot() +
  geom_histogram(data=dat, aes(x=Measure, fill=State), 
                 position="dodge", binwidth=5) +
  facet_wrap(~ Group)

default behaviour with level dropped from facet B

What I would like is for the bars in the facet for Group B to have the same width and relative position as those for Group A. I thought facet_wrap(~ Group, drop = FALSE) would accomplish this but it doesn't seem to have any effect. The following work-around achieves the desired plot:

dat <- rbind(dat, data.frame(Group="B", Measure=50, State=NA))
ggplot() +
  geom_histogram(data=dat, aes(x=Measure, fill=State), 
                 position="dodge", binwidth=5) +
  scale_fill_discrete(na.value = NA) +
  facet_wrap(~ Group)

work-around to give same bin width and position in facets

But I'm sure I must be missing a ggplot option that would accomplish this without having to hack the data.

michael
  • 762
  • 7
  • 13
  • 1
    `ggplot` is generally very good at plotting the data in your data frame, I'm not sure that I'd consider making your data frame better match what you want to plot "hacking the data". `tidyr` has the `complete()` function for just such a transformation. – Gregor Thomas Nov 02 '15 at 06:22
  • In the strict sense, your plot is not a histogram. Instead of using `position_dodge`, I'd use `alpha` transparency or another faceting dimension. – Roland Nov 02 '15 at 07:20
  • @Gregor thanks for the tip about the tidyr function – michael Nov 03 '15 at 01:50

1 Answers1

4

The short answer is NO; there is unfortunately no ggplot option that can achieve this for you. There are several workarounds.

The first and probably easiest option you have already found, adding NA's.

The second option is to manually adjust the width of the bars, like in the first answer to this question.

The third option is taken from the suggestion @Roland: don't "dodge" but use transparency:

ggplot() +
  geom_histogram(data=dat, aes(x=Measure, fill=State), 
                 position=position_identity(), binwidth=5, alpha=0.5) +
  facet_wrap(~ Group) +
  #change the colors and background, to improve visibility
  scale_fill_manual(values=c("red","blue")) +
  theme(panel.background = element_rect(fill = "transparent",colour = "black"))

Will give you this graph:

ggplot histogram with transparency

Personally I find it hideous.

Community
  • 1
  • 1
RHA
  • 3,677
  • 4
  • 25
  • 48