Edited at

データサイエンスの可視化 #3 Unit 2: ggplot2の導入とプロットの作り方[MOOC/edX]

edXの「Data Science: Visualization(データサイエンスの可視化)」をまとめています。

前回の記事←→次回の記事


Unit 2 - 1. ggplot2の基礎


ggplot2とは?


  • Rで可視化するためのパッケージ

  • dplyrというのを使って、tidyverseライブラリ経由で読み込む

  • 実はRはデフォルトで十分な描画機能を持っていたり、他のライブラリがあったりするが、ggplot2は文法が簡単で高機能で初心者でも扱いやすいためおすすめ


データを可視化するときの構成要素


  1. データ

  2. グラフの形状(散布図、q-qプロット、棒グラフ、密度プロット、箱ひげ図、ヒストグラム、...)

  3. x軸、y軸、データラベル、データプロットの色、...

  4. x軸とy軸の範囲(スケール)

  5. ラベル、タイトル、凡例、...


ggplot2オブジェクトの宣言の仕方


ggplot2オブジェクトの宣言

p <- ggplot(data = murders) # murdersというデータセットを読み込んでggplotで描画する設定



Unit 2 - 2. プロットのカスタマイズ

順を追って説明していきます。全てをまとめたものだけ見たい方はこちら


2.1 レイヤ

グラフの形状、データを要約した値などを計算するために加えられる要素。こんな感じで+を使って列挙していく。


ggplotでのレイヤの文法

data %>% ggplot() + LAYER1 + LAYER2 + ... + LAYERN


%>%(パイプ演算子)は、「左を右の関数の引数に渡す」という意味。この例だと、dataggolot()の引数として渡す。


基本のレイヤ

(1) geom_グラフの名前() : グラフの形状を定める。

(2) aes() : データをグラフに紐づける。aestheticなマッピングを簡単に定義できる。

散布図(geom_point()を使う)だとこんな感じ。


ggplotの基本の描画の形

# data %>% ggplot() + LAYER1 + LAYER2 + ... + LAYERN

murders %>% ggplot() + geom_point(aes(x = population/10^6), y = total)
# または先にggplotオブジェクトを別で宣言してもいい
p <- ggplot(data = murders)
p + geom_point(aes(popuration/10^6, total))

基本のグラフはこんな感じ(講義動画のスクショなので先生とか映っててごめんなさい)。

Screen Shot 2018-10-28 at 10.47.30.png

なお次の例から、p <- ggplot(data = murders)を省略した抜粋を記載します。


2.2 見た目を調整する


データの点とラベル

(3) geom_label() : データラベルをつける(文字が四角で囲まれる)。

(4) geom_text() : データラベルをつける(文字だけ)。


データラベル

p + geom_point(aes(popuration/10^6, total))

+ geom_text(aes(popuration/10^6, total, label = abb)) # データラベルとしてテキストを付加するためのabb(abbreviation)。

Screen Shot 2018-10-28 at 11.06.35.png

(5) size = : プロットのサイズを変える。


サイズ

p + geom_point(aes(popuration/10^6, total), size = 3)

+ geom_text(aes(popuration/10^6, total, label = abb))

Screen Shot 2018-10-28 at 11.03.37.png

(6) nudge_x= : ラベルをちょっとずらす。


ラベルをずらす

p + geom_point(aes(popuration/10^6, total), size = 3) + 

+ geom_text(aes(popuration/10^6, total, label = abb), nudge_x = 1.5)

なお、popuration/10^6, total, label = abbの部分が何回も出てきて鬱陶しいので、pの定義をこんな感じにすることで、コードをシンプルにできる。


コードをシンプルに書き直す

# 前に出てきた

# murders %>% ggplot() + geom_point(aes(x = population/10^6), y = total)
# と
# p <- ggplot(data = murders)
# を合わせた感じ
p <- murders %>% ggplot(aes(population/10^6, label = abb))
p + geom_point(size = 3)
+ geom_text(nudge_x = 1.5)

Screen Shot 2018-10-28 at 11.04.12.png


(7) scale_x_ continuous() : 軸のスケールを変更する。


スケール

p <- murders %>% ggplot(aes(population/10^6, label = abb))

p + geom_point(size = 3)
+ geom_text(nudge_x = 0.05) # logにするのでラベルと点の間は小さく指定する
+ scale_x_continuous(trans = "log10") # 常用対数がよく使われるので、scale_x_log10というのも特別に用意されてる
+ scale_y_continuous(trans = "log10") # scale_y_log10と書いても同じ

IMG_0058.PNG

両軸が対数表示になる。

(8) xlab()、(9) ylab()、(10) ggtitle(): 軸の名前、タイトルを変更する


軸の名前、タイトル

p <- murders %>% ggplot(aes(population/10^6, label = abb))

p + geom_point(size = 3)
+ geom_text(nudge_x = 0.05)
+ scale_x_log10
+ scale_y_log10
+ xlab("Populations in millions (log scale)")
+ ylab("Total number of murders (log scale)")
+ ggtitle("US Gun Murders in US 2010")

IMG_0059.PNG

(11) aes(col= ) : プロットの色を変える。凡例は自動的に追加される。

IMG_0055.PNG


データの要約を加える


データの要約を計算

r <- murders %<% + summarize(rate = sum(total) / sum(population) * 10^6) %>% .$rare


(↑詳細説明なし、よく分かってない、要確認)

(12) geom_abline() : 回帰直線を加える(デフォルトでは傾き1、雪片0の直線)。


回帰直線

p + gepm_point(aes(col=region), size = 3) + geom_abline(intercept = log10(r))


IMG_0056.PNG

ついでに直線のタイプを変える(13) lty=、(14) color=も加えるとこんな感じ。


回帰直線

p <- p + geom_abline(intercept = log10(r), lty = 2, color = "darkgrey")

+ gepm_point(aes(col=region), size = 3)

IMG_0057.PNG

おまけ

(15) scale_color_discrete() : 凡例の"region"を"Region"にする


おまけ

p <- p + scale_color_discrete(name = "Region")



パッケージを使って見栄えを整える

(16) ggthemes : グラフ描画の全体的なスタイルを変えるライブラリ。(17) theme_fivethityeight()、(18) theme_economistとか色々な種類がある。

(19) ds_theme_set() : ggthemesライブラリの中で、使いやすい多くのテーマを提供しているパッケージ。今回は使わないけど、今後はめっちゃ使うとのこと。

theme_economistの指定の仕方はこんな感じ。


スタイルを変える

library(ggthemes)

p + theme_economist() + ... # (描画のための他のレイヤ)

IMG_0060.PNG

おまけ

(20) ggrepel : 文字と点が重ならないようにデータラベルを追加するライブラリ。


これまでのまとめ


まとめ

> library(ggthemes) # グラフの全体的なスタイル(レイアウトとか)を変えるライブラリ

> library(ggrepel) # 文字と点が重ならないようにデータラベルを追加するライブラリ
> ### 傾きの計算と回帰直線の定義
> r <- murders %>% summarize(rate = sum(total) / sum(population) * 10^6) %>% .$rate
> ### プロット描画
> murders %>% ggplot(aes(population/10^6, total, label = abb))
+ geom_abline(intercept = log10(r), lty = 2, color = "darkgrey")
+ geom_point(aes(col=region), size = 3)
+ geom_text_repel() # geom_textの代わりにrepelライブラリを使ってデータラベル追加
+ scale_x_log10()
+ scale_y_log10()
+ xlab("Populations in millions (log scale)")
+ ylab("Total number of murders (log scale)")
+ ggtitle("US Gun Murders in US 2010")
+ scale_color_discrete(name = "Region")
+ theme_economist() # ggthemesライブラリの中から好みのスタイルを指定する

IMG_0062.PNG


2.3 他の例


ヒストグラムと密度プロット


ヒストグラムと密度プロット

# ヒストグラム

p <- heights %>% filter(sex == "Male") %>% ggplot(aes(x = height)) # ヒストグラムにはxしか必要ない
p + geom_histgram(binwidth = 1, fill ~ "blue", col = "black") # binを定義してあげないとwarningが出る
+ xlab("Male heights in inches")
+ ggtitle("Histgram")

# 密度プロット
p <- geom_density(fill = "blue")


IMG_0065.PNG


q-qプロット


q-qプロット

# 平均0、sd1の正規分布に従ったグラフ

p <- heights %>% filter(sex == "Male") %>% ggplot(aes(sample = height)) # qqプロットの引数はxではなくsampleと指定する
p + geom_qq() # 平均0、sd1の分布に従ったグラフが描画される

# データから求めた平均、sdの正規分布に従ったq-qプロット(dparams=オプションを使う)
params <- heights %>% filter(sex == "Male") %>% summarize(mean = mean(height), sd = sd(height))
p + geom_qq(dparams = params) # データの平均、sdに従ったグラフが描画される

# 正規分布に従ったq-qプロット
p <- heights %>% filter(sex == "Male") %>% ggplot(aes(sample = scale(height)))
p + geom_qq()
+ geom_abline() # ついでに近似直線を描画


標準正規分布に従ったq-qプロット(一番下の例)はこんな感じ。

Screen Shot 2018-10-28 at 12.41.00.png

(21) grid.arrange : 複数のグラフをまとめて描画する。


複数のグラフをまとめて描画する

> p <- heights %>% filter(sex == "Male") %>% + ggplot(aes(x = height))

> p1 <- p + geom_histgram(binwidth = 1, fill = "blue", col = "black")
> p2 <- p + geom_histgram(binwidth = 2, fill = "blue", col = "black")
> p3 <- p + geom_histgram(binwidth = 3, fill = "blue", col = "black")
> library(gridExtra)
> grid.arrange(p1,p3,p4, ncol = 3)

IMG_0063.PNG


今後の予定

随時リンク追加予定

(いつか)まとめる予定の講座の記事一覧