Here is a hack using gridExtra
and setting up levels:
d.splt <- split(d, d$panel)
max.unique <- max(sapply(d.splt, function(x) length(unique(x$sites))))
d.gg <- lapply(d.splt, function(d.sub){
lvls <- unique(as.character(d.sub$sites))
length(lvls) <- max.unique
lvls <- replace(lvls, is.na(lvls), "")
d.sub$sites <- factor(as.character(d.sub$sites), levels=lvls)
ggplot(d.sub, aes(x=month, y=sites, fill=value, colour="white")) +
geom_tile(colour="white", stat="identity") +
scale_y_discrete(drop=F) + scale_fill_continuous(guide=F)
} )
library(gridExtra)
do.call(grid.arrange, c(d.gg, list(nrow=1)))
This will throw some warnings, but you can ignore them. Also, you'll need to add titles and also a legend (you can mess with the logic so the last one produces a legend).
The main issue with this is that the color scale will be fit for each graph independently, but there you can force that to be fixed.