本記事ではRのggplot2で作成した棒グラフにプロットを入れる方法について解説しています。
棒グラフに関連する記事はこちら↓
本記事の内容
本記事の内容については以下の通りです。
本記事で使うRパッケージとデータセット
本記事では、以下のパッケージを使用します。
・tidyverse:ロードすればggplot2も一緒にロードされます。必須。
・ggbeeswarm : プロットをきれいに散らばらせたい場合にあると便利
インストールしていないパッケージについてはインストールし、その後ロードしてください。
# ggbeeswarmをインストールしていなければインストール
install.packages("ggbeeswarm")
# パッケージをロードする
library(tidyverse)
library(ggbeeswarm)
Rのオススメ本
tidyverseパッケージを使ったオススメの実践入門書を紹介します。データの前処理や分析、可視化(ggplot2)が学べるのでとてもオススメ!
Rを使ってもっとデータ分析をしてみたい!と思わせてくれる一冊です。
使用するデータセット
今回使用するデータセットは、Rにもともと入っている"iris"データセットです。
棒グラフ作成シリーズの続きなのでmpgデータセットの方が良かったのですが、例としてあまり美しくなかったため今回はirisを使うことにしました。
head(iris)
> head(iris)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
irisデータセットとは:
・Rに元々入っているデータセットで、アヤメ(iris)というお花のデータ
・3種類のアヤメのガク片(Sepal)および花弁(Petal)の長さと幅がそれぞれ50個格納
・アヤメの種類はsetosa、versicolor、virginica
解説に使用する基本グラフについて
今回は、irisデータセットのSpecies(アヤメの種類)ごとのSepal.Length(ガクの長さ)の平均値の棒グラフをもとに解説していきます。そのため、この基本グラフをオブジェクトgとして保存しておきます。
基本の棒グラフの書き方はこちらをご確認ください。
# 基本グラフの作成
g <- ggplot(iris,
aes(x = Species,
y = Sepal.Length))+
stat_summary(geom = "bar",
fun = "mean",
fill = "grey80",
color = "black",
width = 0.5)+
theme_classic(base_size = 16)
g
この基本グラフgに、各Speciesにおける個別プロットを継ぎ足していきます。
棒グラフにプロットを入れる方法
棒グラフにプロットを入れる方法としては、
・geom_point()を使った方法
・ggbeeswarmパッケージを使った方法
の2パターンがあります。それぞれについて説明していきます。
最もシンプルな方法(geom_point())
geom_point()でプロットを入れる最もシンプルな方法です。
プロット数が少ない場合はgeom_pointで十分かと思いますが、プロット数が多くなると点同士が重なってしまいます。
# alpha でプロットの透過度を設定する
g +
geom_point(alpha = 0.3)
alphaの設定幅は0~1で、0に近くなるほど半透明になります。
点同士の重なりが多いほど色が濃くなるので、上記グラフの場合は重なりが非常に多いことがわかります。
そこで、なるべくプロットの重なりを防いで点同士を散らばらせるために使うのが次に紹介するposition_jitterです。
プロットをランダムに散らばらせる(position_jitter)
ランダムに散らばらせる場合は、position_jitterを使用します。
g +
geom_point(position = position_jitter(width = 0.2,
seed = 2),
shape = 16,
alpha = 0.3,
size = 2)
・width : 散らばり幅
・seed : 散らばらせ方(後述)
を示しています。sizeやshapeはプロットのサイズや形の種類ですね。
seedについて
seedでは、"点同士の散らばり方”を設定できます。
seedは省略しても構いませんが、その場合はグラフを書くたびに散らばり方が変わります。そのため、グラフの再現性という観点で任意の値を入れておくといいです。
値は1でも9でも9999でもなんでもOKです。
プロットをキレイに散らばらせる方法(ggbeeswarm)
jitterではランダムに散らばらせることができました。
一方で、散らばり方はランダムで点同士で重なりが出てしまったりします。
そこで、よりキレイにプロットを並べる方法としてggbeeswarmパッケージを紹介します。
ggbeeswarmをインストールしていない場合は、前述の通りインストールしてください。
# ggbeeswarmをインストール
install.packages("ggbeeswarm")
# パッケージをロードする
library(ggbeeswarm)
beeswarmを使った散らばらせ方には、
・geom_beeswarm()を使う方法
・geom_pointの引数positionでbeeswarmを使う
この2つの方法があります。以下のコードはそれぞれ同じグラフになります。
g +
geom_beeswarm(aes(color = Species),
alpha = 0.5,
show.legend = FALSE)+
labs(title = "geom_beeswarm")
g + geom_point(aes(color = Species),
alpha = 0.5,
position = position_beeswarm(),
show.legend = FALSE)+
labs(title = "position_beeswarm")
・aes(color = Species) : Species(アヤメの種類)ごとに色付け
・show.legend = FALSE : 凡例を表示しないようにする
きれいに散らばりましたね!
ですが、点同士が半分重なってしまっているので散らばり幅を調整する必要があります。
散らばり幅を調整する
点同士の散らばり幅の調整は、cexを使います。
geom_point()を使うか、geom_beeswarm()を使うかはどちらでもOKです。
# 以下、どちらも同じグラフになります
g +
geom_point(aes(color = Species),
position = position_beeswarm(cex = 1.6),
shape = 21,
show.legend = FALSE)
g + geom_beeswarm(aes(color = Species),
cex = 1.6,
shape = 21,
show.legend = FALSE)
cexの値をどれくらいにするかはグラフによって変わりますので調整必須です。
プロットが重ならないようにしたい場合
点同士が完全に重ならないようにしたい場合は、ggbeeswarmパッケージのgeom_quasirandom()を使用します。
g +
geom_quasirandom(aes(color = Species),
width = 0.2,
method = "smiley",
show.legend = FALSE)
・width:散らばり幅を調節する
・method = "smiley" : 口角の上がったスマイルのような並び方にする
widthの設定をしないと点同士の幅が広がりすぎてしまうため、widthの設定はした方がいいです。また、methodには、"smiley"の他にも以下の設定ができます。
◆ methodの種類
“quasirandom”, “pseudorandom”, “smiley”, “maxout”, “frowney”, “minout”, “tukey”, “tukeyDense”
frowneyでは、smileとは逆に口角が下がったような並び方になります。そのほかいろいろありますが、quasirandom(デフォルト)かsmileyでいいと思います。
棒グラフにプロットとエラーバーを同時に入れる方法
ここでは下のグラフのような、棒グラフにプロットとエラーバーが入った図の書き方について解説します。
以前こんな感じのグラフを作る機会があって英語でググっても出てこなかったので、もしかしたら需要あるかも?と思い書いてみることにしました。段階を分けてご紹介します。
まず、棒グラフを書きます。
後からプロットを隣に入れたいので、position_nudge()で棒グラフをx軸方向にズラしています。
# 棒グラフを作る
g1 <- ggplot(iris,
aes(x = Species,
y = Sepal.Length))+
geom_bar(stat = "summary",
fun = "mean",
fill = "grey80",
color = "black",
width = 0.4,
position = position_nudge(x = -0.4))+
theme_classic(base_size = 14)
g1
次に、stat_summary()でエラーバーを入れます。
エラーバーは棒グラフの中心に来てほしいので、position_nudge()で先ほどの棒グラフと同じ位置に入れます。
# 棒グラフにエラーバーをつける
g2 <- g1 +
stat_summary(geom = "errorbar",
fun.data = "mean_sd",
width = 0.1,
position = position_nudge(x = -0.4))
g2
次にgeom_beeswarm()でプロットを入れます。
ここまでで棒グラフ、エラーバー、プロットは揃いました。
# 個別プロットを入れる
g3 <- g2 +
geom_beeswarm(aes(color = Species,
fill = Species),
size = 1,
shape = 21,
fill = "white",
cex = 1,
show.legend = FALSE)
g3
次に見た目の違和感を無くしていきます。
scale_x_discrete()を使って、グラフを真ん中に寄せます。
# グラフ全体を真ん中に寄せる
g4 <- g3 +
scale_x_discrete(expand = expansion(add = c(0.8, 0.2)))
g4
引数expandについて
expandでは軸の拡張ができます。
ggplot2でグラフを書くと、離散値の場合はx軸の値に対して0.6単位分、連続値の場合は5%分だけ軸が拡張されています。expandでは、この拡張の調節ができます(下図の赤矢印部分)。
今回の場合、setosaの左側の間隔を広げてvirginicaの右側は狭くしたいので、それぞれ0.8、0.2としています。
次に、theme()を使って水準名(setosaとか)の位置を棒グラフとプロットの間に移動させます。
ついでに目盛り線も消します。
# 水準名の位置を移動 & 軸目盛りを消す
g5 <- g4 +
theme(axis.text.x = element_text(hjust = 1.1,
size = 12),
axis.ticks.x = element_blank())
g5
最後に、scale_y_continuous()で棒グラフの下部をx軸にくっつけます。ggplot2の棒グラフってなぜか棒が浮いているんですよね…
また、y軸の目盛り調整をします。
# 棒グラフの下部をx軸にくっつける
g6 <- g5 +
scale_y_continuous(expand = c(0, 0),
breaks = seq(0, 8, by = 1),
limits = c(0, 8),
labels = scales::number_format(accuracy = 0.1))
g6
・expand:軸の拡張の調節。0にすることで拡張しない設定にする
・breaks:目盛りの設定。0から8まで目盛り線をつけて、間隔は1にする
・limits : y軸の最小/最大の設定
・labels : 目盛りの単位を小数点以下第1位に設定。
これで完成です!
もっと簡単な方法がある場合はtwitter(@kanisanblog)に連絡をいただけると喜びます!
まとめ:棒グラフにプロットを入れる時はbeeswarmが綺麗
今回は棒グラフにプロットを入れる方法について解説しました。
Rのggplot2を使った棒グラフの作り方は、これまでに基礎編、エラーバー編、今回のプロット編の3部作で紹介しましたので、一通りの棒グラフは書けるようになれるのではないでしょうか。
今後また書きたい内容が出てきたら書きます!
R言語の勉強におすすめの本
今後Rの勉強をしていきたい!という方に、こちらの参考書がおすすめです。
特に、RユーザのためのRStudio実践入門は、tidyverseパッケージに特化して書かれていてとても実用的でしたのでオススメです。私自身、この本を読んでRで出来ることが一気に増えた実感のある本です。kindleで試し読みもできるのでぜひ参考にしてください。