3

I am working in the updated ggplot2 (2.2.0). A great new feature is the ability to plot along each x-axis for an uneven number of plots, as per this page.

I wish to plot with the same x-axis in each facet. However, this does not work when missing data is introduced. As an example, I shall draw upon the example data in this question.

# Example dataset
dataf <- data.frame(x=c(1:30), A=rnorm(30,20,5), B=rnorm(30,15,0.5))
datam <- melt(dataf, id="x")
# Plot in ggplot2
ggplot(datam, aes(factor(x), value)) + 
  geom_bar(stat="identity") + 
  facet_wrap(~variable,nrow = 2,scales = "free")

When I remove particular rows and introduce missing data (as per my code below), I am no longer to have the same x-axis labels for both "A" and "B".

# Remove certain rows to introduce missing data
datam <- datam[-c(2, 4, 58), ]

I can plot missing values and align to the bottom x-axis using scales = fixed although I no longer have x-axis tick mark labels for group "A" in the facet.

ggplot(datam, aes(factor(x), value)) + 
  geom_bar(stat="identity") + 
  facet_wrap(~variable,nrow = 2,scales = "fixed")

How do have the exact same x-axis labels showing for every facet, even when there is missing data?

Thank you.

Community
  • 1
  • 1
user2716568
  • 1,866
  • 3
  • 23
  • 38
  • @hadley - is there functionality within ggplot2 to please do the above without having to use the workaround in the answer below? – user2716568 Dec 17 '16 at 10:45
  • I provided solution below only within ggplot2 functionality, without workaround. – Djork Mar 12 '22 at 02:29

2 Answers2

1

You could do something like:

library(reshape2)
library(ggplot2)
dataf <- data.frame(x=c(1:30), A=rnorm(30,20,5), B=rnorm(30,15,0.5))
datam <- melt(dataf, id="x")
datam2 <- datam[-c(2, 4, 58), ] #mising rows
graph<-ggplot(datam2, aes(factor(x), value)) + 
  geom_bar(stat="identity") + 
  facet_wrap(~variable,nrow = 2,scales = "fixed")
library(gtable)
library(grid)
g <- ggplotGrob(graph) #retrieve grob from graph
panels <- grep("panel", g$layout$name)
top <- unique(g$layout$t[panels])
all <- gtable:::rbind_gtable(gtable:::rbind_gtable(g[seq.int(min(top)), ], 
                                                   g[max(top)+1,], "first"), 
                             g[seq(min(top)+1, nrow(g)),], "first")
grid.newpage()
grid.draw(all)

enter image description here
Pretty sure that a solution I found on SO at some point. But can't remember the original post.

Haboryme
  • 4,611
  • 2
  • 18
  • 21
  • 1
    Great, thanks for the workaround! It is a shame it couldn't be addressed through the scales option. How would I add my y-axis label (not in original post)? – user2716568 Dec 17 '16 at 10:08
0

Here is a solution using only ggplot2 functionality. There is a drop parameter in scale_x_discreet' and scale_y_discreet' when set to FALSE, it shows all factors regardless if no data exist for that factor.

See ? scale_x_discreet. The first step is to factor datam$x.

library(ggplot2)
dataf <- data.frame(x=c(1:30), A=rnorm(30,20,5), B=rnorm(30,15,0.5))
datam <- melt(dataf, id="x")

# missing data
datam <- datam[-c(2, 4, 58), ]

# solution
ggplot(datam, aes(factor(x), value)) + 
  geom_bar(stat="identity") + 
  facet_wrap(~variable,nrow = 2, scales = "free") + 
  scale_x_discrete(drop=FALSE)

enter image description here

Djork
  • 3,319
  • 1
  • 16
  • 27