← 授業トップへ戻る


本日の目標

  1. theme() を使ってグラフの見た目を整える
  2. グラフを論文・レポート向けに整形できる
  3. グラフをファイルに保存できる(ggsave())

0. 前回の復習:2週間ぶりです

10月23日は休講だったので,第3回(10月16日)から2週間空いています。 今日やるのは第3回で作ったグラフをきれいにすることなので, まず前回の宿題のファイルが動くことを確認してください。

0-1. 宿題のファイルを開いて実行する

  1. RStudioを起動する
  2. 前回保存した .R ファイルを開く(File → Open File...)
  3. 全選択(Ctrl + A)してから Ctrl + Enter(Mac は Cmd + A → Cmd + Enter)で, まとめて実行する
  4. 散布図・ヒストグラム・箱ひげ図の3つが表示されれば完了です (図は Plots タブの左右の矢印でさかのぼれます)

うまくいかないときは

  • 「関数 ‘ggplot’ を見つけることができませんでした」というエラー → library(tidyverse) の行が実行されていません。全選択して実行し直してください。 なお iris はR本体に入っているデータなので,これは読み込まなくても使えます
  • ファイルがどこにあるか分からない → 作り直しても構いません。 第3回 演習の模範解答(.R ファイル) をそのまま使って構いません。 問題から解き直したい人は第3回の演習にあります。 保存先の決め方は第3回の0-1を見てください
  • コードは走るのに図が出ない → source("ファイル名.R") や Source ボタンで 実行していませんか。この方法では図が表示されません。 全選択して Ctrl + Enter で実行してください
  • どこで失敗しているのか分からない → そのときだけ,1行目にカーソルを置いて Ctrl + Enter を繰り返し,止まる行を探してください。 ふだんは全選択で構いません

0-2. 今日のために思い出しておくこと

今日は新しいグラフの種類は出てきません。第3回の書き方の + の後ろに,見た目の指定を足していくだけです。

第3回で学んだこと 今日の使い方
ggplot(data = ..., aes(...)) + geom_xxx() この後ろに + theme_bw() などを足す
aes() の中は「データを見た目に対応づける」 aes(color = Species) で分かれた色を,今日は自分で選ぶ
labs() でタイトル・軸ラベルを付ける 今日も使います。日本語のラベルを付けます

上の3点が思い出せていれば大丈夫です。では始めましょう。


準備:パッケージの読み込み

この回のコードは,すべて tidyverse を読み込んだ状態で動きます。 RStudioを起動したら,まずこれを実行してください。

library(tidyverse)

毎回必要です。読み込まないまま ggplot() を使うと, 「関数 ‘ggplot’ を見つけることができませんでした」というエラーになります。

Macの人へ:図の日本語が □ になります

macOSの既定の設定では,グラフの日本語がすべて □(豆腐)になります。 今日は日本語のラベルを付ける回なので,先にこれを直してください。

① ragg を入れる(1回だけ。コンソールで実行します)

install.packages("ragg")

② RStudioの描画方式を切り替える

Tools → Global Options... → General → 右側の Graphics タブ → Backend を AGG に変更 → OK → RStudioを再起動

これで Plots タブの表示も,ggsave() で保存した画像も,日本語が出るようになります。

AGGが選べないときは,テーマに直接フォントを指定します。

ggplot(iris, aes(x = Sepal.Length, y = Petal.Length)) +
  geom_point() +
  labs(title = "がく片の長さと花びらの長さ") +
  theme_bw(base_family = "Hiragino Sans")   # Windowsなら "Yu Gothic"

図を作るたびに書く必要があります。

theme_set() でまとめて指定しても直りません。 あとから + theme_bw() を足すと,そちらのフォント指定で上書きされて また □ に戻ります。 この資料は全部の図でテーマを足しているので, ①②のやり方で直してください。

Windowsの人は,そのままで日本語が表示されます。 ①②は不要です。


1. テーマ(theme)によるデザイン変更

ggplot2には,グラフ全体の見た目を変えるテーマが用意されています。

# デフォルトのグラフ
p <- ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
  geom_point() +
  labs(title = "デフォルトのテーマ", x = "がく片の長さ", y = "花びらの長さ")
p

主なテーマ一覧

p + theme_bw()      # 白黒テーマ(論文向き)

p + theme_classic() # クラシック(軸線のみ,論文で人気)

p + theme_minimal() # ミニマル(シンプル)

p + theme_dark()    # ダーク(プレゼン向き)

論文・レポートには theme_bw() または theme_classic() がおすすめです。


2. 色のカスタマイズ

手動で色を指定する

ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
  geom_point() +
  # 色は自分で決められます。ここでは Dark2 パレットの3色を書き出しました
  scale_color_manual(values = c("setosa" = "#1B9E77",
                                 "versicolor" = "#D95F02",
                                 "virginica" = "#7570B3")) +
  theme_classic()

組み込みのカラーパレット

# ColorBrewerパレット(カテゴリ変数向き)
ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
  geom_point() +
  scale_color_brewer(palette = "Dark2") +
  theme_bw()

"Dark2" 以外に何があるか,どこで調べるか

パレットの名前は RColorBrewer というパッケージが持っています (tidyverse を入れると一緒に入るので,追加のインストールは要りません)。 一覧を図で見るには,コンソールで次を実行してください。

RColorBrewer::display.brewer.all(type = "qual")

種・性別のように順序のないものに使うのは qual(qualitative=質的)のグループで,次の8つです。

Accent Dark2 Paired Pastel1 Pastel2 Set1 Set2 Set3

type を付けずに display.brewer.all() と書くと全35個が出ますが, Plots ペインが狭いと縦に潰れて読めません。 その場合は Plots ペイン上部の Zoom ボタンで別ウィンドウに出すか, 上のように type で絞ってください。

残りは,順序のある量に使う seq(薄い→濃い)と, 中央を基準に両側へ分かれる div(例:マイナス←0→プラス)です。 名前と使える色数を表で見たいときは RColorBrewer::brewer.pal.info, 関数の説明は ?scale_color_brewer で読めます。

色数の上限があります。 例えば Set2 は8色までなので, 9つ以上のグループを塗り分けようとすると色が足りなくなります。 iris は3種なのでどれを選んでも足ります。

色の選び方には,好み以外の基準もあります

この回以降の資料では Dark2(線や点の色)と Set2(塗りつぶし)を使っています。 色の見え方は人によって違い, 日本では男性の約5%に,赤と緑が近い色に見える型があります。 Set1 や Pastel1(よく見かける既定のパレットです)はこの点で配慮されておらず, 赤と緑を隣り合わせに使うと,一部の人には同じ色に見えます。

配慮されたパレットだけを表示するには次のようにします。

RColorBrewer::display.brewer.all(type = "qual", colorblindFriendly = TRUE)

Dark2・Set2・Paired の3行だけが出ます。

カテゴリ変数向き(qual)で配慮されているのは Dark2・Set2・Paired の3つだけです。 発表や論文に使う図では,ここから選んでください。 色のほかに形(shape =)や線の種類(linetype =)も変えると, 白黒で印刷されても読めます。


3. 軸・凡例のカスタマイズ

ggplot(data = iris, aes(x = Species, y = Sepal.Length, fill = Species)) +
  geom_boxplot() +
  scale_x_discrete(labels = c("setosa" = "セトサ",
                               "versicolor" = "バーシカラー",
                               "virginica" = "バージニカ")) +
  scale_fill_brewer(palette = "Set2") +
  labs(
    title = "種ごとのがく片の長さ",
    x = "種",
    y = "がく片の長さ (cm)",
    fill = "アヤメの種"
  ) +
  theme_bw() +
  theme(
    legend.position = "bottom",        # 凡例の位置
    plot.title = element_text(size = 14, face = "bold"),  # タイトルの書式
    axis.title = element_text(size = 12)                  # 軸タイトルの書式
  )


4. 複数グラフを並べる(facet)

facet_wrap() で,指定した変数の水準ごとにグラフを分割できます。 ここでは Species という1つの変数の3水準(setosa / versicolor / virginica)で分かれます。

ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length)) +
  geom_point(color = "steelblue") +
  facet_wrap(~ Species) +
  labs(title = "種ごとの散布図", x = "がく片の長さ", y = "花びらの長さ") +
  theme_bw()


5. 回帰直線を追加する

点の散らばりに傾向を表す線を重ねると,関係の向きが見やすくなります。

ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "lm", se = TRUE) +   # 回帰直線 + 信頼区間
  scale_color_brewer(palette = "Dark2") +
  labs(title = "散布図と回帰直線",
       x = "がく片の長さ (cm)", y = "花びらの長さ (cm)") +
  theme_bw()

実行すると,次のメッセージが出ます。

`geom_smooth()` using formula = 'y ~ x'

これは失敗ではありません。 第3回のヒストグラムのときと同じで,「y ~ x という式(=直線)を当てはめました」という案内です。

線が3本あるのはなぜか

aes() の中に color = Species があるので,種ごとに別々の線が引かれます。全体で1本ではありません。

3本をよく見ると,傾きがそれぞれ違います。

種 線の様子
setosa ほぼ横ばい。がく片が長くても,花びらの長さはあまり変わらない
versicolor 右上がり
virginica はっきり右上がり

グループを分けないとどう見えるか

color = Species を外すと,全体で1本になります。並べて見てください。

ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "lm", se = TRUE) +
  labs(title = "種を区別しない場合", x = "がく片の長さ (cm)", y = "花びらの長さ (cm)") +
  theme_bw()

1本にすると,3本のどれよりも急な線になります。

傾きを並べると違いがはっきりします。

対象 傾き 相関係数 \(r\)
全体(1本) 1.86 0.87
setosa 0.13 0.27
versicolor 0.69 0.75
virginica 0.75 0.86

全体の線が急になるのは,setosaが左下に,virginicaが右上にかたまっているためです。 全体の傾向には,同じ種の中での関係と,種どうしの平均的な大きさの違いの両方が入っています。

全体に強い関係があること自体は確かです(\(r = 0.87\))。 問題になるのは,その線をそのまま「同じ種の中での関係」として読むことです。 setosa の中では,がく片が長くても花びらの長さはほとんど変わりません(傾き0.13)。 全体の傾向と,グループ内の傾向は分けて確かめてください。

傾きの大きさと関係の強さは別のものです。 全体(傾き1.86・\(r\) = 0.87)と virginica(傾き0.75・\(r\) = 0.86)を比べると, 傾きは2倍以上違うのに相関係数はほぼ同じです。 傾きは,xが1増えたときに回帰直線上のyの予測値がどれだけ変わるかを表します(単位はyの単位です)。 相関係数は,2つの変数の直線的な関係の向きと強さを,単位によらない \(-1\) から \(1\) までの値で表します。

この線と帯は何か

線は,点の散らばりの真ん中あたりを通るように引いた直線です(回帰直線といいます)。 影の帯は,各xにおける平均的なyの値をどれくらい確かに推定できるかを表す95%信頼区間です。 直線を当てはめた今回は,xの平均のあたりで最も狭く,そこから離れるほど広がります。 全体で1本引いた図では,がく片の長さの全体平均5.84 cm付近で最も狭くなります。 種ごとに線を引いた図では,それぞれの種の平均付近で最も狭くなります (種ごとの線は,その種のデータだけを使って別々に当てはめられています)。 「データの95%がこの帯に入る」という意味ではありません。 帯が不要なら se = FALSE と書きます。

計算の中身と解釈のしかたは第8回以降で扱います。今日は「傾向を目で見るための補助線」として使います。

線が引けたからといって,原因と結果の関係があるとは限りません。 「がく片が長いから花びらが長くなる」とは言えません。どちらも「その種はもともと大きい」という 共通の理由で説明できるかもしれないからです。線は関係の向きを見せるだけです。


6. グラフの保存(ggsave)

作成したグラフをファイルに保存するには ggsave() を使います。

# グラフを変数に保存しておく
my_plot <- ggplot(data = iris, aes(x = Species, y = Sepal.Length, fill = Species)) +
  geom_boxplot() +
  scale_fill_brewer(palette = "Set2") +
  theme_bw() +
  labs(title = "種ごとのがく片の長さ")

# PNG形式で保存
ggsave(filename = "my_plot.png",
       plot = my_plot,
       width = 8,       # 幅(インチ)
       height = 5,      # 高さ(インチ)
       dpi = 300)       # 解像度(論文用は300以上推奨)

# PDF形式で保存(ベクター形式,高品質)
ggsave(filename = "my_plot.pdf",
       plot = my_plot,
       width = 8,
       height = 5)

ファイルはどこに保存されるか

パスを書かずにファイル名だけを指定すると,いま作業しているフォルダに保存されます。 どこかは getwd() で確認できます。プロジェクトを使っていれば,プロジェクトのフォルダです。

日本語を含む図をPDFで保存するときの注意

PDFの標準フォントは日本語に対応していないため,環境によっては文字が消えたり□になったりします。 うまくいかないときは PNG で保存するか,次のように書いてください。

ggsave("my_plot.pdf", my_plot, width = 8, height = 5,
       device = grDevices::cairo_pdf)

cairo_pdf も環境によっては使えないことがあります。確実なのはPNGです。

解像度の目安

これはPNGなどの画像形式(ラスター)の目安です。 PDFは点ではなく線の情報で保存するため, dpi を上げても仕上がりは変わりません。

用途 dpi
画面・Web表示 72〜96
印刷・プレゼン 150〜200
論文投稿 300〜600

width = 7,height = 5,dpi = 300 なら 2100 × 1500 ピクセルのPNGになります (インチ数 × dpi)。論文に出すときは,投稿先の指定があればそちらを優先してください。


7. よく使うグラフのまとめ

グラフの種類 用途 geom関数
散布図 2変数の関係 geom_point()
ヒストグラム 1変数の分布 geom_histogram()
棒グラフ カテゴリのカウント・集計値 geom_bar() / geom_col()
箱ひげ図 グループ間の分布比較 geom_boxplot()
折れ線グラフ 時系列・連続変化 geom_line()
バイオリン図 箱ひげ図より詳細な分布 geom_violin()

演習

演習1:テーマの比較

第3回で作ったグラフのいずれかに,theme_classic() と theme_bw() を適用し, どちらが見やすいか比較してください。

演習2:論文用グラフの作成

以下の要件を満たすグラフを作成してください。

  • データ:iris
  • グラフの種類:箱ひげ図
  • x軸:Species,y軸:Petal.Length
  • 色:fill = Species,カラーパレットは "Set2"
  • テーマ:theme_bw()
  • 日本語のラベル:タイトル・軸ラベルを日本語で
  • 凡例の位置:下(legend.position = "bottom")
ggplot(data = iris, aes(x = ___, y = ___, fill = ___)) +
  geom_boxplot() +
  scale_fill_brewer(palette = "___") +
  labs(title = "___", x = "___", y = "___") +
  theme_bw() +
  theme(legend.position = "___")

演習3:グラフの保存

演習2で作ったグラフを kadai_02.png(dpi = 300,幅 = 7インチ,高さ = 5インチ)で保存してください。

模範解答

演習1〜3の解答例を置いてあります。自分で解いたあとに見てください。

→ 第4回 演習の模範解答(.R ファイル)

ブラウザで中身が表示されます。保存するときは右クリック →「リンク先を別名で保存」。 RStudioで開いて,全選択して Ctrl + Enter で実行して確かめてください。


本日のまとめ

  • theme_bw() / theme_classic() で論文向きのデザインにできる
  • scale_color_manual() や scale_color_brewer() で色をカスタマイズ
  • facet_wrap() で,指定した変数の水準ごとに分割したグラフを作れる
  • geom_smooth(method = "lm") で回帰直線を追加できる(method を省略すると直線以外の曲線になる)
  • ggsave() でグラフをPNG・PDFなどで保存できる

宿題・予習

  • 演習3で保存した kadai_02.png を開いて,画像ができていることを確認する
    • 提出は要りません。 自分のパソコンに保存できていれば完了です
    • どこに保存されたか分からなくなったら getwd() で確認してください
    • 画像の大きさが 2100 × 1500 ピクセルになっていれば,dpi = 300 が効いています (Windows はファイルを右クリック →「プロパティ」→「詳細」, Mac は右クリック →「情報を見る」で確認できます)
  • 次回から データの加工(dplyr) に入ります
  • 教科書のdplyr関連の章に目を通しておく

← 授業トップへ戻る