情報の整理 → 正しい解析・新しい発見・仮説生成
carat
が大きいほど price
も高いらしい。
その度合いは clarity
によって異なるらしい。
ある程度はテクニックであり教養。
デザインの基本的なルールを
知りさえすれば誰でも上達する。
iris
: アヤメ属3種150個体の測定データRに最初から入ってて、例としてよく使われる。
print(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
--
147 6.3 2.5 5.0 1.9 virginica
148 6.5 3.0 5.2 2.0 virginica
149 6.2 3.4 5.4 2.3 virginica
150 5.9 3.0 5.1 1.8 virginica
長さ150の数値ベクトル4本と因子ベクトル1本。
描けるっちゃ描けるけど。カスタマイズしていくのは難しい。
boxplot(Petal.Width ~ Species, data = iris)
plot(iris$Sepal.Length, iris$Sepal.Width)
hist(iris$Petal.Length)
きれいなグラフを簡単に描けるパッケージを使いたい。
R標準のやつとは根本的に違うシステムで作図する。
+
で重ねていく+
で重ねていくggplot(data = diamonds) # diamondsデータでキャンバス準備
# aes(x = carat, y = price) + # carat,price列をx,y軸にmapping
# geom_point() + # 散布図を描く
# facet_wrap(vars(clarity)) + # clarity列に応じてパネル分割
# stat_smooth(method = lm) + # 直線回帰を追加
# coord_cartesian(ylim = c(0, 2e4)) + # y軸の表示範囲を狭く
# theme_classic(base_size = 20) # クラシックなテーマで
+
で重ねていくggplot(data = diamonds) + # diamondsデータでキャンバス準備
aes(x = carat, y = price) # carat,price列をx,y軸にmapping
# geom_point() + # 散布図を描く
# facet_wrap(vars(clarity)) + # clarity列に応じてパネル分割
# stat_smooth(method = lm) + # 直線回帰を追加
# coord_cartesian(ylim = c(0, 2e4)) + # y軸の表示範囲を狭く
# theme_classic(base_size = 20) # クラシックなテーマで
+
で重ねていくggplot(data = diamonds) + # diamondsデータでキャンバス準備
aes(x = carat, y = price) + # carat,price列をx,y軸にmapping
geom_point() # 散布図を描く
# facet_wrap(vars(clarity)) + # clarity列に応じてパネル分割
# stat_smooth(method = lm) + # 直線回帰を追加
# coord_cartesian(ylim = c(0, 2e4)) + # y軸の表示範囲を狭く
# theme_classic(base_size = 20) # クラシックなテーマで
+
で重ねていくggplot(data = diamonds) + # diamondsデータでキャンバス準備
aes(x = carat, y = price) + # carat,price列をx,y軸にmapping
geom_point() + # 散布図を描く
facet_wrap(vars(clarity)) # clarity列に応じてパネル分割
# stat_smooth(method = lm) + # 直線回帰を追加
# coord_cartesian(ylim = c(0, 2e4)) + # y軸の表示範囲を狭く
# theme_classic(base_size = 20) # クラシックなテーマで
+
で重ねていくggplot(data = diamonds) + # diamondsデータでキャンバス準備
aes(x = carat, y = price) + # carat,price列をx,y軸にmapping
geom_point() + # 散布図を描く
facet_wrap(vars(clarity)) + # clarity列に応じてパネル分割
stat_smooth(method = lm) # 直線回帰を追加
# coord_cartesian(ylim = c(0, 2e4)) + # y軸の表示範囲を狭く
# theme_classic(base_size = 20) # クラシックなテーマで
+
で重ねていくggplot(data = diamonds) + # diamondsデータでキャンバス準備
aes(x = carat, y = price) + # carat,price列をx,y軸にmapping
geom_point() + # 散布図を描く
facet_wrap(vars(clarity)) + # clarity列に応じてパネル分割
stat_smooth(method = lm) + # 直線回帰を追加
coord_cartesian(ylim = c(0, 2e4)) # y軸の表示範囲を狭く
# theme_classic(base_size = 20) # クラシックなテーマで
+
で重ねていくggplot(data = diamonds) + # diamondsデータでキャンバス準備
aes(x = carat, y = price) + # carat,price列をx,y軸にmapping
geom_point() + # 散布図を描く
facet_wrap(vars(clarity)) + # clarity列に応じてパネル分割
stat_smooth(method = lm) + # 直線回帰を追加
coord_cartesian(ylim = c(0, 2e4)) + # y軸の表示範囲を狭く
theme_classic(base_size = 20) # クラシックなテーマで
+
で重ねていくggplot(data = diamonds) + # diamondsデータでキャンバス準備
aes(x = carat, y = price) + # carat,price列をx,y軸にmapping
geom_point() + # 散布図を描く
# facet_wrap(vars(clarity)) + # clarity列に応じてパネル分割
# stat_smooth(method = lm) + # 直線回帰を追加
# coord_cartesian(ylim = c(0, 2e4)) + # y軸の表示範囲を狭く
theme_classic(base_size = 20) # クラシックなテーマで
p1 = ggplot(data = diamonds)
p2 = p1 + aes(x = carat, y = price)
p3 = p2 + geom_point()
p4 = p3 + facet_wrap(vars(clarity))
print(p3)
この p3
は後で使います。
自動車のスペックに関するデータ mpg
を使って。
manufacturer model displ year cyl trans drv cty hwy fl class
1 audi a4 1.8 1999 4 auto(l5) f 18 29 p compact
2 audi a4 1.8 1999 4 manual(m5) f 21 29 p compact
--
233 volkswagen passat 2.8 1999 6 manual(m5) f 18 26 p midsize
234 volkswagen passat 3.6 2008 6 auto(s6) f 17 26 p midsize
🔰 排気量 displ
と市街地燃費 cty
の関係を散布図で。
関数名を ggplot2
と書いちゃうと勘違い:
> ggplot2(diamonds)
Error in ggplot2(diamonds) : could not find function "ggplot2"
ggplot2 はパッケージ名。
今度こそ関数名は合ってるはずなのに…
> ggplot(diamonds)
Error in ggplot(diamonds) : could not find function "ggplot"
パッケージ読み込みを忘れてた。新しくRを起動するたびに必要:
library(conflicted) # 安全のおまじない
library(tidyverse) # including ggplot2
ggplot(diamonds) # OK!
そのほか よくあるエラー集 (石川由希さん@名古屋大) を参照。
ggplot()
に渡すのは整然データ tidy dataprint(diamonds)
carat cut color clarity depth table price x y z
1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
4 0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63
--
53937 0.72 Good D SI1 63.1 55 2757 5.69 5.75 3.61
53938 0.70 Very Good D SI1 62.8 60 2757 5.66 5.68 3.56
53939 0.86 Premium H SI2 61.0 58 2757 6.15 6.12 3.74
53940 0.75 Ideal D SI2 62.2 55 2757 5.83 5.87 3.64
https://r4ds.had.co.nz/tidy-data.htmlaes()
の中で列名を指定する。
ggplot(diamonds) +
aes(x = carat, y = price) +
geom_point(mapping = aes(color = clarity, size = cut))
aes()
の外で値を指定する。
ggplot(diamonds) +
aes(x = carat, y = price) +
geom_point(color = "darkorange", size = 6, alpha = 0.4)
aes()
は全ての geom_*()
に波及するggplot(diamonds) +
aes(x = carat, y = price) +
geom_point(aes(color = clarity)) +
geom_line() # NO color
ggplot(diamonds) +
aes(x = carat, y = price, color = clarity) +
geom_point() + # color
geom_line() # color
color
, 面は fill
不透明度は alpha
ggplot(diamonds) +
aes(cut, carat) +
geom_boxplot(color = "royalblue", fill = "gold", alpha = 0.5, linewidth = 2)
自動車のスペックに関するデータ mpg
を使って。
manufacturer model displ year cyl trans drv cty hwy fl class
1 audi a4 1.8 1999 4 auto(l5) f 18 29 p compact
2 audi a4 1.8 1999 4 manual(m5) f 21 29 p compact
--
233 volkswagen passat 2.8 1999 6 manual(m5) f 18 26 p midsize
234 volkswagen passat 3.6 2008 6 auto(s6) f 17 26 p midsize
🔰 排気量 displ
と市街地燃費 cty
の関係を青い散布図で描こう
🔰 駆動方式 drv
やシリンダー数 cyl
によって色を塗り分けしてみよう
赤
緑
青の3色を使った先ほどの図は多くの人には問題なさそう。
しかし5%くらいの人には右のように赤
緑
青 や
赤
緑
青の2色に見えている。
MacやiOSならSim Daltonismというアプリでシミュレーションできる。
WindowsならColor Oracleが使えそう。
Sequential palette:
Diverging palette:
Qualitative (categorical, discrete) palette:
scale_color_*()
viridis
と
ColorBrewer
のパレットはggplot2に組み込まれているので簡単。
上記リンクから名前を探して、option =
か palette =
で指定。
ggplot(diamonds) + aes(carat, price) +
geom_point(mapping = aes(color = clarity)) +
scale_color_viridis_d(option = "inferno")
# scale_color_brewer(palette = "YlGnBu")
渡す値とscale関数が合ってないと怒られる:
Error: Continuous value supplied to discrete scale
ggplot(diamonds) + aes(carat, price) +
geom_point(mapping = aes(color = price)) +
scale_color_viridis_c(option = "inferno")
# scale_color_distiller(palette = "YlGnBu")
scale_color_viridis_d()
, scale_color_brewer()
scale_color_viridis_c()
, scale_color_distiller()
scale_color_viridis_b()
, scale_color_fermenter()
R標準の palette.colors()
や
colorspaceパッケージ
を使う。
okabe_ito = palette.colors(9L, "Okabe-Ito")
ggplot(mpg) +
aes(x = displ, y = cty) +
geom_point(aes(color = drv), size = 4, alpha = 0.66) +
scale_color_discrete(type = unname(okabe_ito)[-1])
# scale_color_discrete(type = palette.colors(8L, "R4")[-1])
# colorspace::scale_colour_discrete_divergingx("Zissou 1")
自分で全色個別指定もできるが、専門家の考えたセットを使うのが無難。
scale_color_*
を省略できるように設定することも可能連続値viridis, 離散値Okabe-Itoをデフォルトにする例:
grDevices::palette("Okabe-Ito")
options(
ggplot2.continuous.colour = "viridis",
ggplot2.continuous.fill = "viridis",
ggplot2.discrete.colour = grDevices::palette()[-1],
ggplot2.discrete.fill = grDevices::palette()[-1]
)
options()
による設定はRを終了するまで有効。
ggplotの真骨頂! これをR標準機能でやるのは結構たいへん。
p3 + facet_wrap(vars(clarity), ncol = 4L)
ggplotの真骨頂! これをR標準機能でやるのは結構たいへん。
p3 + facet_grid(vars(clarity), vars(cut))
自動車のスペックに関するデータ mpg
を使って。
manufacturer model displ year cyl trans drv cty hwy fl class
1 audi a4 1.8 1999 4 auto(l5) f 18 29 p compact
2 audi a4 1.8 1999 4 manual(m5) f 21 29 p compact
--
233 volkswagen passat 2.8 1999 6 manual(m5) f 18 26 p midsize
234 volkswagen passat 3.6 2008 6 auto(s6) f 17 26 p midsize
🔰 駆動方式 drv
やシリンダー数 cyl
によってfacetしてみよう
scale_*
, coord_*
ggplot(diamonds) + aes(carat, price) + geom_point(alpha = 0.25) +
scale_x_log10() +
scale_y_log10(breaks = c(1, 2, 5, 10) * 1000) +
coord_cartesian(xlim = c(0.1, 10), ylim = c(800, 12000)) +
labs(title = "Diamonds", x = "Size (carat)", y = "Price (USD)")
theme
既存の theme_*()
をベースに、theme()
関数で微調整。
p3 + theme_bw(base_size = 18) + theme(
panel.background = element_rect(fill = "khaki"), # 箱
panel.grid = element_line(color = "royalblue"), # 線
axis.title.x = element_text(size = 32), # 文字
axis.text.y = element_blank() # 消す
)
+
で重ねていく別のパッケージ (cowplot や patchwork) の助けを借りて
pAB = cowplot::plot_grid(p3, p3, labels = c("A", "B"), nrow = 1L)
cowplot::plot_grid(pAB, p3, labels = c("", "C"), ncol = 1L)
width
やheight
が小さいほど、文字・点・線が相対的に大きく
# 7inch x 300dpi = 2100px四方 (デフォルト)
ggsave("dia1.png", p3) # width = 7, height = 7, dpi = 300
# 4 x 300 = 1200 全体7/4倍ズーム
ggsave("dia2.png", p3, width = 4, height = 4) # dpi = 300
# 2 x 600 = 1200 全体をさらに2倍ズーム
ggsave("dia3.png", p3, width = 2, height = 2, dpi = 600)
# 4 x 300 = 1200 テーマを使って文字だけ拡大
ggsave("dia4.png", p3 + theme_bw(base_size = 22), width = 4, height = 4)
環境設定 → General → Graphics → Backend: AGG
英数字以外を使わずに済ませられればそれに越したことはないけど…
geom_*()
が使える?なんでもある。 公式サイトを見に行こう。
うん。でもすべての点について後から確認できるし、使い回せる!
set.seed(1)
p = ggplot(diamonds) +
aes(x = cut, y = price) +
geom_jitter(aes(color = cut), height = 0, width = 0.2, alpha = 0.1, stroke = 0) +
geom_boxplot(fill = NA, outlier.shape = NA) +
scale_color_viridis_d(option = "plasma") +
facet_wrap(vars(clarity)) +
coord_flip(xlim = c(0.5, 5.5), ylim = c(0, 20000), expand = FALSE) +
labs(title = "Diamonds", x = "Cut", y = "Price (USD)") +
theme_bw(base_size = 20) +
theme(legend.position = "none",
axis.ticks = element_blank(),
panel.grid.major.y = element_blank(),
panel.spacing.x = grid::unit(3, "lines"),
plot.margin = grid::unit(c(1, 2, 0.5, 0.5), "lines"))
print(p)
ggsave("diamonds-cut-price.png", p, width = 12, height = 9)
下図になるべく似るように作図・調整してください。
説明文、Rコード、実行結果、図。
それらをひとまとめに扱えるようなシステムがあるらしい…
スクリプト.Rさえ保存しておけばいつでも実行できるけど… 面倒
ggsave()
で画像を書き出しておけるけど… どのコードの結果か分からない
→ スクリプトと実行結果を一緒に見渡せる形式が欲しい。
3 * 14
ggplot(mpg) + aes(displ, hwy) + geom_point(aes(color = drv))
[1] 42
プログラミングからレポート作成まで一元管理できて楽ちん。
.qmd
).Rmd
と使い勝手は同じ。.md
)(どんなものが作れるのか 作成例ギャラリー を見てみよう。)
文書の構造や視覚的修飾を記述するための言語。
e.g., HTML+CSS, XML, LaTeX
<h3>見出し3</h3>
<p>ここは段落。
<em>強調(italic)</em>、
<strong>強い強調(bold)</strong>、
<a href="https://www.lifesci.tohoku.ac.jp/">リンク</a>とか。
</p>
ここは段落。 強調(italic)、 強い強調(bold)、 リンクとか。
表現力豊かで強力だが人間が読み書きするには複雑すぎ、機械寄り。
(好きなウェブサイトのHTMLソースコードを見てみよう。)
マークアップ言語の中でも人間が読み書きしやすいもの。
e.g., Markdown, reStructuredText, 各種Wiki記法など
### 見出し3
ここは段落。
*強調(italic)*、
**強い強調(bold)**、
[リンク](https://www.lifesci.tohoku.ac.jp/)とか。
ここは段落。 強調(italic)、 強い強調(bold)、 リンクとか。
(示してあるバージョンは最低要件ではなく私の現在の環境の)
install.packages("quarto")
:
多くの人には不要。
Quarto CLIをRコマンドで呼べるようにするだけ。RStudio > New File > Quarto Document…
(DocumentとHTMLを選択し、)タイトルと著者を埋めて、OK。
---
で挟まれた部分。
文書全体に関わるメタデータを入力。html
```{r}
のように始まるコードブロック。echo: false
: コードを非表示。結果は表示。eval: false
: コードを実行せず表示だけ。include: false
: コードも結果も表示せず、実行だけする。fig.width: 7
, fig.height: 7
: 図の大きさを制御。まあ細かいことは必要になってから調べるとして…
左のqmdを “→Render” すると右のができる。手順は次スライド。
report.qmd
report.html
左のようなqmdを作ってRenderし、右のようなHTMLファイルを提出。
{ID}-{name}-day{d}.html
, e.g., C0SB0000-iwasaki-day2.html
embed-resources: true
で画像などを埋め込んだ独立HTML。# 親切コメント
。ggsave()
まできっちりやる。