出處: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循環輸出了如下的動態圖,詳細的代碼請移步
例四 火山圖
火山圖是散點圖的一種,能夠快速的辨別出大型數據集重復變量之間的差異,具體的介紹可以參考wiki和Colin 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輸出
|


