・お題:先日、ggplotで棒グラフを作成した。X軸のラベルを二層にしたい場合があったので、やり方をメモしたい。基本的にはfacetを使う。
・ライブラリを読み込み、データを作る。
> library(tidyverse)
> set.seed(1)
> TestComp. <- rep(c("Vehicle", "Comp.A(mg/kg)", "Comp.B(mg/kg)"),
+ times = c(10, 30, 30))
> Dose <- c(rep(0, times = 10),
+ rep(c(1, 3, 10), each = 10),
+ rep(c(1, 3, 10), each = 10))
> Score <- c(rnorm(10, mean = 10, sd = 2),
+ rnorm(10, mean = 10, sd = 2),
+ rnorm(10, mean = 15, sd = 2),
+ rnorm(10, mean = 20, sd = 2),
+ rnorm(10, mean = 15, sd = 2),
+ rnorm(10, mean = 20, sd = 2),
+ rnorm(10, mean = 20, sd = 2))
> df <-
+ data.frame(TestComp., Dose, Score) %>%
+ group_by(TestComp., Dose) #TestComp.とDoseの条件ごとにGroup化しておく。
・作ったデータはこんな感じ。
> df
・データを読み込む。
> p <- ggplot(data = df)
・とりあえず、X軸のラベルが単層の場合でやってみる。
> bar <- p +
+ geom_bar(mapping = aes(x = factor(Dose),
+ y = Score,
+ fill = factor(TestComp.)),
+ position="dodge",
+ stat = "summary",
+ fun = "mean",
+ color = "gray30",
+ width = 0.6)+
+ scale_fill_manual(name = "Groups", labels = c("Comp.A", "Comp.B", "Vehicle"), values = c("black", "red", "white")) + #個別の色を設定
+ geom_point(mapping = aes(x = factor(Dose),
+ y = Score,
+ fill = factor(TestComp.)),
+ position = position_dodge(0.6),
+ color = "gray") +
+ scale_y_continuous(expand = c(0, 0), limits = c(0, 40)) +
+ labs(title="title1",
+ x = "Dose(mpk)",
+ y = "Score")+
+ theme_classic()
> plot(bar)
・この時点で、「並びが悪い」「Vehicleが太い」など改良の余地あり。とりあえず、このままfacetしてみる。
> bar2 <- bar +
+ facet_grid(. ~ as.factor(TestComp.),
+ switch = "x") +
+ theme(strip.placement = "outside",
+ strip.background = element_rect(fill = "white"),
+ axis.title.x = element_blank())
> plot(bar2)
・分からないではないが、各Groupで余分なDoseができてしまっている。もうちょっとうまいことやりたい。以下のサイトを参考にさせて頂いた。
・一気にまとめていく。
> bar3 <- p +
+ geom_bar(mapping = aes(x = as.factor(Dose),
+ y = Score,
+ fill = factor(TestComp., levels=c("Vehicle", "Comp.A(mg/kg)" , "Comp.B(mg/kg)"))), #levelsでfactorの序列を指定する。
+ position="dodge",
+ stat = "summary",
+ fun = "mean",
+ color = "gray30",
+ width = 0.6)+
+ scale_fill_manual(name = "Groups", labels = c("Vehicle", "Comp.A", "Comp.B"), values = c("white","black", "red")) + #序列を指定しつつ、個別の色を設定
+ geom_point(mapping = aes(x = factor(Dose),
+ y = Score,
+ fill = factor(TestComp.)),
+ position = position_dodge(0.6),
+ color = "gray") +
+ scale_y_continuous(expand = c(0, 0), limits = c(0, 40)) +
+ labs(title="title1",
+ x = "Dose(mpk)",
+ y = "Score") +
+ theme_classic() +
+ facet_grid(. ~ factor(TestComp., levels=c("Vehicle", "Comp.A(mg/kg)" , "Comp.B(mg/kg)")), #表示のための序列を指定
+ scales = "free_x", # 空カラムがないように、GroupごとにDoseを変えられるようにする。
+ space = "free_x", # カラムの太さを揃える。
+ switch = "x")+
+ theme(strip.placement = "outside", #facetしたグループの場所を下に持ってくる
+ axis.title.x = element_blank(), #X軸ラベルを消す
+ text = element_text(size = 15) #ついでに、文字の大きさを変える
+ )
> plot(bar3)
・そもそもデータフレームの時点でfactor化して序列を設定しておけば、描画時にいちいち指定する必要がなくなる。少しだけシンプルになる。
> df$TestComp. <- factor(df$TestComp., levels=c("Vehicle", "Comp.A(mg/kg)" , "Comp.B(mg/kg)")) #序列を指定する。
> df$Dose <- factor(df$Dose) #数字もラベルとして使用するならfactor化しておく。
・最初のグラフでvehicle群が太くなっていたので、少し修正しておく。
> bar4 <- ggplot(data = df,
+ mapping = aes(x = Dose,
+ y = Score,
+ fill = TestComp.))+
+ geom_bar(stat = "summary",
+ fun = "mean",
+ color = "gray30",
+ width = 0.6,
+ position = position_dodge2(preserve = "single"))+#カラムの幅を揃える
+ scale_fill_manual(name = "Groups", labels = c("Vehicle", "Comp.A", "Comp.B"), values = c("white","black", "red")) +
+ geom_point(mapping = aes(x = Dose,
+ y = Score,
+ fill = TestComp.),
+ position = position_dodge(0.6),
+ color = "gray") +
+ scale_y_continuous(expand = c(0, 0), limits = c(0, 40)) +
+ labs(title="title1",
+ x = "Dose(mpk)",
+ y = "Score") +
+ theme_classic()
> plot(bar4)
・facet版はコードも結果も全く同じなので、割愛。
おわり。