]
---
layout: true
background-image: url(data:image/png;base64,#https://www.agec.ntu.edu.tw/uploads/asset/data/675f864c74ccc38a768f8254/%E6%9C%AA%E4%BE%86%E5%B1%95%E6%9C%9B%E5%9C%96%E7%89%87.png)
background-position: 98% 2%
background-size: 5%
---
## Recall ggplot2
<img src="data:image/png;base64,#./gglayers.png" width="75%" style="display: block; margin: auto;" />
<p style="text-align: center;">圖片來源:<a href="https://r.qcbs.ca/workshop03/book-en/grammar-of-graphics-gg-basics.html">QCBS R Workshop</a></p>
---
## Gapminder
[Gapminder](https://www.gapminder.org/) 是一個非營利組織,統計世界各個國家長期的社會、經濟與環境等指標。在 R 中有簡易的示範資料,包含各個國家中的 GDP、平均壽命等數據。
``` r
library(gapminder)
df <- gapminder
glimpse(df)
```
```
## Rows: 1,704
## Columns: 6
## $ country <fct> "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan", …
## $ continent <fct> Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, …
## $ year <int> 1952, 1957, 1962, 1967, 1972, 1977, 1982, 1987, 1992, 1997, …
## $ lifeExp <dbl> 28.801, 30.332, 31.997, 34.020, 36.088, 38.438, 39.854, 40.8…
## $ pop <int> 8425333, 9240934, 10267083, 11537966, 13079460, 14880372, 12…
## $ gdpPercap <dbl> 779.4453, 820.8530, 853.1007, 836.1971, 739.9811, 786.1134, …
```
---
## Basic ggplot2
上學期有使用 **ggplot2** 快速示範過各個統計圖表,如:散點圖、折線圖或直方圖,其中各個圖表中還有許多細節可以調整與修改。
.panelset[
.panel[.panel-name[Basic]
首先,最最基礎的 ggplot object 需要有三個要素:
- 繪圖資料(Data): 分析數據。
- 幾何圖形(Geom): 圖表類型。
- 映射(Mapping): 圖表上呈現的數值與樣態。
]
.panel[.panel-name[Step]
將圖層(Grammar of graphics)拆開來理解:
- `ggplot()` 拿出一張白紙來畫圖
- `ggplot(data = df)` 使用 df 這個材料來畫圖
- `geom_point()` 決定畫一張散點圖
- `mapping = aes(x = gdpPercap, y = lifeExp)` 將 gdpPercap 映射在散點圖的 X 軸上、lifeExp 映射在散點圖的 Y 軸上
]
.panel[.panel-name[Code]
.pull-left[
``` r
ggplot(data = df) + geom_point(mapping = aes(x = gdpPercap, y = lifeExp))
```
看起來平均 GDP 與平均壽命呈現正相關。
]
.pull-left[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-5-1.png" width="85%" style="display: block; margin: auto;" />
]
]
]
---
## Collapse Data
如果當想要分析的資料層級與手邊的資料層級不同時,就必須將資料疊加、加總起來,如:手上的資料是日資料,而我們想要分析月層級的資料,就必須將日資料加總成月資料。
這邊我們先用 `summarize()` 來將 df 中的資料從每年各國家加總成每年各洲:
``` r
df1 <- df %>% group_by(year, continent) %>%
summarize(lifeExp = mean(lifeExp, na.rm = T),
pop = mean(pop, na.rm = T),
gdpPercap = mean(gdpPercap, na.rm = T), .groups = "drop")
```
也可以使用 `across()` 簡化寫法:
``` r
df1 <- df %>% group_by(year, continent) %>%
summarize(across(lifeExp:gdpPercap, mean), .groups = "drop")
```
---
## Visualize Collapsed Data
將資料變成洲級資料後可以看出更明顯的 GDP 越高平均壽命也越高的趨勢。
``` r
ggplot(data = df1) + geom_point(mapping = aes(x = gdpPercap, y = lifeExp))
```
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-8-1.png" width="46%" style="display: block; margin: auto;" />
---
## Main Goal Today
<img src="data:image/png;base64,#https://edu-resource.thomasjwise.com/dataviz_research/learning_materials/images/ggplot_graphs.jpg" width="50%" style="display: block; margin: auto;" />
<p style="text-align: center;">圖片來源:<a href="https://edu-resource.thomasjwise.com/dataviz_research/learning_materials/images/ggplot_graphs.jpg">hugo-theme-learn</a></p>
]
---
## Aesthetics
.pull-left[
<img src="data:image/png;base64,#./ggplot_aesthetics_cheatsheet.png" width="80%" style="display: block; margin: auto;" />
<p style="text-align: center;">圖片來源:<a href="https://x.com/ChBurkhart/status/1287462411667152897">Christian Burkhart</a></p>
]
.pull-right[
在 `geom_*(mapping = aes())` 統計圖表圖層中,儘管每個統計圖表都有預設值(即輸入 X、Y 後就有東西畫出來),但還有許多設置可以客制化圖表,如:大小、樣式、顏色、透明度等屬性。
而每個統計圖表所能調整的屬性略有不同,取決於該圖表繪製時所使用的數據與方法。
[各圖表內容可參考](https://ggplot2tor.com/aesthetics/)
]
---
## Scatter Plot
.panelset[
.panel[.panel-name[Shape]
散點圖預設的圖形為實心原點(16),可以透過 `shape` 來修改點形狀。
.pull-left[
``` r
ggplot(data = df1) + geom_point(mapping = aes(x = gdpPercap, y = lifeExp), shape = 17)
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-11-1.png" width="85%" style="display: block; margin: auto;" />
]
]
.panel[.panel-name[Size]
可以透過 `size` 來修改點大小。
.pull-left[
``` r
ggplot(data = df1) + geom_point(mapping = aes(x = gdpPercap, y = lifeExp), size = 3)
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-12-1.png" width="85%" style="display: block; margin: auto;" />
]
]
.panel[.panel-name[Color]
可以透過 `color` 來修改點顏色。
.pull-left[
``` r
ggplot(data = df1) + geom_point(mapping = aes(x = gdpPercap, y = lifeExp), color = "blue")
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-13-1.png" width="85%" style="display: block; margin: auto;" />
]
]
]
---
## Line Plot
.panelset[
.panel[.panel-name[Type]
折線圖預設的線條樣式為實線(1),可以透過 `linetype` 來修改線條樣式。
.pull-left[
``` r
ggplot(data = df1) + geom_line(mapping = aes(x = gdpPercap, y = lifeExp), linetype = 2)
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-14-1.png" width="85%" style="display: block; margin: auto;" />
]
]
.panel[.panel-name[Width]
可以透過 `linewidth` 來修改線條寬度。
.pull-left[
``` r
ggplot(data = df1) + geom_line(mapping = aes(x = gdpPercap, y = lifeExp), linewidth = 2)
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-15-1.png" width="85%" style="display: block; margin: auto;" />
]
]
.panel[.panel-name[Transparency]
可以透過 `alpha` 來修改線條透明度。
.pull-left[
``` r
ggplot(data = df1) + geom_line(mapping = aes(x = gdpPercap, y = lifeExp), linewidth = 2, alpha = 0.5)
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-16-1.png" width="85%" style="display: block; margin: auto;" />
]
]
]
---
## Labs
說明一張圖表最重要的元素莫過於整張圖的標題、子標題或座標標題等等。
.panelset[
.panel[.panel-name[title]
.pull-left[
``` r
ggplot(data = df1) + geom_point(mapping = aes(x = gdpPercap, y = lifeExp), size = 3) +
ggtitle("GDP per capita vs. Life expectancy")
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-17-1.png" width="85%" style="display: block; margin: auto;" />
]
]
.panel[.panel-name[xlab]
.pull-left[
``` r
ggplot(data = df1) + geom_point(mapping = aes(x = gdpPercap, y = lifeExp), size = 3) +
ggtitle("GDP per capita vs. Life expectancy") +
xlab("GDP per capita(US$)")
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-18-1.png" width="85%" style="display: block; margin: auto;" />
]
]
.panel[.panel-name[ylab]
.pull-left[
``` r
ggplot(data = df1) + geom_point(mapping = aes(x = gdpPercap, y = lifeExp), size = 3) +
ggtitle("GDP per capita vs. Life expectancy") +
xlab("GDP per capita (US$)") +
ylab(NULL)
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-19-1.png" width="85%" style="display: block; margin: auto;" />
]
]
.panel[.panel-name[labs]
可以使用 `labs` 一次完成 title, x ,y 標題設置。
.pull-left[
``` r
ggplot(data = df1) + geom_point(mapping = aes(x = gdpPercap, y = lifeExp), size = 3) +
labs(title = "GDP per capita vs. Life expectancy", x = "GDP per capita (US$)", y = "Life expectancy (years)")
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-20-1.png" width="85%" style="display: block; margin: auto;" />
]
]
]
---
## Theme
預設的圖表中,各個元素總是有美中不足的部分,這時就可以透過 ggplot 中的現成主題如:`theme_minimal()` 更換主題或是手動使用 `theme()` 將整張圖表的各細節進行調整。
.panelset[
.panel[.panel-name[theme_minimal]
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-21-1.png" width="40%" style="display: block; margin: auto;" />
]
.panel[.panel-name[theme_void]
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-22-1.png" width="40%" style="display: block; margin: auto;" />
]
.panel[.panel-name[theme_bw]
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-23-1.png" width="40%" style="display: block; margin: auto;" />
]
.panel[.panel-name[theme_gray]
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-24-1.png" width="40%" style="display: block; margin: auto;" />
]
]
---
## Theme
`theme()` 可以手動調整更多細節部分,包括:字體大小、位置、顏色,基本寫法為 `theme(element.name = element_function())`。
延續 ggplot2 的圖層邏輯,允許基於一個已存在的 ggplot 物件進行 theme 上的修改。
.pull-left[
``` r
raw <- ggplot(data = df1) + geom_point(mapping = aes(x = gdpPercap, y = lifeExp), size = 3)
p <- raw + labs(title = "GDP per capita vs. Life expectancy", x = "GDP per capita (US$)", y = "Life expectancy (years)")
print(p)
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-25-1.png" width="95%" style="display: block; margin: auto;" />
]
---
## Theme
.panelset[
.panel[.panel-name[title size]
``` r
p + theme(plot.title = element_text(size = 30))
```
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-26-1.png" width="45%" style="display: block; margin: auto;" />
]
.panel[.panel-name[title color]
``` r
p + theme(plot.title = element_text(colour = "red"))
```
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-27-1.png" width="45%" style="display: block; margin: auto;" />
]
.panel[.panel-name[title position]
``` r
p + theme(plot.title = element_text(hjust = 0.5))
```
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-28-1.png" width="45%" style="display: block; margin: auto;" />
]
.panel[.panel-name[axis text]
``` r
p + theme(axis.text = element_text(size = 15))
```
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-29-1.png" width="45%" style="display: block; margin: auto;" />
]
.panel[.panel-name[more axis appearances]
<img src="data:image/png;base64,#./axis_elements.png" width="70%" style="display: block; margin: auto;" />
<p style="text-align: center;">圖片來源:<a https://ggplot2-book.org/themes">ggplot2 book</a></p>
]
]
---
## Correlation
使用 `geom_smooth()` 來展現兩個變數之間的線性關係。
``` r
ggplot(data = df1) + geom_smooth(mapping = aes(x = gdpPercap, y = lifeExp))
```
```
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
```
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-31-1.png" width="40%" style="display: block; margin: auto;" />
---
## Correlation
可以使用 `method` 決定兩變數間擬合線的模型。
``` r
ggplot(data = df1) + geom_smooth(mapping = aes(x = gdpPercap, y = lifeExp), method = "lm")
```
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-32-1.png" width="40%" style="display: block; margin: auto;" />
---
## Correlation
疊加圖表能初步判斷擬合線的模型估計是否有誤差或受極值影響。
.pull-left[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-33-1.png" style="display: block; margin: auto;" />
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-34-1.png" style="display: block; margin: auto;" />
]
---
## Straight Line
在圖形上添加直線以強調某個統計重要數值或時間點。
.panelset[
.panel[.panel-name[Horizontal]
.pull-left[
``` r
p + geom_smooth(mapping = aes(x = gdpPercap, y = lifeExp)) + geom_hline(aes(yintercept = mean(lifeExp), color = "red"))
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-35-1.png" width="95%" style="display: block; margin: auto;" />
]
]
.panel[.panel-name[Vertical]
.pull-left[
``` r
p + geom_smooth(mapping = aes(x = gdpPercap, y = lifeExp)) + geom_vline(aes(xintercept = median(gdpPercap), color = "red"))
```
]
.pull-right[
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-36-1.png" width="95%" style="display: block; margin: auto;" />
]
]
]
---
## Mapping Error
不管在疊加圖層或是修改圖層元素時,要注意 Mapping 時繪圖指令所參考的依據。
.panelset[
.panel[.panel-name[Error]
``` r
p + geom_smooth(mapping = aes(x = gdpPercap, y = lifeExp)) + geom_vline(xintercept = median(gdpPercap), color = "red")
```
```
## Error: 找不到物件 'gdpPercap'
```
]
.panel[.panel-name[Global]
``` r
p + geom_smooth(mapping = aes(x = gdpPercap, y = lifeExp)) + geom_vline(xintercept = median(df1$gdpPercap), color = "red")
```
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-38-1.png" width="35%" style="display: block; margin: auto;" />
]
.panel[.panel-name[Local]
** 放在 `aes()` 中的元素才屬於一開始 ggplot 物件 p 中的資料範圍內。**
``` r
p + geom_smooth(mapping = aes(x = gdpPercap, y = lifeExp)) + geom_vline(aes(xintercept = median(gdpPercap), color = "red"))
```
<img src="data:image/png;base64,#IntroductoryAE_1005_files/figure-html/unnamed-chunk-39-1.png" width="30%" style="display: block; margin: auto;" />
]
]
---
class: center, middle, inverse
### 謝謝
#### 下周見