出处: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输出
|