R使用笔记: ggplot2
本笔记内容:
最近工作中遇到的分析需求:按照要求的分组画boxplot和PcoA的散点图。对画各种图的实现方法,一些具体问题的解决方法等。
- Long data和wide data之间的转换, 及其作用
- 作图细节:box的颜色,散点分布,调整label的角度, 修改label: theme(), labs()等
- 调整横坐标labels的顺序:设置factor中level的顺序
- facet_grid(): 将一个Plot按照分组绘制多个Plot,并在theme()中设置它的属性
- ggplot2的一些通用规律
- PCoA:ade4和ggplot2
- legend()用法
- theme()快捷设置
long data和wide data之间的转换, 及其作用
关于Long data和wide data之间的转换及其意义,我写过在python中的用法,见python学习:pandas学习笔记(三)中Pandas.melt()的用法。在这里是用R实现。一般ggplot2需要使用Long data. 比方说如下所示的数据cond1
, cond2
和control
你都想用ggplot2画boxplot出来,那必须转化为Long data, 把每个样本的测量值分一列,测得是cond1还是cond2一列。
了解更多参考这个链接
t <- read.table(header=TRUE, text='
subject sex control cond1 cond2
1 M 7.9 12.3 10.7
2 F 6.3 10.6 11.1
3 F 9.5 13.1 13.8
4 M 11.5 13.4 12.9
')
t_long <- melt(t, id.vars = c('subject', 'sex')) # id.vars为不合并的列,即保留的列
t_long
subject sex variable value
1 1 M control 7.9
2 2 F control 6.3
3 3 F control 9.5
4 4 M control 11.5
5 1 M cond1 12.3
6 2 F cond1 10.6
7 3 F cond1 13.1
8 4 M cond1 13.4
9 1 M cond2 10.7
10 2 F cond2 11.1
11 3 F cond2 13.8
12 4 M cond2 12.9
作图细节:box的颜色,散点分布等
以以上数据为例,按照variable的分组画三个boxplot:
ggplot(t_long, aes(x = variable, y = value)) +
geom_boxplot()
ggplot(t_long, aes(x = variable, y = value, fill = variable)) +
geom_boxplot() + geom_point(position = position_jitterdodge()) +
# 在box中加上点,让点随机排列,不要忘记用加号衔接
scale_fill_brewer(palette = "Set3") + # 使用brewer.pal中的调色盘
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
# theme()用来设置labels, 以及labels与各轴之间的角度
labs(x = "condition", y = "condition_values")
# 重命名labels
ggplot(t_long, aes(x = variable, y = value, fill = sex)) +
geom_boxplot(position = position_dodge(0.8)) +
# 因为把大boxplot拆分成两个,设置这两个小boxplot之间的距离
geom_point(position = position_jitterdodge()) +
scale_fill_brewer(palette = "Set3") +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
labs(x = "condition", y = "condition_values")
# ggplot(aes(fill = ))变化了,将每个variable拆分成sex的两个小组画图
可以参考这个链接,一个基础又详细的教程。
调整横坐标labels的顺序:设置factor中level的顺序
c <- t_long$value
t_long$variable <- factor(t_long$variable ,
levels =unique(t_long$variable[order(-c)]))
# 让整个boxplot大致降序排列,需要将包含box类别的变量设置为factor,在level中设置为按照值来降序排列
# ....真是麻烦啊...如果有什么别的好办法还请告诉我
将boxplot降序或者升序排列,在fill = 变量非常多,把整个图拉的很长的情况下很有用,可以很明确的看出数据的规律。最好能在input dataframe的时候就把数据整理成一定顺序。
还有一个办法:
ggplot(t_long, aes(x = reorder(variable, value, FUN = median)), y = ...)
# 在ggplot的aes()里指定按照中位数大小排列
facet_grid():将一个Plot按照分组绘制多个Plot
使用一个R自带的数据集为例:data(ToothGrowth)
,这个数据集有两个分组,一个是supp, 一个是dose, 记得需要先把dose转化为factor再行后续操作。
t <- data(ToothGrowth)
t$dose <- as.factor(t$dose)
p2 <- ggplot(t, aes(x = supp, y = len, fill = supp)) +
geom_boxplot(position = position_dodge(0.8)) +
geom_point(position = position_jitterdodge()) +
scale_fill_brewer(palette = "Set3") +
facet_grid(dose ~ .,scales = "free") + # 按照dose的分组将plot分成3个不同的dose子plot; scales的意思是按照各分组数据的极限值设置各子plot的scale, 不统一。
theme(axis.title = element_text(size = 15),
axis.text.x = element_text(size = 15),
axis.text.y = element_text(size =12),
strip.text.y = element_text(size = 12), # 调整不同子plot的标签字体大小
panel.spacing = unit(1, "lines")) + # 调整不同子plot之间距离大小
labs(x = "", y = "")
不设置facet_grid的图
设置facet_grid形成子plot
更多参考以下链接:
http://www.sthda.com/english/wiki/ggplot2-customize-how-to-personalize-easily-ggplot2-graphs-in-r-statistical-software
http://www.sthda.com/english/wiki/ggplot2-facet-split-a-plot-into-a-matrix-of-panels
ggplot2的一些通用规律
ggplot(dataframe, aes(x = X, y = Y, fill = group, color = group)) +
# 设置了fill则将"可以fill的形状"填充起来,比方说椭圆,比方说boxplot, barplot等。不设置fill什么颜色则ggplot2默认填充。用scale_fill_**设置填充颜色
# color用于设置点或者线的颜色,比方说boxplot的外框描线...
+ geom_point(aes(color = group), alpha = 0.8, size = 4)
# 在aes()中设置点的颜色,但是点的透明度,大小等属性注意在aes()之外设置
# 在aes()之外,position = position_jitterdodge()将点按照分组分开
+ geom_boxplot()
+ scale_color_manual(values = c(xxx,xxx,xxx...))
# scale_color_**用于自定义color的颜色,即点,线的颜色
+ scale_fill_manual(values = c(xxx, xxx, xxx...))
# scale_fill_**用于自定义fill的颜色,即填充颜色
PCoA:ade4和ggplot2
ade4包:以距离矩阵为input, 用cmdscale()获取坐标轴位置,用s.class画图并按照分组聚类。可是没有坐标轴信息,也不知道这两维分别可以有多少variance explained
unifrac <- read.table(...)
meta <- read.csv(...)
mds <- cmdscale(unifrac,k = 2, eig = TRUE)
mds_m <- mds$points
group <- as.factor(meta$grouping) # 把分组信息转化为Factor
plot_color <- brewer.pal(5,"Set2")[group] # 便于给每个样本分组并上色
s.class(mds_m, col=unique(plot_color), cpoint = 1, fac = group, cstar = 1, cellipse = 1)
# 按照分组形成聚类椭圆(wheel)
# 用fake data画的
ggplot2包:需要把metadata和cmdscale()得到的mds坐标合并为一个dataframe作为input, 并使用上面ade4包得到的mds$eig计算variance explained
可以参考一篇宏基因组公众号的文章: 扩增子统计绘图2散点图:Beta多样性
eig <- mds$eig
mds_df <- data.frame(mds_m)
mds_meta <- cbind(mds_df, meta)
# X1, X2为各点坐标信息的col_name,grouping为分组信息的col_name
# 都在mds_meta中
ggplot(mds_meta, aes(x = X1, y = X2)) +
geom_point(aes(color = factor(grouping)), size = 3) +
scale_color_discrete(name = "grouping") +
stat_ellipse(aes(x = X1, y = X2, color = grouping), type = "norm") +
labs(x = paste("PCoA 1 (", format(100*eig[1]/sum(eig), digits = 4), "%)",sep = ""),
y = paste("PCoA 2 (", format(100*eig[2]/sum(eig), digits = 4), "%)",sep = "")
)
# 手动添加variance explained的label
legend()用法
group <- as.factor(data$group)
color <- brewer.pal(length(levels(group)), "Set1")
heatmap.2(x...)
par(lend = 1)
legend(0.88, 0.998, # 也可以直接指定:“bottomright”, “bottom”, “bottomleft”, “left”, “topleft”, “top”, “topright”, “right”, “center”
legend = levels(group), # 指定legend中写什么字
col = color, #指定颜色
lty = 1, # 显示为直线型色块
lwd = 10, # 显示色块的宽度
text.col = "black",# legend字体颜色
pch = c(.., .., .....) # 如果你的legend lty没有设置,想设置成不同形状不同颜色的legend,则使用pch指定色块的形状,具体代码对应的形状见下图
cex = 0.8) # 设置字体大小
pch对应的具体形状
参考连接:https://www.rdocumentation.org/packages/graphics/versions/3.5.0/topics/legend
theme()快捷设置
default为+ theme_gray()
常用 theme_classic()
, 详见以下链接
http://ggplot2.tidyverse.org/reference/ggtheme.html
theme_classic(size = n)
设置默认classic的主题中字体大小
theme(legend.position = "none")
则去除legend
给boxplot加上统计检验结果及P值
https://www.r-bloggers.com/add-p-values-and-significance-levels-to-ggplots/
ggarange() 把图组合在一起,公用legend等
string_aes()的用法
unexpected symbol error in parse(text = str)的解决方法
画韦恩图
在plot上加significant的问题:which_pair_to_use 来解决只显示sig的pairs