R語言學習ggplot2繪制統(tǒng)計圖形包全面詳解
一、序
作為一枚統(tǒng)計專業(yè)的學僧,首先需要掌握的編程語言一定是R。雖然自己對R談不上精通,但卻有著不一樣的熱愛,尤其熱衷于使用R語言繪制各種各樣覺得十分酷炫的圖。每每磕完一個繪圖作品,仿佛過了一個愉快的寒暑假,充實而滿足。而在R語言中,談到繪圖,就不得不聊聊ggplot2
這個大神器。
剛開始接觸學習的時候,其實是非常抵觸,覺得非常非常難的,但隨著一張張圖片躍然于屏幕之上,心中的抵觸滿滿消失,取而代之的甚至多出了一絲喜愛。而這絲喜愛愈釀愈醇厚,愈釀愈香甜。這就促使我寫一寫這篇博文。回顧我之前學習ggplot2
所走過的路,使大家能夠避免走上我曾經(jīng)走過的死胡同,從而走上一條康莊大道。也希望大家能夠愛上R這門編程語言,享受使用ggplot2
繪圖的樂趣。
本文其實借鑒了網(wǎng)上很多的教程與參考文獻,具體這些學習資料的網(wǎng)址,也會在文末進行說明。
二、ggplot2是什么?
一句話概括:它是一個用來繪制統(tǒng)計圖形(不只是統(tǒng)計圖形)的R包!
為什么叫ggplot呢?其中的gg當然不是Good Game的意思,而是Grammar of Graphics,直譯就是繪圖的語法,這是一門學問,繪圖的學問。后面會介紹其與眾不同的語法。
作者是Hadley Wickham,下面我們先瞻仰一下大神,沾點靈氣,為后續(xù)的ggplot
學習之路打好基礎。
說起這位作者,可就厲害了。他是RStudio公司的首席科學家,在博士期間其實就已經(jīng)開發(fā)出了ggplot
包,后面覺得寫的不行,于是推陳出新,天空一聲巨響,ggplot2
閃亮登場。由于這個包實在是太好用了,所以漸漸的,如今Python等多個編程語言都有了其對應的庫。
當然,如果僅僅憑借ggplot2
,Wickham還無法成為RStudio公司的首席科學家,他還是dplyr
,devtools
,readxl
,rvest
等包的作者,是一位全能型大神。
與此同時,在工作之外,他擅長烘焙和調制雞尾酒,并且還有自己的家庭食譜網(wǎng)站。真的非常的膩害!
更新:大神還榮獲2019年的統(tǒng)計學諾貝爾獎——COPSS 獎!
好了,言歸正傳,我們接著介紹ggplot2
。
三、ggplot2能畫出什么樣的圖?
前面一直在夸它的好,得看看它究竟能創(chuàng)作出什么樣的圖?。ㄓ捎诓┛偷南拗?,不能使用svg的高清無碼矢量圖,故只能使用略帶模糊的jpg圖片)
前面兩個圖都是標準的統(tǒng)計學的我們需要畫的圖,只不過是將箱線圖、柱狀圖、直方圖、散點圖、擬合回歸以及相關系數(shù),全部融合在了一張圖上,信息量非常豐富。集百家之所長,成一家之言!但這還沒什么,ggplot2
還能做出令你更加吃驚的統(tǒng)計圖。就比如下面的回歸樹圖:
還有下面這個像巖漿一樣的族譜圖:從祖先到你,如何薪火相傳。
以及最后一個犯罪率的變化情況。
好看的圖片千千萬,有趣的繪圖包只有ggplot2
。這里只介紹極小的一部分情況,說明一下它能做些什么。屏幕中的圖,如果不自己生成,就永遠只是別人家的圖,而不是自己的,所以下面我們就來講講如何像搭積木,組裝機器一樣,組裝成一個獨屬于你的妖嬈且風騷的圖片。
四、組裝機器
ggplot2
繪圖三步走:
- 按照**“設計圖紙”**
- 用一個個**“零件”**
- 自己進行**“組裝”**
后面會一一進行介紹,這三步。但其實只要有一個概念,用ggplot2
就是像PS一樣,一個圖層一個圖層的疊加,最后組成我們的目標繪圖。
它的優(yōu)勢非常明顯:
- 用戶能在更抽象層面上控制圖形,使創(chuàng)造性繪圖更容易
- 采用圖層的設計方式,使其更具靈活性
- 圖形美觀,同時避免繁瑣細節(jié)
- 將常見的統(tǒng)計變換融入到了繪圖中
五、設計圖紙
想要了解ggplot2
,我們必須先了解下面這些概念:
- 數(shù)據(jù)(Data)和映射(Mapping):將數(shù)據(jù)映到圖像
- 幾何對象(Geometric):代表在圖中看到的實際元素,如點、線、多邊形等
- 統(tǒng)計變換(Statistics):對數(shù)據(jù)進行某種匯總,如直方圖,或將二維關系用線性模型解釋
- 標度(Scale):將數(shù)據(jù)的取值映射到圖形空間,例如用:顏色、大小、形狀表示不同取值
- 坐標系(Coordinate):數(shù)據(jù)如何映射到圖形所在平面,提供作圖所需的坐標軸和網(wǎng)格線
- 分面(Facet):將數(shù)據(jù)分解為子集,進行聯(lián)合展示
- 圖層(Layer):對所需的繪圖操作進行一層一層疊加,最終得到所需圖形
這些概念能幫助你加深對其的理解,但是還是不懂?沒關系!我們剛開始只需要掌握下面的零件構造就好了!
六、機器的零件
在最最最開始,你需要安裝R
并且建議安裝R Studio
,都是免費的,并且都需要安裝,然后可以直接從R Studio
打開。
然后我們需要先安裝ggplot2
包,在R
或者R Studio
中使用下述語句,即可完成安裝。
install.packages('ggplot2')
接著,我們就可以學習其中的每個零件的用法了。
1. 零件——散點圖
如果我們想要看兩個變量之間的關系,最簡單,最方便的做法就是繪制散點圖,那我們如何使用ggplot2
繪制這樣一個圖形呢?
library(ggplot2) p <- ggplot(data = mpg, mapping = aes(x = cty, y = hwy)) p + geom_point()
首先需要使用library()
對ggplot2
包進行加載(記得每次重新打開都需要進行加載?。?,當然也可以使用require()
。然后就可以愉快地進行繪圖了。
我們需要找到一個映射,也就是一對一的對應關系,這個我們在程序中如何給定呢?這就需要使用ggplot()
這個函數(shù)。
首先在data =
后面需要加上數(shù)據(jù)集的名稱,在例子中是mpg
一個關于汽車的數(shù)據(jù)集(注意:這個數(shù)據(jù)集是ggplot2
包中特有的,加載了包才會有這個數(shù)據(jù)集)。在這個數(shù)據(jù)集里面有很多變量,其中有cty
與hwy
等一系列變量。 每個變量都有一列數(shù)值,也就是樣本的信息,我們需要看cty
與hwy
兩個變量對應的信息,就需要指定x軸是誰,y軸對應的是誰。在代碼中,首先需要使用aes()
將兩個坐標軸的信息對應起來。aes代表的是aesthetic mappings,具有美感的映射,然后在里面分別使用x =
,y =
來制定需要映射的變量。至此,我們的對應關系就找出來了。
但是!此時,你運行p
這個變量是沒有圖像信息反饋出來的,因為你只是指定了關系,而沒有說明應該以什么形式進行展現(xiàn)。可能是散點、折線、曲線等等。不過由于我們是進行散點圖的繪制,所以使用的是后面還要+ geom_point()
就可以展現(xiàn)出散點圖了,其中geom表示的是geometric object,幾何對象的意思。
接著,我們再對散點圖進行一點點潤色。(黑黑的點真的好丑)
1) 變換顏色
p <- ggplot(mpg, aes(x = cty, y = hwy, colour = factor(year))) p + geom_point()
這里我們指定了其散點的顏色,在aes()
中使用了colour =
,其后面的year
也是mpg
數(shù)據(jù)集中的一個變量。里面只有1999和2008兩年,每個樣本都有一個年份。(colour =
寫在aes()
里面可以自動分配顏色,寫在外面就是強制指定點的顏色,如加上‘blue'
等)
不過為了將數(shù)字轉化成factor因子形式,我們這里使用了factor()
將數(shù)值變成了因子(可以自己嘗試不添加factor()
看看會出現(xiàn)什么樣的結果,其實會出現(xiàn)顏色的深淺表示數(shù)值的大?。?。
這里使用了p <- ggplot(mpg, aes(x = cty, y = hwy, colour = factor(year)))
,我們默認將后面這部分賦值給了變量p
,后面的p
全部都是指代這行語句。
這行代碼還有另外一個地方發(fā)生了變化,data =
消失,只是這個都可以省略,只要在對應的位置有數(shù)據(jù)集這個變量就好了(這里是mpg
)。同理,其實x =
與y =
在這里都可以省略。
在出現(xiàn)了散點之后,還是覺得空蕩蕩的,我們再加點別的零件。
2) 擬合曲線
p + geom_point() + stat_smooth()
相比于原先的操作,只是再加了一行 + stat_smooth()
,stat表示的是statistical transformation,統(tǒng)計學變換。因為我們需要用插值的方法來繪制擬合直線,并且附帶置信區(qū)間。
3) 變換大小
p + geom_point(aes(colour = factor(year), size = displ)) + stat_smooth() # 排量越大,點越大
想要變換點的大小,只需再在aes()
中加上size =
,后面接上一個新的變量名稱displ
代表著汽車的排量,每個點的尺寸越大,代表著排量越大,其對應關系如右邊圖例所示。
在此基礎上我們還想在一張圖上添加更多的信息,同時也可以解決點與點之間的重疊的問題,不會因為遮蓋而使得我們有部分點看不到。那么我們應該怎么做呢?
透明度!
4) 修改透明度
p + geom_point(aes(colour = factor(year), size = displ), alpha = 0.5) + stat_smooth() + scale_size_continuous(range = c(4, 10))
同樣,我們只需使用alpha =
即可其范圍在0 — 1之間,越小表示越透明。注意,在這里,我們是寫在aes()
的外面,代表對所有的點都強制透明度為0.5。
在修改完透明度后,我們發(fā)現(xiàn),圖像已經(jīng)有一點夢幻般的感覺了。但仔細一看,會發(fā)現(xiàn),這張圖實在是太擁擠了,1999年與2008年全部擠在了一塊兒,那有沒有什么簡單的方法可以將兩年直接分開呢?
使用分層操作!
5) 分層
p + geom_point(aes(colour = class, size = displ), alpha = 0.5) + stat_smooth() + scale_size_continuous(range = c(4, 10)) + facet_wrap(~ year, ncol = 1)
這次變化的內容其實有點多,我們來細細捋一捋,首先是分層。
其實分層操作用起來非常的簡單,就一行代碼:facet_wrap(~ year, ncol = 1)
,facet_wrap()
是關鍵,facet與wrap兩個詞組合,就是逐面地包起來。里面我們選擇按照year
這個變量來分層,就可以將1999與2008分開。一定要注意!這里在year
前面有個~
,回歸中的用法。而最后的ncol = 1
代表著我們的小窗口是1列,指定了1列之后,默認就是兩行啦。(因為年份一共只有兩種)如果不加這句,會默認橫著排列,或者想要指定幾行,則使用nrow = 1
。
第二個修改的地方是colour = class
。同樣的,class
也是數(shù)據(jù)集中的一個變量,代表不同種類的汽車,而因為汽車的種類非常多,所以顏色也就變的很多了。
第三個修改點是:添加了scale_size_continuous(range = c(4, 10))
,也就是指定我們size
的變化范圍。在本圖中,就是控制點的絕對大小的范圍, 不要太大,也不要太小。
至此,散點圖該潤色的地方,已經(jīng)潤色的差不多了,唯獨還有一個小小的缺陷:能否加個標題,并且將這些英文簡寫的名稱改得更容易懂一些。畢竟做統(tǒng)計圖不是為了自娛自樂,而是要給別人看的,要讓大家明白你在做什么,在分析什么。
所以我們還需要進行一點點修改。
6) 改中文
p + geom_point(aes(colour = class, size = displ), alpha=0.5) + stat_smooth() + scale_size_continuous(range = c(4, 10)) + facet_wrap(~ year,ncol = 1) + labs(y = '每加侖高速公路行駛距離', x = '每加侖城市公路行駛距離', title = '汽車油耗與型號', size = '排量', colour = '車型') + theme(text = element_text(family = "STHeiti"), plot.title = element_text(hjust = 0.5))
看到這么長的代碼,首先要做的就是淡定,不要虛!我們慢慢來解釋。
其實我們只添加了兩個地方,labs()
與theme()
。
labs()
修改的是我們標簽的名稱。我們前面在aes()
中用了x =
,y =
,size =
以及colour =
,這些都是會有標簽名稱的,默認都是前面顯示的一些英文。而這里,我們只需要在labs()
中,寫上其對應的名稱即可。另外我們還附送一個title =
,就是我們圖像的標題。
theme()
更偏向于格式的修改。text = element_text(family = "STHeiti")
是對字體進行修改,變?yōu)楹隗w。Windows系統(tǒng)的各位,可以不添加這行,一樣會顯示前面labs()
中設定的中文。而如果是Mac或者Linux系統(tǒng),由于字體的缺失,會顯示成一個一個的框框,在圖像上顯示不了中文字。
第二行plot.title = element_text(hjust = 0.5)
是調整標題的位置,不加這行,標題會居左,加上才會居中。hjust = 0.5
其實就是左右移動的意思,0.5表示居中。
2. 零件——直方圖與條形圖
學完了零件——散點圖,我們再來學學其它零件。
我們先著重介紹直方圖與條形圖??赡軙杏腥藛?,這兩個不都是方塊兒條嗎,有什么區(qū)別。其實這兩個圖有本質的區(qū)別:一個是針對連續(xù)的變量(直方圖,histogram),將連續(xù)的變量砍成一段一段,再進行計數(shù);一個是針對離散的變量(條形圖,bar),直接對每類的樣本來數(shù)數(shù)。
1) 直方圖
p1 <- ggplot(mpg, aes(x = hwy)) p1 + geom_histogram()
這里不再用前面的變量p
,而是變成p1
,其映射是不需要y
的,只需要指定x =
數(shù)據(jù)集中的一個變量即可。然后+ geom_histogram()
會使用默認的參數(shù)進行直方圖的繪制。
2) 潤色
p1 + geom_histogram(aes(fill = factor(year), y = ..density..), alpha = 0.3, colour = 'black') + stat_density(geom = 'line', position = 'identity', size = 1.5, aes(colour = factor(year))) + facet_wrap(~ year, ncol = 1)
這里又進行了很多操作,下面將其進行分解。
首先是facet_wrap(~ year, ncol = 1)
按年分層,這里不再詳述。我們來聊聊geom_histogram()
中的參數(shù)。
fill = factor(year)
放在aes()
中表示按年進行填充顏色。為什么不用前面說到的colour =
?這是ggplot繪圖中一個非常重要的點?。ㄇ煤诎澹。τ诰€與點這種面積為0的結構,它的顏色就直接使用colour =
進行指定,而對條形圖,柱狀圖,扇形圖(特殊的柱狀圖),箱線圖等等有面積的圖形,其面積的顏色,我們需要用fill =
來指定。
添加y = ..density..
是將原本的頻數(shù)直方圖變成頻率密度直方圖,目的是為了在直方圖上添加密度曲線,兩者可以同時在一張圖上展現(xiàn)。
alpha = 0.3
是指定填充顏色的透明度, colour = 'black'
則是強制指定柱狀圖邊框的顏色為黑色。注意這兩個參數(shù)是放在aes()
外面,就是強制設定的意思。
stat_density()
表示添加統(tǒng)計學中的密度曲線,進行密度估計。geom = 'line'
指定為線形, position = 'identity'
表示一個一一映射, size = 1.5
是強制修改線的尺寸,為原先的1.5倍。最后的aes(colour = factor(year))
為修改擬合密度曲線的顏色,這里就是用的colour =
而不是fill =
3) 條形圖
p2 <- ggplot(mpg, aes(x=class)) p2 + geom_bar()
直接簡單地計算不同車種類在數(shù)據(jù)集中的數(shù)量,使用 + geom_bar()
,用默認參數(shù)即可繪制。我們直接從圖上也可以看出,geom_bar()
與geom_histogram()
,兩者繪制出來的圖形,一個有間隔,一個沒有間隔。這就正好對應了我們的離散與連續(xù)的區(qū)別。
我們想進一步比較不同年份,兩者的汽車種類的數(shù)量是否有差別,我們可以使用并立條形圖。
a. 并立條形圖
p3 <- ggplot(mpg, aes(class, fill = factor(year))) p3 + geom_bar(position = 'dodge')
只需添加參數(shù)position = 'dodge'
,并立條形圖帶回家!當然前面要說明用什么變量來并立,這里是年份:fill = factor(year)
同樣,我們可以做不同的條形圖。
b. 堆疊條形圖
p3 <- ggplot(mpg, aes(class, fill = factor(year))) p3 + geom_bar(position = 'dodge')
c. 分面條形圖
p3 + geom_bar(aes(fill = class)) + facet_wrap(~ year)
只需動一動手指,就可享受到買一送三的奢華體驗!
3. 零件——餅圖
餅圖可以說是條形圖的一種特殊形式,其繪制方法可以從代碼中看出。
p4 <- ggplot(mpg, aes(x = factor(1), fill = factor(class))) + geom_bar(width = 1) p4 + coord_polar(theta = "y")
首先x軸,只有一個柱子,柱子的寬度我們設置為1,geom_bar(width = 1)
,也就是鋪滿整個圖,而柱子按照class
變量來分類,并且是堆疊的(默認是堆疊條形圖)。這時的圖,也就是p4
是一個“千層餅”。然后我們按照y軸為原點,用coord_polar(theta = "y")
,把這個千層餅卷成千層卷,就成了我們的餅圖了。
后面會專門開個博客來細講餅圖的一些細節(jié)操作。
4. 零件——箱線圖
用geom_boxplot()
繪制箱線圖。
p5 <- ggplot(mpg, aes(class, hwy, fill = class)) p5 + geom_boxplot()
但是箱線圖怎么看都覺得不夠炫酷,我們可以用小提琴圖來使繪圖變得更加美麗動人。
5. 零件——小提琴圖
p5 + geom_violin(alpha = 0.3) + geom_jitter(shape = 21)
使用geom_violin()
繪制小提琴圖,同樣改變透明度。小提琴圖相比于箱線圖多了各個類別分布的信息,是圖像變得更加漂亮。
然后我們用geom_jitter()
添加擾動點,其實就是將數(shù)據(jù)點等間隔的排列,顯得更加高大上。其中的shape = 21
指定的是擾動點的形狀,我們用21號,也就是空心點(默認是實心點)。
至此,主要的零件都已經(jīng)介紹完成了。但我們可以看到,ggplot繪制出來的圖,背景都是灰格子,我們可不可以將其去掉呢?
當然可以!
6. 零件打磨
下面的一系列變化都基于前面繪制的箱線圖。我們通過修改theme()
中一系列參數(shù),來對背景進行修改。
# 不要灰底 p5 <- ggplot(mpg, aes(class, hwy, fill = class)) p6 <- p5 + geom_boxplot() p6 + theme_bw()
# 不要網(wǎng)格線 p6 + theme_bw() + theme(panel.grid = element_blank())
# 不要刻度標簽 p6 + theme_bw() + theme(panel.grid = element_blank(), axis.text = element_blank())
# 不要刻度線 p6 + theme_bw() + theme(panel.grid = element_blank(), axis.text = element_blank(), axis.ticks = element_blank())
# 不要xy軸標題 p6 + theme_bw() + theme(panel.grid = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(), axis.title = element_blank())
# 不要外層邊框 p6 + theme_bw() + theme(panel.grid = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(), axis.title = element_blank(), panel.border = element_blank())
# 不要圖例 p7 <- p6 + theme_bw() + theme(panel.grid = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(), axis.title = element_blank(), panel.border = element_blank(), legend.position = "none") p7
7. 超級變變變
到這里還有沒有進一步的提升空間呢?比如定制自己喜歡的配色?當然可以!
這里我們使用scale_fill_manual()
函數(shù),來對箱線圖中填充的顏色進行修改。觀察這個函數(shù),可以發(fā)現(xiàn),由于是箱線圖中填充的顏色,所以函數(shù)中間是fill。如果將中間的fill替換成colour,也就是scale_colour_manual()
,就可以對點與線的顏色進行定制了!
關于具體的配色,在文末會有推薦的網(wǎng)站,大家只需選中自己喜歡的配色,復制粘貼即可。
變
# 黃棕變 color = c('#ffffd4', '#fee391', '#fec44f', '#fe9929', '#ec7014', '#cc4c02', '#8c2d04') p7 + scale_fill_manual(values = color)
變!
# 紅藍變 color = c('#b2182b', '#ef8a62', '#fddbc7', '#f7f7f7', '#d1e5f0', '#67a9cf', '#2166ac') p7 + scale_fill_manual(values = color)
變??!
# 清新脫俗變 color = c('#fbb4ae', '#b3cde3', '#ccebc5', '#decbe4', '#fed9a6', '#ffffcc', '#e5d8bd') p7 + scale_fill_manual(values = color)
8. 其他常用零件
最后我們再介紹一些其他常用的零件:
函數(shù) | 圖形 | 選項 |
---|---|---|
geom_bar() | 條形圖 | color, fill, alpha |
geom_boxplot() | 箱線圖 | color, fill, alpha, notch, width |
geom_density() | 密度圖 | color, fill, alpha, linetype |
geom_histogram() | 直方圖 | color, fill, alpha, linetype, binwidth |
geom_hline() | 水平線 | color, alpha, linetype, size |
geom_jitter() | 抖動點 | color, alpha, size, shape |
geom_line() | 線圖 | color, alpha, linetype, size |
geom_point() | 散點圖 | color, alpha, size, shape |
geom_rug() | 地毯圖 | color, sides |
geom_smooth() | 擬合曲線 | method, formula, color, fill, linetype, size |
geom_text() | 文字注解 | … … |
geom_violin() | 小提琴圖 | color, fill, alpha, linetype |
geom_vline() | 垂線 | color, alpha, linetype, size |
… … | … … | … … |
七、實踐出真知
別人家的男票再帥,也是別人家的。
同理可證,代碼一定要自己一行一行的敲,并且每次可以自己多試幾種類似的情況,看看圖形會怎么變。帶著問題去學習,去探索,一定會很快入門ggplot2
這個大殺器!
八、學習資源
九、參考資料
ggplot2 Elegant Graphics for Data Analysis (use R)
最后本文的PPT(利用 R 包 xaringan 制作而成)于GitHub上可獲得:
https://github.com/kannyjyk/ggplot2-xaringan
以上就是R語言學習ggplot2繪制統(tǒng)計圖形包全面詳解的詳細內容,更多關于R語言ggplot2繪制統(tǒng)計圖形包的資料請關注腳本之家其它相關文章!
相關文章
R語言ComplexHeatmap繪制復雜熱圖heatmap
ComplexHeatmap可以繪制很復雜的熱圖,能滿足日常以及文章所需,本文介紹一下文章常見的復雜熱圖的繪制方式,含代碼,文章比較長,建議耐心看一下,也許就有你需要的熱圖2022-06-06pycharm實現(xiàn)R語言運行環(huán)境安裝配置的實現(xiàn)步驟
大多數(shù)人仍然使用RStudio進行R語言開發(fā)。與RStudio相比,PyCharm具有更多的優(yōu)勢,本文主要介紹了pycharm運行R語言腳本的實現(xiàn)步驟,文中通過圖文介紹的非常詳細,感興趣的可以了解一下2023-10-10R語言wilcoxon秩和檢驗及wilcoxon符號秩檢驗的操作
這篇文章主要介紹了R語言wilcoxon秩和檢驗及wilcoxon符號秩檢驗的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04