複数のファセット変数を含むプロットでは、ggplot2 は、「内部」変数のすべてのレベルにまたがる単一のスパニング ファセット ストリップを使用するのではなく、「外部」変数のファセット ラベルを繰り返します。パッケージgtable_add_grob
から使用して、繰り返される外側のファセット ラベルを単一のスパニング ファセット ストリップでカバーするために使用しているコードがあります。gtable
残念ながら、ファセット ストリップのグロブ構造が変更されたため、このコードは ggplot2 2.2.0 では機能しなくなりました。具体的には、ggplot2 の以前のバージョンでは、ファセット ラベルの各行に独自のグロブ セットがありました。ただし、バージョン 2.2.0 では、ファセット ラベルの各垂直スタックが単一のグロブのように見えます。これによりコードが破損し、修正方法がわかりません。
数か月前に回答した SO の質問から取った具体的な例を次に示します。
# Data
df = structure(list(location = structure(c(1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L), .Label = c("SF", "SS"), class = "factor"), species = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("AGR", "LKA"), class = "factor"),
position = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L,
2L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L,
1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L,
2L), .Label = c("top", "bottom"), class = "factor"), density = c(0.41,
0.41, 0.43, 0.33, 0.35, 0.43, 0.34, 0.46, 0.32, 0.32, 0.4,
0.4, 0.45, 0.34, 0.39, 0.39, 0.31, 0.38, 0.48, 0.3, 0.42,
0.34, 0.35, 0.4, 0.38, 0.42, 0.36, 0.34, 0.46, 0.38, 0.36,
0.39, 0.38, 0.39, 0.39, 0.39, 0.36, 0.39, 0.51, 0.38)), .Names = c("location",
"species", "position", "density"), row.names = c(NA, -40L), class = "data.frame")
# Begin with a regular ggplot with three facet levels
p=ggplot(df, aes("", density)) +
geom_boxplot(width=0.7, position=position_dodge(0.7)) +
theme_bw() +
facet_grid(. ~ species + location + position) +
theme(panel.margin=unit(0,"lines"),
strip.background=element_rect(color="grey30", fill="grey90"),
panel.border=element_rect(color="grey90"),
axis.ticks.x=element_blank()) +
labs(x="")
3 つのレベルのファセットを持つプロットから始めます。
次に、上部の 2 つのファセット ストリップをスパニング ストリップで覆い、ストリップ ラベルが繰り返されないようにします。
pg = ggplotGrob(p)
# Add spanning strip labels for species
pos = c(4,11)
for (i in 1:2) {
pg <- gtable_add_grob(pg,
list(rectGrob(gp=gpar(col="grey50", fill="grey90")),
textGrob(unique(densityAGRLKA$species)[i],
gp=gpar(cex=0.8))), t=3,l=pos[i],b=3,r=pos[i]+7,
name=c("a","b"))
}
# Add spanning strip labels for location
pos=c(4,7,11,15)
for (i in 1:4) {
pg = gtable_add_grob(pg,
list(rectGrob(gp = gpar(col="grey50", fill="grey90")),
textGrob(rep(unique(densityAGRLKA$location),2)[i],
gp=gpar(cex=0.8))), t=4,l=pos[i],b=4,r=pos[i]+3,
name = c("c","d"))
}
grid.draw(pg)
これは、このプロットが ggplot2 2.1.0 でどのように見えるかです:
ただし、ggplot2 2.2.0 で同じコードを試すと、ストリップ ラベルを変更せずに元のプロットが返されます。元のプロットのグロブ構造を見ると、p
なぜこれが起こっているのかがわかります。この質問の下部にあるグロブ テーブルに貼り付けました。スペースを節約するために、ファセット ストリップに関連する行のみを含めました。
列を見るとcells
、プロットの 2.1.0 バージョンでは、各行の最初の 2 つの数字が 3、4、または 5 のいずれかであり、プロット内の他のグロブに対するグロブの垂直位置を示していることに注意してください。上記のコードでは、t
とのl
引数gtable_add_grob
が 3 または 4 の値に設定されています。これは、スパン ストリップでカバーしたかったファセット ストリップ行であるためです。
2.2.0 バージョンのプロットの列を見てcells
ください。最初の 2 つの数値は常に 6 であることに注意してください。また、バージョン 2.1.0 では 24 の代わりにファセット ストリップが 8 つのグロブで構成されていることにも注意してください。バージョン 2.2.0 では、3 つのファセット ラベルの各スタックが、3 つの個別のグロブではなく、1 つのグロブになっているようです。したがって、t
andのb
引数gtable_add_grob
を 6 に変更しても、3 つのファセット ストリップすべてがカバーされます。次に例を示します。
pg = ggplotGrob(p)
# Add spanning strip labels for species
pos = c(4,11)
for (i in 1:2) {
pg <- gtable_add_grob(pg,
list(rectGrob(gp=gpar(col="grey50", fill="grey90")),
textGrob(unique(densityAGRLKA$species)[i],
gp=gpar(cex=0.8))), t=6,l=pos[i],b=6,r=pos[i]+7,
name=c("a","b"))
}
gtable_add_grob
それで、その非常に長い導入の後、ここに私の質問があります: ggplot2 バージョン 2.1.0 で使用して作成したもののように見える ggplot2 バージョン 2.2.0 でスパニング ファセット ストリップを作成するにはどうすればよいですか? 簡単な調整があることを願っていますが、大手術が必要な場合は、それも問題ありません.
ggplot 2.1.0
pg
TableGrob (9 x 19) "layout": 45 grobs z cells name grob 2 1 ( 3- 3, 4- 4) strip-top absoluteGrob[strip.absoluteGrob.147] 3 2 ( 4- 4, 4- 4) strip-top absoluteGrob[strip.absoluteGrob.195] 4 3 ( 5- 5, 4- 4) strip-top absoluteGrob[strip.absoluteGrob.243] 5 4 ( 3- 3, 6- 6) strip-top absoluteGrob[strip.absoluteGrob.153] 6 5 ( 4- 4, 6- 6) strip-top absoluteGrob[strip.absoluteGrob.201] 7 6 ( 5- 5, 6- 6) strip-top absoluteGrob[strip.absoluteGrob.249] 8 7 ( 3- 3, 8- 8) strip-top absoluteGrob[strip.absoluteGrob.159] 9 8 ( 4- 4, 8- 8) strip-top absoluteGrob[strip.absoluteGrob.207] 10 9 ( 5- 5, 8- 8) strip-top absoluteGrob[strip.absoluteGrob.255] 11 10 ( 3- 3,10-10) strip-top absoluteGrob[strip.absoluteGrob.165] 12 11 ( 4- 4,10-10) strip-top absoluteGrob[strip.absoluteGrob.213] 13 12 ( 5- 5,10-10) strip-top absoluteGrob[strip.absoluteGrob.261] 14 13 ( 3- 3,12-12) strip-top absoluteGrob[strip.absoluteGrob.171] 15 14 ( 4- 4,12-12) strip-top absoluteGrob[strip.absoluteGrob.219] 16 15 ( 5- 5,12-12) strip-top absoluteGrob[strip.absoluteGrob.267] 17 16 ( 3- 3,14-14) strip-top absoluteGrob[strip.absoluteGrob.177] 18 17 ( 4- 4,14-14) strip-top absoluteGrob[strip.absoluteGrob.225] 19 18 ( 5- 5,14-14) strip-top absoluteGrob[strip.absoluteGrob.273] 20 19 ( 3- 3,16-16) strip-top absoluteGrob[strip.absoluteGrob.183] 21 20 ( 4- 4,16-16) strip-top absoluteGrob[strip.absoluteGrob.231] 22 21 ( 5- 5,16-16) strip-top absoluteGrob[strip.absoluteGrob.279] 23 22 ( 3- 3,18-18) strip-top absoluteGrob[strip.absoluteGrob.189] 24 23 ( 4- 4,18-18) strip-top absoluteGrob[strip.absoluteGrob.237] 25 24 ( 5- 5,18-18) strip-top absoluteGrob[strip.absoluteGrob.285]
ggplot2 2.2.0
pg
TableGrob (11 x 21) "layout": 42 grobs z cells name grob 28 2 ( 6- 6, 4- 4) strip-t-1 gtable[strip] 29 2 ( 6- 6, 6- 6) strip-t-2 gtable[strip] 30 2 ( 6- 6, 8- 8) strip-t-3 gtable[strip] 31 2 ( 6- 6,10-10) strip-t-4 gtable[strip] 32 2 ( 6- 6,12-12) strip-t-5 gtable[strip] 33 2 ( 6- 6,14-14) strip-t-6 gtable[strip] 34 2 ( 6- 6,16-16) strip-t-7 gtable[strip] 35 2 ( 6- 6,18-18) strip-t-8 gtable[strip]