本文主要內(nèi)容翻譯整理自:Easy multi-panel plots in R using facet_wrap() and facet_grid() from ggplot2,部分代碼有修改睬隶。
ggplot2 一個(gè)非常強(qiáng)大的功能就是進(jìn)行 multi-panel plots 的呈現(xiàn)屈扎,也就是我們常說的分面(facet)悼沈。通過使用facet_wrap() 或者 facet_grid() 這樣的函數(shù)我們就可以很方面的將單一的一個(gè)圖變?yōu)槎鄠€(gè)相關(guān)的圖。本文將通過一個(gè)具體的數(shù)據(jù)示例幫助你理解 ggplot2 分面的不同方法以及參數(shù)卤档。
數(shù)據(jù)準(zhǔn)備集
為了紀(jì)念 Captain Marvel 和即將到來的 Avengers: Endgame ,我們將使用來自 Kaggle 的漫威角色數(shù)據(jù)集
我們將主要用到其中的3個(gè)變量信息:
- YEAR: 角色第一次出現(xiàn)的年份
- SEX: 角色的性別
- ALIGN:角色的人設(shè),包括好壞和中立
在進(jìn)行分析之前甸私,首先對(duì)數(shù)據(jù)進(jìn)行幾步清洗,比如去除上述三個(gè)變量存在缺失值的數(shù)據(jù)飞傀,對(duì)變量進(jìn)行更簡(jiǎn)單的重命名皇型,同時(shí)因?yàn)樯婕暗降慕巧辔覀冎贿x擇那些出現(xiàn)次數(shù)大于100次的角色。
library(ggplot2)
library(dplyr)
marvel <- readr::read_csv("marvel-wikia-data.csv")
marvel <- filter(marvel, SEX != "", ALIGN != "", Year != "") %>%
filter(!is.na(APPEARANCES), APPEARANCES>100) %>%
mutate(SEX = stringr::str_replace(SEX, "Characters", "")) %>%
arrange(desc(APPEARANCES)) %>%
rename(gender = SEX) %>%
rename_all(tolower)
按照年份統(tǒng)計(jì)角色出現(xiàn)次數(shù)
在整篇文章中助析,我們將生成按年份分組的演員數(shù)來作為整個(gè)分析過程的開始犀被,在某些情況下還會(huì)生成其他一些分組變量。對(duì)于這個(gè)初始圖我們僅是按年進(jìn)行簡(jiǎn)單的計(jì)算外冀。
marvel_count <- count(marvel, year)
glimpse(marvel_count)
# glimpse 可以展示數(shù)據(jù)的觀測(cè)和變量數(shù)量以及每一列的名字和盡可能多的列信息寡键,和structure類似。
## Observations: 57
## Variables: 2
## $ year <dbl> 1939, 1940, 1941, 1943, 1944, 1947, 1948, 1949, 1950, 195...
## $ n <int> 3, 5, 4, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 7, 20, 36, 34, 21,...
首先畫一個(gè)由線點(diǎn)構(gòu)成的單一圖形雪隧。
ggplot(data = marvel_count, aes(year, n)) +
geom_line(color = "steelblue",size = 1) +
geom_point(color="steelblue") +
theme_classic() +
labs(title = "New Marvel characters by year",
subtitle = "(limited to characters with more than 100 appearances)",
y = "Count of new characters", x = "")
使用 facet_wrap() 按照角色人設(shè)分面
首先按照year和alignment來統(tǒng)計(jì)數(shù)目
marvel_count <- count(marvel, year, align)
glimpse(marvel_count)
## Observations: 114
## Variables: 3
## $ year <dbl> 1939, 1939, 1940, 1940, 1941, 1941, 1943, 1944, 1947, 19...
## $ align <chr> "Good Characters", "Neutral Characters", "Bad Characters...
## $ n <int> 2, 1, 1, 4, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 6, 4,...
只需要在上面繪圖命令的結(jié)尾加上+ facet_wrap(~ align)
就可以繪制按照 alignment 分面的 multi-panel plot
ggplot(data = marvel_count, aes(year, n)) +
geom_line(color = "steelblue",size = 1) +
geom_point(color="steelblue") +
theme_classic() +
labs(title = "New Marvel characters by year",
subtitle = "(limited to characters with more than 100 appearances)",
y = "Count of new characters", x = "") +
facet_wrap(~ align)
這張圖擁有了更大的信息量西轩,比如我們可以發(fā)現(xiàn)在1963和1964年出現(xiàn)了大量的壞蛋,隨后則逐漸減少脑沿;而好人在后面還是一直在穩(wěn)定的加入藕畔。在未特殊指定的情況下,這里 facet_wrap
選擇了一行展示三個(gè)圖庄拇。
如果對(duì) facet_wrap()
使用兩個(gè)變量注服,其實(shí)只需要簡(jiǎn)單的使用 +
來進(jìn)行鏈接。但是通常情況下措近,為了更好的調(diào)整布局溶弟,建議使用facet_grid()
。
marvel_count <- count(marvel, year, align, gender)
ggplot(data = marvel_count, aes(year, n)) +
geom_line(color = "steelblue",size = 1) +
geom_point(color="steelblue") +
theme_classic() +
labs(title = "New Marvel characters by year",
subtitle = "(limited to characters with more than 100 appearances)",
y = "Count of new characters", x = "") +
facet_wrap(~ align + gender)
按照 facet_grid() 指定行列進(jìn)行繪圖
facet_grid(row_variable ~ column_variable)
可以通過指定行和列來進(jìn)行繪圖瞭郑,例如使用align 作為行變量辜御,gender 作為列變量
ggplot(data = marvel_count, aes(year, n)) +
geom_line(color = "steelblue",size = 1) +
geom_point(color="steelblue") +
theme_classic() +
labs(title = "New Marvel characters by year",
subtitle = "(limited to characters with more than 100 appearances)",
y = "Count of new characters", x = "") +
facet_grid(align ~ gender)
如果想要排除行或者列變量可以通過.
來進(jìn)行代替。如下所示:
ggplot(data = marvel_count, aes(year, n)) +
geom_line(color = "steelblue",size = 1) +
geom_point(color="steelblue") +
theme_classic() +
labs(title = "New Marvel characters by year",
subtitle = "(limited to characters with more than 100 appearances)",
y = "Count of new characters", x = "") +
facet_grid(. ~ gender)
ggplot(data = marvel_count, aes(year, n)) +
geom_line(color = "steelblue",size = 1) +
geom_point(color="steelblue") +
theme_classic() +
labs(title = "New Marvel characters by year",
subtitle = "(limited to characters with more than 100 appearances)",
y = "Count of new characters", x = "") +
facet_grid(align ~ .)
顏色有時(shí)效果更好
在時(shí)間序列數(shù)據(jù)中屈张,使用兩條不同顏色的線有時(shí)比分面效率要更高擒权。
# Limit to male and female and change levels for drawing order
marvel_count <- filter(marvel_count, gender%in%c("Female ", "Male ")) %>%
mutate(gender = factor(gender, levels = c("Male ", "Female ")))
ggplot(data = marvel_count, aes(year, n, color = gender)) +
geom_line(size = 1) +
geom_point() +
theme_classic() +
labs(title = "New Marvel characters by gender",
subtitle = "(limited to characters with more than 100 appearances)",
y = "Count of new characters", x = "")
顏色和分面混用也不失為一個(gè)高效的選擇袱巨。
ggplot(data = marvel_count, aes(year, n, color = gender)) +
geom_line(size = 1) +
geom_point() +
theme_classic() +
labs(title = "New Marvel characters by alignment & gender",
subtitle = "(limited to characters with more than 100 appearances)",
y = "Count of new characters", x = "")+
facet_grid(. ~ align)
幾個(gè)常用參數(shù)
在faceting 函數(shù)中,有一些參數(shù)是通用的碳抄,只是在使用略有差別愉老。
nrow 或者 ncol
- 只對(duì)
facet_wrap()
有效 - 控制圖形布局
ggplot(data = marvel_count, aes(year, n)) +
geom_line(color = "steelblue",size = 1) +
geom_point(color = "steelblue") +
theme_classic() +
facet_wrap(~ gender + align, nrow = 2) +
labs(title = "New Marvel characters by gender & alignment",
subtitle = "(using nrow=2)",
y = "Count of new characters", x = "")
ggplot(data = marvel_count, aes(year, n)) +
geom_line(color = "steelblue", size = 1) +
geom_point(color ="steelblue") +
theme_classic() +
facet_wrap(~ gender + align, ncol = 6) +
labs(title = "New Marvel Characters by gender & alignment",
subtitle = "(using ncol=6)",
y = "Count of new characters", x = "") +
theme(
axis.text.x = element_text(angle=50, hjust=1)
)
margins
- 只對(duì)
facet_grid
有效 - 增加額外的一個(gè)分面進(jìn)行匯總
marvel_count <-
mutate(marvel_count, align = stringr::str_replace(align, "Characters", ""))
ggplot(data = marvel_count, aes(year, n)) +
geom_line(color = "steelblue", size = 1) +
geom_point(color = "steelblue") +
theme_classic() +
labs(title = "New Marvel characters by alignment & gender",
subtitle = "(margins= TRUE)",
y = "Count of new characters", x = "") +
facet_grid(align ~ gender, margins=TRUE)
自由定義不一致的Y軸
可以使用scales = "free"
或者 scales = "free_x"
或者 "free_y"
進(jìn)行設(shè)置。但是一定要注意這樣的圖可能會(huì)使讀者造成誤解纳鼎。
ggplot(marvel_count, aes(year, n)) +
geom_line(color = "steelblue", size = 1) +
facet_wrap(~gender, scales = "free_y")+
theme_classic() +
labs(title = 'with "free" y axes' ,
y = "Count of new Marvel characters")
space
- 僅
facet_grid()
有效 - 控制每個(gè)panel 的高和寬
- 默認(rèn)所有的panels有一樣的size
- 可以設(shè)置"free", "free_y" "free_x" 三個(gè)參數(shù)
- 需要和
scales = "free"
一起連用
ggplot(data = marvel_count, aes(year, n)) +
geom_line(color = "steelblue", size = 1) +
geom_point(color = "steelblue") +
theme_classic() +
labs(title = "New Marvel characters by alignment & gender",
subtitle = '(space = "free")',
y = "Count of new characters", x = "") +
facet_grid(align ~ gender, space="free", scales="free")
strip.position
- 僅
facet_wrap()
可用 - 控制facet subset labels
- 有四個(gè)選項(xiàng) "top" (default), "bottom", "left" 和 "right"
ggplot(marvel_count, aes(year, n)) +
geom_line(color = "steelblue", size = 1) +
theme_classic() +
facet_wrap(~gender, strip.position = "right") +
labs(title = 'strip.postition = "right"',
y = "Count of new Marvel characters")
switch
- 進(jìn)對(duì)
facet_grid()
有效 - 默認(rèn)是右上角
-
x
會(huì)讓label在底部俺夕,y
右改為左,both
則改為左下
ggplot(marvel_count, aes(year, n)) +
geom_line(color = "Steelblue", size = 1) +
theme_classic() +
facet_grid(~gender, switch = "x" ) +
labs(title = 'switch = "x"',
y = "Count of new Marvel characters")