michael
michael

Reputation: 814

Prevent factor level being dropped in ggplot facetted histograms

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.

Upvotes: 3

Views: 812

Answers (1)

RHA
RHA

Reputation: 3872

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.

Upvotes: 4

Related Questions