geom_raster faceted plot with ggplot2: control row

2019-05-22 02:33发布

问题:

In the example below I have a dataset containing two experiments F1 and F2. A classification is performed based on F1 signal, and both F1 and F2 values are ordered accordingly. In this diagram, each facet has the same dimension although the number of rows is not the same (e.g class #7 contains only few elements compare to the other classes). I would like to modify the code to force row height to be the same across facets (facets would thus have various blank space below). Any hints would be greatly appreciated. Thank you

library(ggplot2)
library(reshape2)

set.seed(123)

# let's create a fake dataset
nb.experiment <- 4
n.row <- 200
n.col <- 5
nb.class <- 7

d <- matrix(round(runif(n.row * n.col),2), nc=n.col) 
colnames(d) <- sprintf("%02d", 1:5)

# These strings will be the row names of each heatmap
# in the subsequent facet plot
elements <- sample(replicate(n.row/2, rawToChar(as.raw(sample(65:90, 6, replace=T)))))


# let's create a data.frame d
d <- data.frame(d, 
                experiment = sort(rep(c("F1","F2"), n.row/2)),
                elements= elements)

# Now we split the dataset by experiments
d.split <- split(d, d$experiment)


# Now we create classes (here using hierarchical clustering )
# based on F1 experiment
dist.mat <- as.dist(1-cor(t(d.split$F1[,1:5]), method="pearson"))
hc <- hclust(dist.mat)
cuts <- cutree(hc, nb.class)
levels(cuts) <- sprintf("Class %02d", 1:nb.experiment)

# We split F1 and F2 based on classification result
for(s in names(d.split)){
  d.split[[s]] <- split(d.split[[s]], cuts)
}


# Data are melt (their is perhaps a better solution...)
# in order to use the ggplot function
dm <- melt(do.call('rbind',lapply(d.split, melt)), id.var=c( "experiment", "elements", "variable", "L1"))
dm <- dm[, -5]
colnames(dm) <- c("experiment","elements", "pos", "class", "exprs")
dm$class <- as.factor(dm$class)
levels(dm$class) <- paste("Class", levels(dm$class))

# Now we plot the data
p <- ggplot(dm, aes(x = pos, y = elements, fill = exprs))
p <- p + geom_raster()                                        
p <- p + facet_wrap(~class +experiment , scales = "free", ncol = 2)
p <- p + theme_bw()
p <- p + theme(text = element_text(size=4))
p <- p + theme(text = element_text(family = "mono", face = "bold"))

print(p)

回答1:

Use facet_grid instead of facet_wrap and set the space attribute:

ggplot(dm, aes(x = pos, y = elements, fill = exprs)) +
  geom_raster() +    
  facet_grid(rowMeanClass ~ experiment , scales = "free", space = "free_y") + 
  theme_bw()