2014-02-13 74 views
1

該水平板基本上是同樣的問題this one,但有一個重要的區別:我想基於GGPLOT2瓦情節與水平面板,並在所有拼貼的高度相等。另一個問題是關於垂直面板。GGPLOT2瓦地塊不同高度

下面是一些示例代碼的基礎上,一個在另一個問題:使用

ggplot(d, aes(x=month, y=sites, fill=value)) + 
    geom_tile(colour="white") + facet_wrap(~panel, nrow=1) 

結果

d = data.frame(sites=rep(paste("S", 1:31),each=12), 
       month=factor(rep(1:12,31)), 
       value=runif(31*12), 
       panel=c(rep("Group 1",16*12), rep("Group 2", 12*12), 
         rep("Group 3", 3*12))) 

繪製這enter image description here

基本上,我想的藍色每個塊瓷磚向上移動,因此上面沒有空間。我能做到這一點使用

ggplot(d, aes(x=month, y=sites, fill=value, colour="white")) + 
    geom_tile(colour="white") + facet_wrap(~panel, scales="free_y", nrow=1) 

,但這會導致高度不等磚:

enter image description here

The other question有垂直面板的一個很好的解決方案,但將其應用到上面的代碼沒有任何影響。是否有類似的水平面板解決方案?

回答

3

下面是使用gridExtra和設置水平的黑客:

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))) 

enter image description here

這將引發一些警告,但可以忽略它們。此外,您需要添加標題和圖例(您可以混淆邏輯,以便最後一個生成圖例)。

與此相關的主要問題是顏色比例將獨立適合每個圖形,但您可以強制將其固定。

+0

感謝您一個不錯的解決方案。而且很容易改變,將塊移到頂部而不是底部。我想改變的一件事是''lvls < - unique(as.character(d.sub $ sites))'到'lvls < - levels(droplevels(d.sub $ sites))',以保持順序行(對於我的示例數據無關緊要,因爲行已經被標記/按照數字順序排列),但對於其他數據,這會有所作爲。 –

0

我會接受@ BrodieG的解決方案,因爲這是我的問題的最一般的解決方案,但我會添加自己的,對於實際的行/網站名稱無關緊要的特殊情況,只有(面板內)順序的瓷磚行。在這裏,我們可以使用hack來將所有子組中的級別名稱更改爲具有最大行數的組中使用的級別名稱。例如數據和原始的情節:

# Example data 
set.seed(7) 
d = data.frame(sites=rep(paste("S", 1:31),each=12), 
       month=factor(rep(1:12,31)), 
       value=runif(31*12), 
       panel=c(rep("Group 1",16*12), 
         rep("Group 2", 12*12), 
         rep("Group 3", 3*12))) 

# Reorder rows/site names (just to show that the code works properly) 
d$sites = reorder(d$sites, d$value, mean) 

# Original plot 
library(ggplot2) 
ggplot(d, aes(x=month, y=sites, fill=value)) + 
    geom_tile(colour="white") + facet_wrap(~panel, nrow=1) 

enter image description here

現在,我們只需要改變每個子組的站點名稱:

# Fetch the name of the group with the most rows 
library(plyr) 
d.stat = ddply(d, .(panel), summarise, nrows=length(unique(sites))) 
maxpanel = with(d.stat, panel[which.max(nrows)]) 

# Fetch the levels/rownames of the group with the most rows 
levels.maxpanel = levels(droplevels(subset(d, panel==maxpanel))$sites) 

# Substitute the levels/row names of the 
# biggest group for each subgroup 
subs.levels = function(d.sub) { 
    levels.subpanel = rev(levels(droplevels(d.sub$sites))) 
    d.sub$sites[] = rev(levels.maxpanel)[match(d.sub$sites, levels.subpanel)] 
    d.sub 
} 
d.recoded = ddply(d, .(panel), subs.levels) 

# New plot 
ggplot(d.recoded, aes(x=month, y=sites, fill=value)) + 
    geom_tile(colour="white") + facet_wrap(~panel, nrow=1) + 
    theme(axis.text.y=element_blank()) 

enter image description here