2020-03-30 復(fù)習(xí)ggplot2

學(xué)習(xí)資料:https://mp.weixin.qq.com/s/r6pfSU-88e86cUjxp3yFnQ 網(wǎng)紅教授Y書原創(chuàng)公眾號教程ggplot2專題

一、理解數(shù)據(jù)和映射

下面以內(nèi)置數(shù)據(jù)集鉆石的數(shù)據(jù)為例,這份數(shù)據(jù)總共有53940行10列,隨機取一個子集來畫圖。

rm(list = ls())
library(ggplot2)
data(diamonds)
dim(diamonds)
set.seed(100)
dat <- diamonds[sample(nrow(diamonds), 1000), ]
head(dat)

查看隨機取的子集前幾行

> dim(diamonds)
[1] 53940    10
> head(dat)
# A tibble: 6 x 10
  carat cut     color clarity depth table price     x     y     z
  <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  1.26 Ideal   G     SI1      59.6    57  6738  7.08  7.04  4.21
2  0.7  Ideal   D     VS2      62.7    57  3448  5.65  5.67  3.55
3  0.36 Ideal   F     SI1      62      56   770  4.59  4.54  2.83
4  2.1  Premium J     SI2      59.1    58 12494  8.46  8.4   4.98
5  1.21 Premium D     SI2      59.7    58  4946  7.06  6.96  4.19
6  2    Good    E     SI2      64.7    57 15393  7.75  7.86  5.05

以克拉數(shù)為X軸變量,價格為Y軸變量。

p <- ggplot(data = dat, mapping = aes(x = carat, y = price))
p + geom_point()
圖1,理解映射

如果想將切工(cut)映射到形狀屬性。在aes中添加參數(shù):

p <- ggplot(data=dat, mapping=aes(x=carat, y=price, shape=cut))
p+geom_point()
圖2,在映射里面加一個參數(shù)改變了顯示的形狀

再加一個參數(shù)添加顏色:

p <- ggplot(data=dat, mapping=aes(x=carat, y=price, shape=cut, colour=color))
p+geom_point()
圖3,添加顏色映射

二、理解幾何對象(Geometric)

在上面的例子中,各種屬性映射由ggplot函數(shù)執(zhí)行,只需要加一個圖層,使用geom_point()告訴ggplot要畫散點,于是所有的屬性都映射到散點上。

geom_point()完成的就是幾何對象的映射,ggplot2提供了各種幾何對象映射,如geom_histogram用于直方圖,geom_bar用于畫柱狀圖,geom_boxplot用于畫箱線圖等等。ggplot2提供了很多的geom_xxx函數(shù)來完成相應(yīng)的幾何映射,可以滿足我們對各種圖形繪制的需求。

geom_abline     geom_area   
geom_bar        geom_bin2d
geom_blank      geom_boxplot    
geom_contour    geom_crossbar
geom_density    geom_density2d  
geom_dotplot    geom_errorbar
geom_errorbarh  geom_freqpoly   
geom_hex        geom_histogram
geom_hline      geom_jitter     
geom_line       geom_linerange
geom_map        geom_path   
geom_point      geom_pointrange
geom_polygon    geom_quantile   
geom_raster     geom_rect
geom_ribbon     geom_rug    
geom_segment    geom_smooth
geom_step       geom_text   
geom_tile       geom_violin
geom_vline

不同的幾何對象,要求的屬性會有些不同,這些屬性也可以在幾何對象映射時提供,比如上一圖,也可以用以下語法來畫:

p <- ggplot(dat)
p+geom_point(aes(x=carat, y=price, shape=cut, colour=color))

下面就是幾個常見的幾何映射示例:

直方圖

直方圖最容易,提供一個x變量,畫出數(shù)據(jù)的分布。

ggplot(dat)+geom_histogram(aes(x=price, fill=cut))
圖4

展示效果不太好,也可以將其分開,side-by-side地畫直方圖。

ggplot(dat)+geom_histogram(aes(x=price, fill=cut), position="dodge")
圖5在圖4的基礎(chǔ)上改進了

還可以使用position=”fill”,按照相對比例來畫。就是常見的堆積柱狀圖

ggplot(dat)+geom_histogram(aes(x=price, fill=cut), position="fill")
圖6,堆積柱狀圖

柱狀圖非常適合于畫分類變量。

柱狀圖是用來表示計數(shù)數(shù)據(jù)的,但在生物界卻被經(jīng)常拿來表示均值,加上誤差來表示數(shù)據(jù)分布,這可以通常圖層來實現(xiàn),我將在圖層一節(jié)中給出實例。

密度函數(shù)圖

密度函數(shù)圖,數(shù)據(jù)和映射和直方圖是一樣的,唯一不同的是幾何對象函數(shù),geom_histogram告訴ggplot要畫直方圖,而geom_density則是畫密度函數(shù)圖,直接套用即可:

ggplot(dat)+geom_density(aes(x=price, colour=cut))
密度直方圖

改變一個參數(shù)

ggplot(dat)+geom_density(aes(x=price,fill=clarity))

結(jié)果如下:


密度直方圖

colour參數(shù)指定的是曲線的顏色,而fill是往曲線下面填充顏色。

箱式圖

數(shù)據(jù)量比較大的時候,用直方圖和密度函數(shù)圖是表示數(shù)據(jù)分布的好方法,而在數(shù)據(jù)量較少的時候,比如很多的生物實驗,很多時候大家都是使用柱狀圖+errorbar的形式來表示,不過這種方法的信息量非常低,被Nature Methods吐槽,這種情況推薦使用boxplot(箱式圖或箱線圖)。

ggplot(dat)+geom_boxplot(aes(x=cut, y=price,fill=color))
圖9.箱線圖

更換幾何對象映射函數(shù)geom_boxplot將數(shù)據(jù)映射到箱式圖上,按切工(cut)分類,對價格(price)變量畫箱式圖,再分開按照color變量填充顏色。

三、修改標(biāo)尺

分類屬性映射標(biāo)尺修改

在對圖形屬性進行映射之后,使用標(biāo)尺可以控制這些屬性的顯示方式,比如坐標(biāo)刻度,可能通過標(biāo)尺,將坐標(biāo)進行對數(shù)變換;比如顏色屬性,也可以通過標(biāo)尺,進行改變。

ggplot(dat)+geom_point(aes(x=carat, y=price, shape=cut, colour=color))+
  scale_y_log10()+
  scale_colour_manual(values=rainbow(7))

結(jié)果如下:


圖10

以第一部分數(shù)據(jù)和映射示例中所畫散點圖為例,將Y軸坐標(biāo)進行l(wèi)og10變換,再自己定義顏色為彩虹色。

統(tǒng)計變換(Statistics)標(biāo)尺修改

統(tǒng)計變換對原始數(shù)據(jù)進行某種計算,然后在圖上表示出來,例如對散點圖上加一條回歸線。

ggplot(dat, aes(x=carat, y=price))+
  geom_point()+
  scale_y_log10()+
  stat_smooth()
圖11

注意:

  • 這里就不按顏色、切工來分了,不然ggplot會按不同的分類變量分別做回歸,圖就很亂,如果我們需要這樣做,我們可以使用分面。
  • 這里,aes所提供的參數(shù),就通過ggplot提供,而不是提供給geom_point,因為ggplot里的參數(shù),相當(dāng)于全局變量,geom_point()和stat_smooth()都知道x,y的映射,如果只提供給geom_point(),則相當(dāng)于是局部變量,geom_point知道這種映射,而stat_smooth不知道,當(dāng)然你再給stat_smooth也提供x,y的映射,不過共用的映射,還是提供給ggplot更好。

ggplot2提供了多種統(tǒng)計變換方式:

stat_abline       stat_contour      stat_identity     stat_summary
stat_bin          stat_density      stat_qq           stat_summary2d
stat_bin2d        stat_density2d    stat_quantile     stat_summary_hex
stat_bindot       stat_ecdf         stat_smooth       stat_unique
stat_binhex       stat_function     stat_spoke        stat_vline
stat_boxplot      stat_hline        stat_sum          stat_ydensity

統(tǒng)計變換是非常重要的功能,我們可以自己寫函數(shù),基于原始數(shù)據(jù)做某種計算,并在圖上表現(xiàn)出來,也可以通過它改變geom_xxx函數(shù)畫圖的默認統(tǒng)計參數(shù)。

四、坐標(biāo)系統(tǒng)(Coordinante)

坐標(biāo)系統(tǒng)控制坐標(biāo)軸,可以進行變換,例如XY軸翻轉(zhuǎn),笛卡爾坐標(biāo)和極坐標(biāo)轉(zhuǎn)換,以滿足我們的各種需求。

坐標(biāo)軸翻轉(zhuǎn)由coord_flip()函數(shù)實現(xiàn)

ggplot(dat)+geom_bar(aes(x=cut, fill=cut))+coord_flip()

圖12

而轉(zhuǎn)換成極坐標(biāo)可以由coord_polar()函數(shù)映射實現(xiàn):

ggplot(dat)+geom_bar(aes(x=factor(1), fill=cut))+coord_polar(theta="y")
圖14

這也是為什么之前介紹常用圖形畫法時沒有提及餅圖的原因,餅圖實際上就是柱狀圖,只不過是使用極坐標(biāo)而已,柱狀圖的高度,對應(yīng)于餅圖的弧度,餅圖并不推薦,因為人類的眼睛比較弧度的能力比不上比較高度(柱狀圖)。
還可以畫靶心圖:

ggplot(dat)+geom_bar(aes(x=factor(1), fill=cut))+coord_polar()
圖14靶心圖

風(fēng)玫瑰圖(windrose)

ggplot(dat)+geom_bar(aes(x=clarity, fill=cut))+coord_polar()
圖15

五、圖層

圖層概念在上面的散點圖加回歸曲線已經(jīng)展示過了,還可以展示更復(fù)雜的,這就是ggplot2的優(yōu)秀之處了,Y叔舉了個蝙蝠圖的例子我就不重復(fù)了。

六、分面(Facet)

在《ggplot2: 數(shù)據(jù)分析與圖形藝術(shù)》一書的翻譯中,一開始譯者把facet翻譯成切片,Y叔推薦翻譯成分面,分面可以讓我們按照某種給定的條件,對數(shù)據(jù)進行分組,然后分別畫圖。
在統(tǒng)計變換一節(jié)中,提到如果按切工分組作回歸線,顯然圖會很亂,有了分面功能,我們可以分別作圖。

ggplot(dat, aes(x=carat, y=price))+
  geom_point(aes(colour=cut))+
  scale_y_log10() +
  facet_wrap(~cut)+
  stat_smooth()
圖16,分面圖

七、主題(Theme)

通過ggplot畫圖之后,我們可能還需要對圖進行定制,像title, xlab,
ylab這些高頻需要用到的,自不用說,ggplot2提供了ggtitle(),
xlab()和ylab()來實現(xiàn)。 比如:

p <- ggplot(dat)+geom_boxplot(aes(x=cut, y=price,fill=color))
p + ggtitle("Price vs Cut")+xlab("Cut")+ylab("Price")

圖17

但是這個遠遠滿足不了需求,我們需要改變字體,字體大小,坐標(biāo)軸,背景等各種元素,這需要通過theme()函數(shù)來完成。

ggplot2提供一些已經(jīng)寫好的主題,比如theme_grey()為默認主題,我經(jīng)常用的theme_bw()為白色背景的主題,還有theme_classic()主題,和R的基礎(chǔ)畫圖函數(shù)較像。

別外ggthemes包提供了一些主題可供使用,包括:

theme_economist theme_economist_white
theme_wsj       theme_excel
theme_few       theme_foundation
theme_igray     theme_solarized
theme_stata     theme_tufte
library(ggthemes)
p + theme_wsj()
圖18

二維密度圖

在這個文檔里,為了作圖方便,我們使用diamonds數(shù)據(jù)集的一個子集,如果使用全集,數(shù)據(jù)量太大,畫出來散點就糊了,這種情況可以使用二維密度力來呈現(xiàn)。

ggplot(dat, aes(carat, price))+ 
  stat_density2d(aes(fill = ..level..), geom="polygon")+ 
  scale_fill_continuous(high='darkred',low='darkgreen')
圖19

數(shù)據(jù)太多就容易糊。

ggplot2實例

Y叔列了蝴蝶圖,囧字圖等好玩搞怪的圖,最后以生物界中常用的柱狀圖+誤差圖為實例,展示了ggplot2非常靈活的圖層。以他2011年發(fā)表的文章Phosphoproteome profile of human lung cancer cell line A549中的westernblot數(shù)據(jù)為例。這個實例展示了圖層,標(biāo)尺,主題,注釋和各種細節(jié)微調(diào)多種元素。
收藏一下:

Normal <- c(0.83, 0.79, 0.99, 0.69)
Cancer <- c(0.56, 0.56, 0.64, 0.52)
m <- c(mean(Normal), mean(Cancer))
s <- c(sd(Normal), sd(Cancer))
d <- data.frame(V=c("Normal", "Cancer"), mean=m, sd=s)
d$V <- factor(d$V, levels=c("Normal", "Cancer"))

p <- ggplot(d, aes(V, mean, fill=V, width=.5))
p <- p+geom_errorbar(aes(ymin=mean, ymax=mean+sd, width=.2), 
                     position=position_dodge(width=.8))
p <- p + geom_bar(stat="identity", position=position_dodge(width=.8), colour="black")
p <- p + scale_fill_manual(values=c("grey80", "white"))
p <- p + theme_bw() +theme(legend.position="none") + xlab("") + ylab("")
p <- p + theme(axis.text.x = element_text(face="bold", size=12), 
               axis.text.y = element_text(face="bold", size=12))
p <- p+scale_y_continuous(expand=c(0,0), limits=c(0, 1.2), breaks=seq(0, 1.2, by=.2))
p <- p+geom_segment(aes(x=1, y=.98, xend=1, yend=1.1))
p <- p+geom_segment(aes(x=2, y=.65, xend=2, yend=1.1))
p <- p+geom_segment(aes(x=1, y=1.1, xend=2, yend=1.1))
p <- p + annotate("text", x=1.5, y=1.08, label="*")
print(p)
圖20

在這個專題中還有2個神器:

install.packages("ggThemeAssist")

然后愉快的用鼠標(biāo)點點點就能完成細節(jié)了。

ggplot2不單單能出更多更好看的圖,而且出圖并不比GraphPad Prism困難,除了有調(diào)整細節(jié)的插件,還有點點鼠標(biāo)就可以畫圖的插件- esquisse。

你可以使用下面的指令安裝:

devtools::install_github("dreamRs/esquisse")

然后就可以在RStudio中通過點鼠標(biāo),愉快地用ggplot2畫圖了

esquisse::esquisser()

具體使用方法可以點上面的鏈接看Y叔編輯的動圖,也可以參考簡書作者的教程:http://www.itdecent.cn/p/ecfa0d640250
探索數(shù)據(jù)的時候可以用,而且還可以導(dǎo)出畫圖代碼,簡直不要太優(yōu)秀!
這感覺就跟抄作業(yè)一樣。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容