ggplot2入門與進階(下)


出處:http://www.cellyse.com/how_to_use_gggplot2_part2/

更多實戰

例一 Michaelis-Menten動力學方程

這個例子中采用出自文獻中的一組有關於浮萍氮攝取的數據,共2兩個變量8個觀測值,其中底物濃度與浮萍的氮取速率之間可以通過M-M動力學方程來進行描述。在這個例子中首先通過nls()根據M-M動力學方程進行模型擬合,然后用預測值進行了ggplot2繪圖,主要采用了R里面的數學表示方法plotmath在圖中展示了公式,並通過ggplot2種的theme對圖像進行了修飾。需要注意的在geom_text()並不能直接使用expression,需要開啟parse = TURE,且用字符串表示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
conc < - c( 2.856829 , 5.005303 , 7.519473 , 22.101664 , 27.769976 , 39.198025 , 45.483269 , 203.784238 )
rate < - c( 14.58342 , 24.74123 , 31.34551 , 72.96985 , 77.50099 , 96.08794 , 96.96624 , 108.88374 )
L.minor < - data.frame(conc, rate)
L.minor.m1 < - nls(rate ~ Vm * conc / (K + conc), data = L.minor, #采用M-M動力學方程
                   start = list (K = 20 , Vm = 120 ), #初始值設置為K=20,Vm=120
                   trace = TRUE) #占線擬合過程
#確定x軸范圍並構建數據集
min < - range (L.minor$conc)[ 1 ]
max < - range (L.minor$conc)[ 2 ]
line.data < - data.frame(conc = seq( min , max , length.out = 1000 ))
#用模型預測數據構建數據集
line.data$p.predict < - predict(L.minor.m1, newdata = line.data)
 
require(ggplot2)
M_Mfunction < - ggplot() +
   geom_point(aes(x = conc, y = rate), data = L.minor,
              alpha = 0.5 , size = 5 , color = "red" ) +
   geom_line(aes(x = conc, y = p.predict), data = line.data,
             size = 1 , color = "blue" ) +
   scale_x_continuous(
     name = expression(Substrate ~~ concentration(mmol ~~ m^ 3 )), #采用expression來表示數學公式
     breaks = seq( 0 , 200 , by = 25 )) +
   scale_y_continuous(
     name = "Uptake rate (weight/h)" ,
     breaks = seq( 0 , 120 , by = 10 )) +
   geom_text(aes(x = 100 , y = 60 ),
             label = "bolditalic(f(list(x, (list(K, V[m])))) == frac(V[m]%.%x, K+x))" ,
             #注意 geom_text中如果用expression()來進行表達,必須開啟parse = TRUE
             #同時以字符串""的形式表示,不能使用expression
             parse = TRUE, 
             size = 5 , family = "times"
             ) +
   theme_bw() +
   theme(
         axis.title.x = element_text(size = 16 ),
         axis.title.y = element_text(size = 16 ),
         axis.text.x = element_text(size = 12 ),
         axis.text.y = element_text(size = 12 ))


例二 熱圖

熱圖是一種極好的數據可視化方式,能夠清楚的顯示出多維數據之間的關聯性和差異性,糗世界已經為我們展現了R里面所常用的heatmap,ggplot2和lattice3種熱圖繪制方式,當然隨着R的不斷進步,已經有多種包提供了更豐富和更簡單的熱圖繪制方式,例如gplots中的heatmap.2,pheatmap,heatmap.plus等等。ggplot2進行熱圖的繪制也十分方便,熱圖的關鍵是聚類,兩個可行的方案是對聚類結果進行排序和將聚類結果因子化后固定,通過結合plyr包,可以很方便的實現。這里采用一組來源於WHO國家數據來對熱圖的繪制進行,首先數據標准化和正態化后按Index的D(為各國的人口數據)進行排序,再將其因子化后固定,用geom_tile()進行熱圖的繪制,在ggplot2種已能通過scale_fill_gradient2在三種基本色進行漸變。

數據下載

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
WHO< - read.csv( "WHO.csv" , header = TRUE)
require(plyr)
#按總人口數排列數據
WHO< - arrange(WHO, desc(D))
#將數據的名字轉換為因子,並固定已拍好的country,
#同理可以按照聚類的結果進行排列
WHO< - transform(WHO, Country = factor(Country, levels = unique(Country)))
 
require(reshape2)
require(ggplot2)
require(scales)
require(grid)
#melt數據
m.WHO < - melt(WHO)
#標准化,每排數據映射到按最小值和最大值映射到(0,1)區間
m.WHO < - ddply(m.WHO, .(variable), transform, rescale = rescale(value))
#標准化並正態化數據
s.WHO < - ddply(m.WHO, .(variable), transform, rescale = scale(value))
require(ggplot2)
p< - ggplot(s.WHO, aes(variable, Country)) +
   #用tile來進行繪熱力圖
   geom_tile(aes(fill = rescale)) +
   scale_fill_gradient2(mid = "black" , high = "red" , low = "green" , name = "Intensity" ) +
   labs(x = "Country" , y = "Index" , face = "bold" ) +
   theme_bw() +
   theme(
     axis.title.x = element_text(size = 16 ),
     axis.title.y = element_text(size = 16 ),
     axis.text.x = element_text(size = 12 , colour = "grey50" ),
     axis.text.y = element_text(size = 12 , colour = "grey50" ),
     legend.title = element_text(size = 14 ),
     legend.text = element_text(size = 12 ),
     legend.key.size = unit( 0.8 , "cm" )) #需要載入grid包來調整legend的大小

 

例三 動態圖

相信很多人都被Hans Rosling在TED和BCC展現的動態散點圖所驚艷到,這是一種多維數據展現方式,並成功的加入了時間這一維度,各路牛人都用不同的手段進行了實現,精彩的作品例如d3.js,和基於google charts API的googlevis。統計之都的魔王大人也用ggplot2結合animation包和ffmpeg進行了繪制。但ggplot2生成動態圖比較簡陋,主要的原理是一次輸出多張按年份排列的圖片,再將這些圖片按順序結合生成視頻或動態圖。在dataguru的課程上我使用循環並結合paste循環輸出了如下的動態圖,詳細的代碼請移步

 

例四 火山圖

火山圖是散點圖的一種,能夠快速的辨別出大型數據集重復變量之間的差異,具體的介紹可以參考wikiColin Gillespie的博客,下面的代碼和圖是使用ggplot2的實現方式。

數據下載

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
require(ggplot2)
##change theme##
old_theme < - theme_update(
   axis.ticks = element_line(colour = "black" ),
   panel.grid.major = element_blank(),
   panel.grid.minor = element_blank(),
   panel.background = element_blank(),
   axis.line = element_line(size = 0.5 )
)
##Highlight genes that have an absolute fold change > 2 and a p-value < Bonferroni cut-off
a < - read.table( "flu.txt" ,header = TRUE,sep = "\t" ,)
P.Value < - c(a$P.Value)
FC < - c(a$FC)
df < - data.frame(P.Value, FC)
df.G < - subset(df, log2(FC) < - 1 & P.Value < 0.05 ) #define Green
df.G < - cbind(df.G, rep( 1 , nrow(df.G)))
colnames(df.G)[ 3 ] < - "Color"
df.B < - subset(df, (log2(FC) > = - 1 & log2(FC) < = 1 ) | P.Value > = 0.05 ) #define Black
df.B < - cbind(df.B, rep( 2 , nrow(df.B)))
colnames(df.B)[ 3 ] < - "Color"
df.R < - subset(df, log2(FC) > 1 & P.Value < 0.05 ) #define Red
df.R < - cbind(df.R, rep( 3 , nrow(df.R)))
colnames(df.R)[ 3 ] < - "Color"
df.t < - rbind(df.G, df.B, df.R)
df.t$Color < - as.factor(df.t$Color)
##Construct the plot object
ggplot(data = df.t, aes(x = log2(FC), y = - log10(P.Value), color = Color )) +
   geom_point(alpha = 0.5 , size = 1.75 ) +
   theme( legend.position = "none" ) +
   xlim(c( - 5 , 5 )) + ylim(c( 0 , 20 )) +
   scale_color_manual(values = c( "green" , "black" , "red" )) +
   labs(x = expression(log[ 2 ](FC)), y = expression( - log[ 10 ](P.Value))) +
   theme(axis.title.x = element_text(size = 20 ),
         axis.text.x = element_text(size = 15 )) +
   theme(axis.title.y = element_text(size = 20 ),
         axis.text.y = element_text(size = 15 ))

 

 

再說高質量圖片輸出

繪圖完成后最后一步便是圖片輸出,高質量的圖片輸出讓人賞心悅目,而不正確的輸出方式或者直接采用截圖的方式從圖形設備中截取,得到的圖片往往是低劣的。一幅高質量的圖片應當控制圖片尺寸和字體大小,並對矢量圖進行高質量渲染,即所謂的抗鋸齒。R語言通過支持Cairo矢量圖形處理的類庫,可以創建高質量的矢量圖形(PDF,PostScript,SVG) 和 位圖(PNG,JPEG, TIFF),同時支持在后台程序中高質量渲染。在ggplot2我比較推薦的圖片輸出格式為經過Cairo包處理的PDF,因為PDF格式體積小,同時可以儲存為其他任何格式,隨后再將PDF儲存為eps格式並在Photoshop中打開做最終的調整,例如調整比例、色彩空間和dpi(一般雜志和出版社要求dpi=300以上)等。額外需要注意的是ggplot2中的字體大小問題,在cookbook-r一書中指出,在ggplot2中絕大多數情況下,size的大小以mm記,詳細的討論也可以參考stackover的討論,而在theme()中對element_text()里的size進行調整,此時的size是以磅值(points, pts)來進行表示。
下面以3種ggplot2種常用的圖片輸出方式,輸出一幅主標題為20pts,橫縱坐標標題為15pts,長為80mm(3.15in),寬為60mm(2.36in)的圖為例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
require(ggplot2)
require(Cairo)
ggplot() +
   geom_text(aes(x = 16 , y = 16 ), label = "ABC" , size = 11.28 ) + #尺寸為11.28mm,即為32磅
   geom_text(aes(x = 16 , y = 14.5 ), label = "ABC" , size = 32 ) + #尺寸為32mm
   labs( x = "x axis" , y = "y axis" ) +
   ylim( c( 14 , 16.5 )) +
   xlim( c( 15.75 , 16.25 )) +
   theme(
     axis.title.x = element_text(size = 32 ), #尺寸為32磅
     axis.title.y = element_text(size = 32 )) #尺寸為32磅
 
x < - seq( - 4 , 4 , length.out = 1000 )
y < - dnorm(x)
data < - data.frame(x, y)
 
#用Cairo包輸出
require(Cairo)
CairoPDF( "plot1.pdf" , 3.15 , 3.15 ) #單位為英寸
ggplot(data, aes(x = x, y = y)) + geom_line(size = 1 ) +
   theme_bw()
dev.off() #關閉圖像設備,同時儲存圖片
 
plot2 < - ggplot(data, aes(x = x, y = y)) + geom_line(size = 1 ) +
   theme_bw()
#用ggsave輸出,默認即以用Cairo包進行抗鋸齒處理
ggsave( "plot2.pdf" , plot2, width = 3.15 , height = 3.15 )
 
#RStudio輸出
 
 
更改字體

更改默認字體或者采用中文輸出圖片是十分惱人的一件事情,好在我們還有各種拓展包和功能強大的Rstudio來實現。

 

用extrafont輸出英文字體

extrafont包能夠直接調用字體文件,再通過Ghostscript(需要安裝)將寫入的字體插入生成的PDF中,具體代碼可參考了作者說明

好玩的showtext

邱怡軒大神寫了一個好玩的showtext,確實好好玩~

簡單易用的RStudio輸出

最簡單實用的輸出方法還是使用RStudio輸出,直接調用系統字體(我的是win7,mac和linux下還沒有試過)並輸出即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#showtext
require(showtext)
require(ggplot2)
require(Cairo)
font.add( "BlackoakStd" , "C://Windows//Fonts//BlackoakStd.otf" )
font.add( "BrushScriptStd" , "C://Windows//Fonts//BrushScriptStd.otf" )
font.add( "times" , "C://Windows//Fonts//times.ttf" )
font.add( "STHUPO" , "C://Windows//Fonts//STHUPO.ttf" )
CairoPDF( "showtext_output" , 8 , 8 )
showtext.begin()
ggplot() +
   geom_text(aes(x = 16 , y = 16.25 ), label = "Blackoak Std" , size = 8 ,
             family = "BlackoakStd" ) +
   geom_text(aes(x = 16 , y = 16 ), label = "Brush Script Std" , size = 16 ,
             family = "BrushScriptStd" ) +
   geom_text(aes(x = 16 , y = 15.75 ), label = "Times New Roman" , size = 16 ,
             family = "times" ) +
   geom_text(aes(x = 16 , y = 15.50 ), label = "華文琥珀" , size = 16 ,
             family = "STHUPO" ) +
   ylim(c( 15.25 , 16.50 )) +
   labs(x = " ", y = " ") +
   theme_bw() #在用RStudio輸出


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM