ggplot2 分面操作

本文主要內(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")


加入靠譜熊基地贱鄙,和大家一起交流
添加我的微信
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末劝贸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子逗宁,更是在濱河造成了極大的恐慌映九,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瞎颗,死亡現(xiàn)場(chǎng)離奇詭異件甥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)哼拔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門引有,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人倦逐,你說我怎么就攤上這事譬正。” “怎么了檬姥?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵曾我,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我健民,道長(zhǎng)抒巢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任秉犹,我火速辦了婚禮蛉谜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘崇堵。我一直安慰自己型诚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布筑辨。 她就那樣靜靜地躺著,像睡著了一般幸逆。 火紅的嫁衣襯著肌膚如雪棍辕。 梳的紋絲不亂的頭發(fā)上暮现,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天诡渴,我揣著相機(jī)與錄音峰鄙,去河邊找鬼。 笑死正蛙,一個(gè)胖子當(dāng)著我的面吹牛抚太,可吹牛的內(nèi)容都是我干的塘幅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼尿贫,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼电媳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起庆亡,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤匾乓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后又谋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拼缝,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年彰亥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了咧七。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡任斋,死狀恐怖继阻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情仁卷,我是刑警寧澤穴翩,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站锦积,受9級(jí)特大地震影響芒帕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜丰介,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一背蟆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧哮幢,春花似錦带膀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至柜某,卻和暖如春嗽元,著一層夾襖步出監(jiān)牢的瞬間敛纲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工剂癌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留淤翔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓佩谷,卻偏偏與公主長(zhǎng)得像旁壮,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谐檀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容