2017-07-13 20 views
3

我正在嘗試製作大量的「小倍數」圖。 (Aside/Background)我有太多的方面要顯示在一個單一的情節,所以我需要手動將它們分組到不同的情節。我希望我可以通過所需的ncolnrowfacet_wrap,它會盡可能地多我所需要的。事實並非如此。調整strip.background以匹配ggplot中的strip.text facet_wrap

因爲我有很多方面,空間是非常寶貴的。所以,我想減少facet標籤的大小。容易減少strip.text字體的大小,但遺憾的是strip.background矩形不符合字體大小,也不提供尺寸參數(除了邊框尺寸)。將其設置爲element_blank()實際上並沒有刪除爲其留出的空間,它只是使相同的空間透明。

MWE:

set.seed(1) 
xcat = rep(1:10, 1000) 
yvalue1 = rep(runif(10,5,7),1000) 
yvalue2 = rep(runif(10,4,6),1000) 
id = rep(1:1000,each=10) 

df = data.frame(id,xcat,yvalue1,yvalue2) 

for(i in seq(1, length(unique(df$id)), by=100)){ 
    print(
    ggplot(subset(df, id %in% unique(df$id)[i:(i+99)]), aes(x=xcat)) + 
     annotate("line", y=yvalue1, x=xcat, colour="cornflowerblue") + 
     annotate("line", y=yvalue2, x=xcat, colour="grey20") + 
     theme(axis.text.x = element_text(size=5), 
      axis.text.y = element_text(size=5), 
      strip.text = element_text(size=5)) + 
     facet_wrap(~id, ncol=10, nrow=10) + 
     expand_limits(y=0)) 
} 

example image with default grey strip.background

我如何能減少strip.background的高度,使得它不會佔用這麼大的空間的任何想法?理想情況下,它將根據id文本的確切高度來確定大小。

作爲獎勵,如何減少facets之間的間距? (是否有facet_wrap我失蹤的設置?)

它也需要很長一段時間在RStudio渲染與facet_wrap(不facet_wrap它的速度要快得多。

回答

1

你想要的結果是可以實現的修改由ggplot創建的grobs這個過程有點凌亂,並且必然需要一些手動微調:

拋開循環,這對問題沒有影響,我們可以通過減少facet之間的間距開始。通過將panel.spacing自變量添加到theme

library(ggplot2) 

d <- ggplot(subset(df, id %in% unique(df$id)[1:(100)]), aes(x=xcat)) + 
    annotate("line", y=yvalue1, x=xcat, colour="cornflowerblue") + 
    annotate("line", y=yvalue2, x=xcat, colour="grey20") + 
    theme(axis.text.x = element_text(size=5), 
     axis.text.y = element_text(size=5), 
     strip.text = element_text(size=5), 
     panel.spacing = unit(.5, 'pt')) + 
    facet_wrap(~id, ncol=10, nrow=10) + 
    expand_limits(y=0) 

我們接下來要產生GGPLOT2情節GROB。這會創建組成劇情的各個元素的列表。

g <- ggplotGrob(d) 

head(g, 5) 
# TableGrob (5 x 43) "layout": 13 grobs 
# z   cells  name         grob 
# 1 3 (5- 5, 4- 4) axis-t-1-1       zeroGrob[NULL] 
# 2 3 (5- 5, 8- 8) axis-t-2-1       zeroGrob[NULL] 
# 3 3 (5- 5,12-12) axis-t-3-1       zeroGrob[NULL] 
# 4 3 (5- 5,16-16) axis-t-4-1       zeroGrob[NULL] 
# 5 3 (5- 5,20-20) axis-t-5-1       zeroGrob[NULL] 
# 6 3 (5- 5,24-24) axis-t-6-1       zeroGrob[NULL] 
# 7 3 (5- 5,28-28) axis-t-7-1       zeroGrob[NULL] 
# 8 3 (5- 5,32-32) axis-t-8-1       zeroGrob[NULL] 
# 9 3 (5- 5,36-36) axis-t-9-1       zeroGrob[NULL] 
# 10 3 (5- 5,40-40) axis-t-10-1       zeroGrob[NULL] 
# 11 4 (4- 4, 4-40)  xlab-t       zeroGrob[NULL] 
# 12 8 (3- 3, 4-40) subtitle zeroGrob[plot.subtitle..zeroGrob.77669] 
# 13 9 (2- 2, 4-40)  title zeroGrob[plot.title..zeroGrob.77668] 

我們的目標是找到並修復相對於鋼帶的高度。

for(i in 1:length(g$grobs)) { 
    if(g$grobs[[i]]$name == 'strip') g$grobs[[i]]$heights <- unit(5, 'points') 
} 

不幸的是,stripgrobs也受到不同heights的主要情節分爲,所以我們要減少那些也。我還沒有找到一種方法來以編程方式確定哪個高度指的是鋼帶,但檢查g$heights是非常快速的找出我們需要的。

g$heights 
# [1] 5.5pt    0cm     0cm     0cm     0cm     
# [6] 0.518897450532725cm 1null    0cm     0.5pt    0cm     
# [11] 0.518897450532725cm 1null    0cm     0.5pt    0cm     
# [16] 0.518897450532725cm 1null    0cm     0.5pt    0cm     
# [21] 0.518897450532725cm 1null    0cm     0.5pt    0cm     
# [26] 0.518897450532725cm 1null    0cm     0.5pt    0cm     
# [31] 0.518897450532725cm 1null    0cm     0.5pt    0cm     
# [36] 0.518897450532725cm 1null    0cm     0.5pt    0cm     
# [41] 0.518897450532725cm 1null    0cm     0.5pt    0cm     
# [46] 0.518897450532725cm 1null    0cm     0.5pt    0cm     
# [51] 0.518897450532725cm 1null    0.306264269406393cm 1grobheight   0cm     
# [56] 5.5pt  

strip_grob_position <- seq(6, length(g$heights) - 5, 5) 
for(i in strip_grob_position) { 
    g$heights[[i]] = unit(.05, 'cm') 
} 

我們可以得出如下結果:

library(grid) 
grid.newpage() 
grid.draw(g) 

enter image description here

我不是專家在主題好,所以我可能說過或錯誤或不準確解釋的東西。此外,可能有更好的(並且更簡單和更ggplot-ish)方法來獲得結果。

+0

太棒了!我把整個事情都追溯到最後一部分。 'panel.spacing'和'g $ heights'只是這些條是有道理的。但我不清楚,你改變的最終高度是個別的陰謀地區,直到我繪製中間結果,並看到條和地塊之間的空間。你是如何選擇0.05釐米作爲合適的單位的? –

+0

這似乎是一個明智的價值,難的部分確實是找到合適的一個。不知道爲什麼,但我一直無法從'cm'更改爲任何其他單位,例如'pt',因爲它通常是'unit()'的情況。 – GGamba