これで描ける！そういうことかggplot2！！

# はじめに

　こんにちは！データサイエンス系オタク会社員のroadricefieldです！今日はggplot2のお話です．  

　世はDX（デジタルトランスフォーメーション）大戦国時代！アカデミアのあなたも，企業研究者のあなたも，営業のあなたも，マーケティングのあなたも，家計簿をつける主婦のあなたも，高校生のあなたも，そこの社長さんも！データをグラフにして可視化する機会はたくさんあるのではないでしょうか？  

　グラフを描くツールとしてはExcelが便利です．プログラミングをしなくても使えるし，工夫をすればきれいなグラフを誰でもかんたんに描くことができます．しかも最近の義務教育ではExcelの使い方は授業で教えてもらえるのではないでしょうか．  

　Excelは確かに便利です．しかし，以下のような困りごとはありませんか？  

- **マウスでいろんなボタンをポチポチクリックするのは大変！時間がかかる！**
- **同じグラフを違うデータでたくさん描きたいけどコピペ作業が大変！**  

上記のようなお悩みを抱えているそこの**あなた**！ぜひ，この記事を読んで**ggplot2**という素晴らしい武器を身に着けて**きれいなグラフを素早く，効率的に描けるようになりましょう！！**  

# この記事はどんな人向け？  

　この記事は以下の方々に向けて書きます．  

- **きれいなグラフを素早く，効率的に描きたい方**
- **プログラミング言語Rをある程度使えてデータの解析を始めたい方**
- **ggplot2の存在は知っているけどなんだか使いこなせていない方**

なお，プログラミングの経験がない方は[こちら](https://qiita.com/roadricefield/items/001c882f84dd093f4407)の記事でパパっとRというプログラミング言語を習得してください．ggplot2はR用のツールです． 

# サンプルデータの置き場所  

　この記事で使用する表データとスクリプトはすべて[こちら](https://github.com/roadricefield/Qiita_ggplot2_-)に置きましたので必要に応じてダウンロードしてください． 

# レベル1  とにかくプロット！

　早速以下のデータを使ってグラフを描いていきますよ！　　

| day | time |
|-----|------|
| 1   | 156  |
| 2   | 109  |
| 3   | 92   |
| 4   | 113  |
| 5   | 39   |
| 6   | 13   |
| 7   | 66   |

このデータは何でしょう？そうですね，僕がある一週間で[ウマ娘プリティーダービー](https://umamusume.jp/)をプレイした時間（単位: 分）ですね！横軸に日を，縦軸にプレイ時間を取った折れ線グラフをggplot2で描くには以下のようなスクリプトになります．

```R
library(ggplot2)

df <- read.csv("https://github.com/roadricefield/Qiita_ggplot2_-/raw/main/level1.csv")

g <- ggplot(df, aes(x = day, y = time)) + #グラフオブジェクト
     geom_line()

plot(g) #作ったグラフを画面に表示

ggsave(plot = g, file = "level1.png", w = 3.1, h = 2.4, dpi = 600) #pngでグラフを保存
```  

![level1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/26b249cc-ffd7-4ac1-bd8d-db48681e6e16.png)

　ちょっと見た目があれですがレベル2で一気に改善するのでここではggplot2の基本のキを説明しますね．  

　一番大事なのは`ggplot(データ, aes(x = x軸に取りたいデータの列名, y = y軸に取りたいデータの列名))`です！この`ggplot()`がプロットするデータの形式を指定するものです．今回は僕のある一週間で[ウマ娘プリティーダービー](https://umamusume.jp/)をプレイした時間のデータを変数`df`に格納しました．これはデータフレームとなっており，日付が`day`列に，プレイ時間が`time`列に格納されています．データ`df`を使ってx軸に`day`，y軸に`time`を取るグラフを作成するので`ggplot(df, aes(x = day, y = time))`となります．  

　`ggplot()`を作っただけではまだデータの形式を指定しただけで折れ線グラフを描くのか，棒グラフを描くのか，はたまた円グラフを描くのかは指定できていません．今回は折れ線グラフを描きたかったです．それを指定するのが`geom_line()`の部分です．これを`ggplot()`での指定に*足し算*で付け加えます．するとggplotは**「`df`というデータの中の`day`をx軸，`time`をy軸に取って折れ線グラフ（`geom_line()`）を作成ですね」**と理解してグラフをプロットしてくれます．  

　ということで例えば`ggplot(df, aes(x = time, y = day))`とすればx軸とy軸が入れ替わります．  

# レベル2 グラフをカッコよくしよう！  

　先程レベル1でプロットしたグラフはダサいのでこれをもっとかっこよくしていきましょう．ここで大事なことを言います（書きます）．よく聞いて（読んで）くださいね．  

**ggplot要素を足し算**  

**ggplot要素を足し算**  

```R
while(1) print("ggplot要素を足し算")  
```  
大事なことなので無限に言いました（出力しました）．  

## 軸ラベルを変える  

　まずは軸ラベルを変更しましょう．`df`の列名を変更しても良いのですがここでは**軸ラベルという要素を足し算**します．  

```R
g <- ggplot(df, aes(x = day, y = time)) +
     geom_line() +
     xlab("Date") + #x軸の軸ラベルを指定
     ylab("Play time (min)") #y軸の軸ラベルを指定 
```  

![level1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/1798e147-cbe8-92bd-1dc1-735ee8b05c2c.png)

x軸，y軸のラベルを指定する要素はそれぞれ`xlab()`，`ylab()`です．それぞれの括弧の中にラベルにしたい文字を書くだけ！かんたんでしょ？  

## 軸目盛りの間隔を変える  

　今，横軸の目盛りが2, 4, 6となっていますがこれを1から7まで1刻みにしましょう．  

```R  
g <- ggplot(df, aes(x = day, y = time)) +
     geom_line() +
     xlab("Date") +
     ylab("Play time (min)") +
     scale_x_continuous(breaks = seq(1,7,1)) #x軸の目盛り間隔を指定．もちろんbreaks = c(1,2,3,4,5,6,7)
                                             #などでもOK！
```

![level1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/c0398d58-a821-a7a6-dd36-b838d83c8ea4.png)

x軸の目盛りの指定は`scale_x_continuous()`の`breaks`という引数で行います．もちろんy軸の目盛りの指定は`scale_y_continuous()`の`breaks`で行えます．  

## 線の色を変えて点もプロットする  

　どんどん行きます．次は先の色を変えて各日付の位置に点もプロットしましょう．  

```R
g <- ggplot(df, aes(x = day, y = time)) +
     geom_line(color = "royalblue") + #geom_line()のcolor引数に色を指定．
     geom_point(color = "royalblue") + #geom_point()は点を打つ要素．color引数に色を指定．
     xlab("Date") +
     ylab("Play time (min)") +
     scale_x_continuous(breaks = seq(1,7,1))
```  

ちなみにRで使用できる色の名前は[こちら](http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf)．

![level1-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/fefb5761-a90b-5ac3-9f5c-192a693134ff.png)  

## この調子でお好みにカスタマイズする  

```R
g <- ggplot(df, aes(x = day, y = time)) +
     geom_line(color = "royalblue") +
     geom_point(color = "royalblue") +
     xlab("Date") +
     ylab("Play time (min)") +
     scale_x_continuous(breaks = seq(1,7,1)) +
     theme_classic() + #背景を白くして上と右の枠線を描かないようにする要素
     theme(panel.grid = element_blank()) + #背景のグリッド線を消す
     theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15)) #目盛り，軸ラベルの文字の大きさを指定
```
![level1-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/e643fc40-c9e9-093a-eca7-a82fe6ed831d.png)


これで論文クオリティのきれいなグラフになりました．グラフの見た目の細かい調整は`theme()`という要素を足していくことでできます．例えば`theme(panel.grid = element_blank())`の表すところは背景のグリッド線（`panel.grid`）はいらない（`element_blank()`）ということです．`theme(axis.text = element_text(size = 12))`は軸のテキスト，つまり目盛り（`axis.text`）はサイズ12の文字（element_text(size = 12)）にしてくださいということを表します．  

## 軸目盛りとして表示するテキストを変更する  

　現在，x軸の目盛りは1から7まで1ずつの間隔で1~7までの数字は表示されていますがこれを曜日に上書きしてみましょう．  

```R
week <- c("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat") #目盛りに使用する文字のベクトル

g <- ggplot(df, aes(x = day, y = time)) +
     geom_line(color = "royalblue") +
     geom_point(color = "royalblue") +
     scale_x_continuous(breaks = seq(1,7,1), labels = week) + #lables引数に目盛りとして使う文字を指定．
                                                              #1~7まで1ずづの間隔で"Sun"~"Sat"の文字列を軸ラベルに書く．
     xlab("Day") + #曜日なので"Day"としておく．
     ylab("Play time (min)") +
     theme_classic() +
     theme(panel.grid = element_blank()) +
     theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15))
```

![level1-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/051370e6-29f2-0414-e3b0-bc7030304b3a.png)

# レベル3 複数の系統のデータをプロットする

　レベル1とレベル2では以下の僕のウマ娘のプレイ時間だけをプロットしてきました．

| day | time |
|-----|------|
| 1   | 156  |
| 2   | 109  |
| 3   | 92   |
| 4   | 113  |
| 5   | 39   |
| 6   | 13   |
| 7   | 66   |

次はこれに加えて同じ週に僕がTwitterをしていた時間も一緒にプロットしてみましょう．以下がそのデータです．

| day | time |
|-----|------|
| 1   | 94   |
| 2   | 108  |
| 3   | 41   |
| 4   | 105  |
| 5   | 103  |
| 6   | 86   |
| 7   | 124  |

これからこんなグラフを描きましょう！

![level3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/9fa08ce7-f094-3d92-6f4d-9a8b4e761e88.png)

  

　上のグラフでは**x軸で日付**を，**y軸でアプリの起動時間**を表していますね．そして**色でアプリの種類**を表しています．つまり，**色はx軸でもy軸でもない新しい軸**であるという考え方をします．  

　実際にプロットして一緒に考えましょう！まず，ウマ娘とTwitterのデータをあわせて以下のようなデータフレームを作ります．  

| day | time | application |
|-----|------|------|
| 1   | 156  |Umamusume|
| 2   | 109  |Umamusume|
| 3   | 92   |Umamusume|
| 4   | 113  |Umamusume|
| 5   | 39   |Umamusume|
| 6   | 13   |Umamusume|
| 7   | 66   |Umamusume|
| 1   | 94   |Twitter|
| 2   | 108  |Twitter|
| 3   | 41   |Twitter|
| 4   | 105  |Twitter|
| 5   | 103  |Twitter|
| 6   | 86   |Twitter|
| 7   | 124  |Twitter|

　day列をx軸，time列をy軸に取り，**色でapplication列**を表すので`ggplot()`内の`aes()`には`aes(x = day, y = time, color = application)`と書きます．  

```R
df <- read.csv("https://github.com/roadricefield/Qiita_ggplot2_-/raw/main/level3.csv")

g <- ggplot(df, aes(x = day, y = time, color = application)) + #色でapplication列を指定
        geom_line() +
        geom_point() +
        scale_color_manual(values = c("deepskyblue1", "green3")) + #グラフの色を順に指定
        scale_x_continuous(breaks = seq(1,7,1)) +
        xlab("Date") +
        ylab("Time (min)") +
        labs(color = "Application") + #凡例のタイトルを指定．今回は色に関する凡例のタイトルなので
        theme_classic() +             #color = "Application"と指定する必要がある．
        theme(panel.grid = element_blank()) +
        theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15))

plot(g)
```

このスクリプトで上のグラフを描くことができます．`scale_color_manual()`の`values`引数に色をベクトルで指定することでグラフの色を変更できます．ちなみに凡例は`guides(color = F)`と要素を足し算すれば消えます．また，色ではなく点の形と線の種類（`shape`と`lty`）でアプリの種類を表現することもできます．  

```R
g <- ggplot(df, aes(x = day, y = time, shape = application, lty = application)) +
        geom_line() +
        geom_point(size = 2) + #点を少し大きくした．
        scale_x_continuous(breaks = seq(1,7,1)) +
        xlab("Date") +
        ylab("Time (min)") +
        labs(shape = "Application", lty = "Application") + #めんどいがshapeとlty両方で書く必要がある．
        theme_classic() +                                  #書かないとどうなるかは試してみてください．
        theme(panel.grid = element_blank())
        theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15))
```

![level3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/fc982d42-5b03-6f5c-0d3f-f681b729f234.png)


お医者さんの論文でよく見るタイプのグラフになりました．  

## ２つの系統のグラフを分けてプロットするには？  

　`facet_wrap()`という要素を使用します．以下のように書きます．  

```R  

g <- ggplot(df, aes(x = day, y = time, color = application)) +
        geom_line() +
        geom_point() +
        facet_wrap(~application, ncol = 1) + #applicationごとにグラフを分けて縦一列で表示する．
        scale_color_manual(values = c("deepskyblue1", "green3")) + 
        scale_x_continuous(breaks = seq(1,7,1)) +
        xlab("Date") +
        ylab("Time (min)") +
        theme_bw() + #theme_classic() -> theme_bw()
        theme(panel.grid = element_blank()) +
        theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15)) +
        guides(color = F) + #これを書かないと各colorがどのapplicationを指すのかを示す凡例が残ってしまいます．
        theme(strip.background = element_blank(), strip.text = element_text(size = 15)) #下記で説明．

```  

![level3-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/af4cef2b-8abe-1176-a19e-f7855a5fe500.png)


`facet_wrap()`ではグラフの分割に使用するデータのデータフレームの上の列名を`~`（チルダ）をつけて指定します．`ncol`，`nrow`引数で分割したグラフを表示するときの列数，行数をそれぞれ指定できます．ちなみに`facet_wrap(~application, ncol = 1, scales = "free_y")`とするとy軸の目盛りを分割後それぞれのグラフに合わせて調整してくれます．`theme_classic()` -> `theme_bw()`としたのには理由があります．ためしに`theme_classic()`に戻してみてください．軸に関して困ったことが起こります．最後に追記した`theme()`の`strip.background`と`strip.text`は分割したグラフのタイトル（今回は"Twitter"と"Umamusume"）に関する要素です．これを消したりしていじってみてください．

# レベル4 棒グラフ  

　レベル4では棒グラフを例にggplotの設定方法をお伝えします．使うデータは以下です．  

| Subject | Average | SD |
|-----|------|------|
| Mathematics IA   | 51.88  |18.43|
| Mathematics IIB   | 49.03  |22.63|
| Chemistry   | 54.79   |22.59|
| Physics   | 60.68  |21.64|
| Biology   | 57.56   |20.06|
| Earth science   | 39.51   |17.69|

このデータは令和2年度大学入試センター試験の理系科目の受験者平均点と標準偏差です．（[出典](https://www.dnc.ac.jp/albums/abm.php?f=abm00038210.pdf&n=%E5%88%A5%E6%B7%BB2_%E5%AE%9F%E6%96%BD%E7%B5%90%E6%9E%9C%E3%81%AE%E6%A6%82%E8%A6%81.pdf)）  

## とりあえず棒グラフをプロット  

　棒グラフは`geom_bar()`という要素で描きます．とりあえず描いてみましょう．  

```R
df <- read.csv("https://github.com/roadricefield/Qiita_ggplot2_-/raw/main/level4.csv")

g <- ggplot(df, aes(x = Subject, y = Average)) +
        geom_bar(stat = "identity") + #stat = "identity"はおまじないです．
        theme_classic() +
        theme(panel.grid = element_blank()) +
        theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15))

plot(g)
```

![level4-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/1c7fb237-9a43-3109-db21-4a997e9e9564.png)

　ひどい......折れ線グラフと同様にきれいにしていきたいですが実は棒グラフは色々とややこしいです．それではひとつひとつ直していきましょう！  

## 横軸のラベルの角度を変更する  

　今のままでは横軸のラベルが重なってしまっているのでこれを回転させましょう．軸ラベルの回転には`theme()`の`element_text()`の`angle`という引数を使用します．  

```R

g <- ggplot(df, aes(x = Subject, y = Average)) +
        geom_bar(stat = "identity") +
        theme_classic() +
        theme(panel.grid = element_blank()) +
        theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15)) +
        theme(axis.title.x = element_blank()) + #"Subject"は消しちゃう．
        theme(axis.text.x = element_text(angle = 30, hjust = 1, size = 15)) #横軸のテキスト（axis.text.x）を30度回転させて
                                                                            #ついでに文字の大きさを15 ptに変更する．

```  

![level4-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/4de19fbf-ebef-a152-fdd2-43d495404b6e.png)

　これで科目名が読めるようになりました．`hjust`引数や`vjust`引数でラベルの位置を上下左右に微調整できます．基本的には`hjust = 1`としておけば間違いないでしょう．    

## 標準偏差をエラーバーで表示する  

　実験結果を示すグラフを描く際はエラーバーを表示しなければならないでしょう．この棒グラフに各科目の標準偏差をエラーバーで表示してみましょう（テストの点数の標準偏差の可視化として適切ではありませんが......）．エラーバーを表示する要素は`geom_errorbar()`です．今回の場合以下のように書きます．  

```R

g <- ggplot(df, aes(x = Subject, y = Average)) +
        geom_bar(stat = "identity") +
        theme_classic() +
        geom_errorbar(aes(ymin = Average - SD, ymax = Average + SD), width = 0.3) + #これ！！！！！！！！！！！！！！！！
        theme(panel.grid = element_blank()) +
        theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15)) +
        theme(axis.title.x = element_blank()) +
        theme(axis.text.x = element_text(angle = 30, hjust = 1, size = 15))

```  

![level4-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/5657a03d-b865-39bd-1407-8ad5049b6ca6.png)  

`geom_errorbar()`も`aes()`を指定します．縦軸のエラーバーを作成するのでエラーバーの下端`ymin`を`Average - SD`，上端`ymax`を`Average + SD`とします．`width`はエラーバー自体の横幅です．指定しないとデフォルトの1が適用されて棒グラフ本体の横幅と同じ幅となりかなりダサいです．  


　各科目のエラーバー，標準偏差はほぼ同じであり，特定の科目のみが「差が付きやすい」試験だったということはなかったようです．受験生はこれらの教科からいくつか選択して受けるので科目ごとの標準偏差が大きく異なるようでは不公平になりますよね．地学を除けば平均点もほぼ横並び，センター試験，すごいです．  

## 項目の表示順を変更する  

　あれ？そういえば科目の表示順が変わっていませんか？もう一度もとデータを見てみましょう．  

| Subject | Average | SD |
|-----|------|------|
| Mathematics IA   | 51.88  |18.43|
| Mathematics IIB   | 49.03  |22.63|
| Chemistry   | 54.79   |22.59|
| Physics   | 60.68  |21.64|
| Biology   | 57.56   |20.06|
| Earth science   | 39.51   |17.69|  

次に今のグラフを見てみましょう．  

![level4-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/a0a90fac-32fd-4b11-4223-ff842ad2f89c.png)

**もしかして，横軸ラベルが，辞書順に，入れ替わってるぅ～～～～～～！！！？？？**  

なんたるありがた迷惑！実はggplotには指定をしない限りグラフの軸ラベルを辞書順に並び替えて表示してしまう悪い癖があるようです．これを防ぐためには予め順番を指定しておく必要があります．これには順番の情報を保持したデータ型であるfactor型を使用します．以下のように書きます．  

```R  

df$Subject <- factor(df$Subject, levels = c("Mathematics IA", "Mathematics IIB", 
                                            "Chemistry", "Physics", "Biology", "Earth science")) #これ！！！！！！！！！！！！！！！！！！！

g <- ggplot(df, aes(x = Subject, y = Average)) +
        geom_bar(stat = "identity") +
        theme_classic() +
        geom_errorbar(aes(ymin = Average - SD, ymax = Average + SD), width = 0.3)+
        theme(panel.grid = element_blank()) +
        theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15)) +
        theme(axis.title.x = element_blank()) +
        theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 15)) #角度を45度に変更しました．

```

![level4-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/98974e94-83da-0e7c-b749-340542dc67ff.png)

`factor()`関数の１つ目の引数に順番を指定したい文字列のベクトル（今回は`df$Subject`）を指定します．そして`levels`引数に順番を直接ベクトルで入力することで指定します．ここに指定した順でグラフに表示されるようになります．（今回の場合は`df$Subject <- factor(df$Subject, levels = df$Subject)`でもOKですね．)  


##  棒グラフに色をつける  

　灰色のグラフは見苦しいですね．色をつけましょう．それぞれの科目っぽい色を指定してみましょう．  

```R  


df$Subject <- factor(df$Subject, levels = c("Mathematics IA", "Mathematics IIB", 
                                            "Chemistry", "Physics", "Biology", "Earth science"))

g <- ggplot(df, aes(x = Subject, y = Average, color = Subject)) +
        geom_bar(stat = "identity") +
        theme_classic() +
        geom_errorbar(aes(ymin = Average - SD, ymax = Average + SD), width = 0.3) +
        scale_color_manual(values = c("deepskyblue1", "royalblue", "purple", "red",
                                      "seagreen", "saddlebrown")) +
        theme(panel.grid = element_blank()) +
        theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15)) +
        theme(axis.title.x = element_blank()) +
        theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 15))

```  

![level4-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/b6a4f91c-5bbe-ba26-7fff-746a7e30e0a9.png)



**あれ？？なんか思ってたのと違う......**  

　実はggplotでは棒グラフの外枠線を`color`で，塗りつぶしの色を`fill`という別の引数で指定することになっています．また，余計な凡例も出ていたりするのでそこのところを以下のように調整します．  

```R  

df$Subject <- factor(df$Subject, levels = c("Mathematics IA", "Mathematics IIB", 
                                            "Chemistry", "Physics", "Biology", "Earth science"))

g <- ggplot(df, aes(x = Subject, y = Average, fill = Subject)) + #color = Subject -> fill = Subject
        geom_bar(stat = "identity") +
        theme_classic() +
        geom_errorbar(aes(ymin = Average - SD, ymax = Average + SD), width = 0.3) +
        scale_fill_manual(values = c("deepskyblue1", "royalblue", "violet", "tomato1", #scale_color_manual() -> scale_fill_manual()
                                      "springgreen1", "tan3")) +
        theme(panel.grid = element_blank()) +
        theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15)) +
        theme(axis.title.x = element_blank()) +
        theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 15)) +
        guides(fill = F) #これを書かないと各fillの色がどの科目かを示す凡例が出てしまう．

```

![level4-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/e2ec68c3-154f-6a29-a037-a0ba517e2b4f.png)  

いい感じになりましたね．

## 軸の範囲や目盛り間隔を変更する  

　テストは100点満点なので縦軸の範囲を0~100点にしてみましょう．横軸の範囲設定は`xlim()`，縦軸は`ylim()`で行います．  

```R
g <- ggplot(df, aes(x = Subject, y = Average, fill = Subject)) + 
        geom_bar(stat = "identity") +
        theme_classic() +
        geom_errorbar(aes(ymin = Average - SD, ymax = Average + SD), width = 0.3) + 
        scale_fill_manual(values = c("deepskyblue1", "royalblue", "violet", "tomato1", 
                                     "springgreen1", "tan3")) +
        theme(panel.grid = element_blank()) +
        theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15)) +
        theme(axis.title.x = element_blank()) +
        theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 15)) +
        guides(fill = F) +
        ylim(c(0,100)) #これ！！！！！！！！！！！！！！！！！！！！

plot(g)
```  

![level4-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/b7fe6b77-4847-a5c6-2c6e-58fd429f0154.png)  

　縦軸の間隔を20点ずつに変更してみましょう．先程も登場しましたが`scale_x_continuous`や`scale_y_continuous`で設定します．  

```R
g <- ggplot(df, aes(x = Subject, y = Average, fill = Subject)) + 
        geom_bar(stat = "identity") +
        theme_classic() +
        geom_errorbar(aes(ymin = Average - SD, ymax = Average + SD), width = 0.3) + 
        scale_fill_manual(values = c("deepskyblue1", "royalblue", "violet", "tomato1", 
                                     "springgreen1", "tan3")) +
        theme(panel.grid = element_blank()) +
        theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15)) +
        theme(axis.title.x = element_blank()) +
        theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 15)) +
        guides(fill = F) +
        scale_y_continuous(breaks = seq(0,100,20), limits = c(0,100)) #これ！！！！！！！！！！！！

plot(g)
```  

![level4-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/d61c7edc-8d34-73f5-40fb-a1ea4555bcf2.png)  

`scale_y_continuous`の`breaks`引数に間隔としたいベクトルを指定します．そして`limits`に軸の範囲を設定します．このとき先程の`ylim()`を残しているとエラーを吐かれてしまいます．また，`limits`を指定しないと軸の範囲が勝手に調整されてしまいますので注意です．  

# その他のグラフ  

　ここまでで概ねggplotの設定の仕方について説明しました．ここではその他のよくプロットするグラフを描くためのサンプルプログラムをおいておきます．データはデータサイエンス界隈ではおなじみの`iris`というRにすでに入っているものを使いましょう．3種類のアヤメの花の花びらとがくの長さと幅のデータです．各種類50個ずつの花のデータが収録されています．Rでは`iris`という変数にすでに格納されているのでいきなり呼び出すことができます．以下にirisの頭だけ表示します．  

|Sepal.Length|Sepal.Width|Petal.Length|Petal.Width|Species|
|:----|:----|:----|:----|:----|
|5.1|3.5|1.4|0.2|setosa|
|4.9|3|1.4|0.2|setosa|
|4.7|3.2|1.3|0.2|setosa|
|4.6|3.1|1.5|0.2|setosa|
|5|3.6|1.4|0.2|setosa|
|5.4|3.9|1.7|0.4|setosa|
|4.6|3.4|1.4|0.3|setosa|  

  

## 箱ひげ図  

　`geom_boxplot()`を使用します．  


```R
g <- ggplot(iris, aes(x = Species, y = Sepal.Width, fill = Species)) +
        geom_boxplot() +
        theme_classic() +
        theme(axis.title.x = element_blank(), axis.title.y = element_text(size = 15)) +
        theme(axis.text = element_text(size = 15)) +
        guides(fill = F) +
        ylab("Sepal width")
plot(g)
```  

![boxplot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/11ac44ae-2a26-954e-b0b9-5782266dbd88.png)

## ヒストグラム  

　`geom_histogram()`を使用します．

```R  
g <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
        geom_histogram(position = "identity", alpha = 0.8) + #alphaは色の透過度．0~1で設定．
        theme_classic() +
        theme(axis.title.y = element_text(size = 15), axis.title.x = element_text(size = 15)) +
        theme(axis.text = element_text(size = 15)) +
        xlab("Sepal width") +
        ylab("Count") +
        scale_y_continuous(breaks = seq(0,10,2), limits = c(0,10))
plot(g)
```  

![histgram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/409c50db-fa14-1fb9-2936-aca5c88cbfab.png)

binの数はgeom_histogram()の`bins`で変えられます．デフォルトは30です．  

```R
g <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
        geom_histogram(position = "identity", alpha = 0.8, bins = 10) + #bins = 10
        theme_classic() +
        theme(axis.title.y = element_text(size = 15), axis.title.x = element_text(size = 15)) +
        theme(axis.text = element_text(size = 15)) +
        xlab("Sepal width") +
        ylab("Count")
plot(g)
```  

![histgram3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/0ac921f8-e7a7-7841-08b3-7435dacdf554.png)

**注意！！** `geom_histogram()`に`position = "identity"`をしてしないと以下のような積み上げ式グラフになってしまいます．  

```R
g <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
        geom_histogram(alpha = 0.8, color = "black") +
        theme_classic() +
        theme(axis.title.y = element_text(size = 15), axis.title.x = element_text(size = 15)) +
        theme(axis.text = element_text(size = 15)) +
        xlab("Sepal width") +
        ylab("Count")
plot(g)
```  

![histgram2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/1464b90d-41ec-1e69-e02c-1f5fe4ab431b.png)

気づきにくいミスなので本当に注意してください．  

## 確率密度曲線  

　`geom_density()`を使用します．  

```R  
g <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
        geom_density() + 
        facet_wrap(~Species, ncol = 1) +
        theme_classic() +
        theme(axis.title.y = element_text(size = 15), axis.title.x = element_text(size = 15)) +
        theme(axis.text = element_text(size = 15)) +
        xlab("Sepal width") +
        ylab("Density") +
        guides(fill = F) +
        theme(strip.background = element_blank(), strip.text = element_text(size = 15))
plot(g)
```  

![density.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/f9462ee6-1428-0ff7-f8d9-3e07c04793ca.png)
 

`facet_wrap()`を使って種ごとに分けてプロットしてみました．  

# 実務的なサンプルプログラム  

　最後にggplotを使用して大量のデータの可視化を自動化するなど実務的なサンプルプログラムを書いてみます．ぜひ参考にしてみてくださいね．また，実際に動かすとプログラミングで業務の自動化をすることの感動を体験できると思います．

## 表データの項目別可視化
　[Breast Cancer Wisconsin (Diagnostic) Data Set](https://archive.ics.uci.edu/ml/datasets/breast+cancer+wisconsin+(diagnostic))をお借りします．このデータは良性腫瘍と悪性腫瘍のがん細胞の核の形の特徴量のデータです．1列目に検体のID，2列目に良性腫瘍か悪性腫瘍かのラベル（"B" = 良性腫瘍，"M" = 悪性腫瘍），3列目以降に特徴量が格納されています．10種類の特徴量について平均値，標準誤差，最大値が順番に格納されていて計30列の項目があります．  
　以下のサンプルプログラムではこのデータから10種類の特徴量の平均値のみを取り出し，良性腫瘍群と悪性腫瘍群の分布をバイオリンプロットで可視化します．さらに各群での平均値をひし形の点で表示します．forループを使って10個のグラフを一気に出力します．  

```R
library(ggplot2)

data <- read.csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data",
                 header = F)

attri <- c("ID", "Diagnosis", "Radius", "Texture", "Perimeter", "Area", "Smoothness",
           "Compactness", "Concavity", "Concave_points", "Symmetry", "Fractal_dimension")

ext_data <- data[,c(1, 2, seq(3, 30, 3))]

colnames(ext_data) <- attri

ext_data_mean <- data.frame(Diagnosis = c("B", "M"))
B <- which(ext_data$Diagnosis == "B")
M <- which(ext_data$Diagnosis == "M")

for(i in 3:12) ext_data_mean <- cbind(ext_data_mean, c(mean(ext_data[B,i]), mean(ext_data[M,i])))
colnames(ext_data_mean)[2:11] <- colnames(ext_data)[3:12]

for(i in 3:12){
  g <- ggplot(ext_data, aes(x = Diagnosis, y = ext_data[,i], fill = Diagnosis)) +
    geom_violin() +
    theme_classic() +
    theme(axis.title.x = element_blank(), axis.title.y = element_text(size = 15)) +
    theme(axis.text = element_text(size = 15)) +
    guides(fill = F) +
    scale_fill_manual(values = c("royalblue", "firebrick3")) +
    ylab(gsub(x = colnames(ext_data)[i], pattern = "_", replacement = " "))
  
  g <- g +
    geom_point(data = ext_data_mean, aes(x = Diagnosis, y = ext_data_mean[,i-1]), 
               fill = "white", size = 3, shape = 23)
  
  ggsave(plot = g, file = paste0("wdbc_plots/", colnames(ext_data)[i], ".png"), w = 6.2, h = 4.8, dpi = 600)
}
```  

このプログラムを実行すると以下のようなバイオリンプロットが10種類の特徴量に対して一瞬で作成されます（実行するディレクトリの直下にwdbc_plotsという名前の空ディレクトリを作成しておいてください）．  

![Radius.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/e377292d-ba1c-13e3-c2a7-8be95b36097b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/73047c61-b360-4d14-6a08-4517c67eb657.png)  

　このように様々な項目について同じグラフをたくさんつくりたいときはforループを使うのが便利です．  

　ちなみに一つのPDFファイルにまとめたいときは  

```R
pdf("wdbc_plots.pdf", w = 6.2, h = 4.8) #PDFファイルを開く．
for(i in 3:12){
  g <- ggplot(ext_data, aes(x = Diagnosis, y = ext_data[,i], fill = Diagnosis)) +
    geom_violin() +
    theme_classic() +
    theme(axis.title.x = element_blank(), axis.title.y = element_text(size = 15)) +
    theme(axis.text = element_text(size = 15)) +
    guides(fill = F) +
    scale_fill_manual(values = c("royalblue", "firebrick3")) +
    ylab(gsub(x = colnames(ext_data)[i], pattern = "_", replacement = " "))
  
  g <- g +
    geom_point(data = ext_data_mean, aes(x = Diagnosis, y = ext_data_mean[,i-1]), 
               fill = "white", size = 3, shape = 23)

  plot(g) #開いたPDFファイル内にプロットしていく．
}
dev.off() #PDFファイルを閉じる．
```

とすると作成できます．  

さらに上級テクですが`apply()`などを使ってもっとスタイリッシュに書くこともできます！！  

```R
library(tidyverse)

data <- read.csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data",
                 header = F)

attri <- c("ID", "Diagnosis", "Radius", "Texture", "Perimeter", "Area", "Smoothness",
           "Compactness", "Concavity", "Concave_points", "Symmetry", "Fractal_dimension")

ext_data <- data[,c(1, 2, seq(3, 30, 3))]

colnames(ext_data) <- attri

ext_data_mean <- apply(ext_data[, 3:12], 2, function(x) tapply(x ,ext_data$Diagnosis, mean)) %>% as.data.frame()
ext_data_mean$Diagnosis <- rownames(ext_data_mean)

plot_violin <- function(obs){
  g <- ggplot(ext_data, aes(x = Diagnosis, y = .data[[obs]], fill = Diagnosis)) +
    geom_violin() +
    theme_classic() +
    theme(axis.title.x = element_blank(), axis.title.y = element_text(size = 15)) +
    theme(axis.text = element_text(size = 15)) +
    guides(fill = F) +
    scale_fill_manual(values = c("royalblue", "firebrick3")) +
    ylab(gsub(x = obs, pattern = "_", replacement = " "))
  
  g <- g +
    geom_point(data = ext_data_mean, aes(x = Diagnosis, y =.data[[obs]]), 
               fill = "white", size = 3, shape = 23)
  
  ggsave(plot = g, file = paste0("wdbc_plots/", obs, ".png"), w = 6.2, h = 4.8, dpi = 600)
}

sapply(attri[3:12], plot_violin)
```  
`apply()`の使い方は[こちら](http://takenaka-akio.org/doc/r_auto/chapter_07_apply.html)の解説がわかりやすかったです．

## 2つの特徴量組の散布図を相関係数と一緒に出力する．  

　引き続きBreast Cancer Wisconsin (Diagnostic) Data Setを使います．  

```R
library(ggplot2)

data <- read.csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data",
                 header = F)

attri <- c("ID", "Diagnosis", "Radius", "Texture", "Perimeter", "Area", "Smoothness",
           "Compactness", "Concavity", "Concave_points", "Symmetry", "Fractal_dimension")

ext_data <- data[,c(1, 2, seq(3, 30, 3))]

colnames(ext_data) <- attri

for(i in 3:11){
  for(j in (i+1):12){
    r <- round(cor(ext_data[,i],  ext_data[,j]), 2) #相関係数の計算
    g <- ggplot(ext_data, aes(x = .data[[attri[i]]], y = .data[[attri[j]]], color = Diagnosis)) +
      geom_point(alpha = 0.5) +
      theme_classic() +
      theme(axis.title.x = element_text(size = 15), axis.title.y = element_text(size = 15)) +
      theme(axis.text = element_text(size = 15)) +
      scale_color_manual(values = c("royalblue", "firebrick3")) +
      xlab(gsub(x = attri[i], pattern = "_", replacement = " ")) +
      ylab(gsub(x = attri[j], pattern = "_", replacement = " ")) +
      ggtitle(paste0("r = ", r)) + #相関係数を表示
      theme(plot.title = element_text(size = 15)) +
      guides(alpha = F)
    
    ggsave(plot = g, file = paste0("wdbc_plots_cor/", attri[i], "_vs_", attri[j], ".png"), 
           w = 6.2, h = 4.8, dpi = 600)
  }
}
```

　このプログラムを実行すると計45個の以下のような散布図が作成されます（実行するディレクトリの直下にwdbc_plots_corという名前の空ディレクトリを作成しておいてください）．

![Radius_vs_Perimeter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/18b2b409-bc58-c2cc-8aab-3b7c4ae6bf4a.png)  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477619/fb662729-1153-7de8-d7b5-d5d4039b59d6.png)

　このスクリプトも`apply()`を使うと少しだけスタイリッシュになります．  

```R
library(tidyverse)

data <- read.csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data",
                 header = F)

attri <- c("ID", "Diagnosis", "Radius", "Texture", "Perimeter", "Area", "Smoothness",
           "Compactness", "Concavity", "Concave_points", "Symmetry", "Fractal_dimension")

ext_data <- data[,c(1, 2, seq(3, 30, 3))]

colnames(ext_data) <- attri

attri_comb <- combn(attri[3:12], m = 2)

plot_cor <- function(obs){
  r <- round(cor(ext_data[,obs[1]],  ext_data[,obs[2]]), 2) #相関係数の計算
  g <- ggplot(ext_data, aes(x = .data[[obs[1]]], y = .data[[obs[2]]], color = Diagnosis)) +
    geom_point(alpha = 0.5) +
    theme_classic() +
    theme(axis.title.x = element_text(size = 15), axis.title.y = element_text(size = 15)) +
    theme(axis.text = element_text(size = 15)) +
    scale_color_manual(values = c("royalblue", "firebrick3")) +
    xlab(gsub(x = obs[1], pattern = "_", replacement = " ")) +
    ylab(gsub(x = obs[2], pattern = "_", replacement = " ")) +
    ggtitle(paste0("r = ", r)) + #相関係数を表示
    theme(plot.title = element_text(size = 15)) +
    guides(alpha = F)
  
  ggsave(plot = g, file = paste0("wdbc_plots_cor/", obs[1], "_vs_", obs[2], ".png"), 
         w = 6.2, h = 4.8, dpi = 600)
}

apply(attri_comb, 2, plot_cor)
```  



# さいごに  

　この記事ではggplot2の使い方をハマりどころを含め一通り説明いたしました．少しでもみなさんの研究やお仕事に役立つと嬉しいです．追加説明などご希望ございましたらコメントまでぜひお願いいたします！！！