简介
在查阅文献的过程中,看到了几幅非常不错的出版图,今天就跟着小编一起学习下,他们是怎么使用 R 绘制出来的。
今天主要介绍 第三幅图(C)——两组数据的带抖动点箱线图,这种图形在小编的研究方向中,经常会用来比较不同参数估计方法(极大似然,贝叶斯方法等)的估计性能好坏。这幅图比较常规,难点在于前期的数据准备。
前两幅图的详细代码介绍可见:基于 R 语言的科研论文绘图技巧详解(2),基于 R 语言的科研论文绘图技巧详解(1)。后面几幅图会一一介绍,读者在学习过程中,可以将内部学到的知识点应用到自己的图形绘制中。推文已经将主要知识点进行罗列,更有利于读者学习和查阅。
那我们来看看,作者是怎么实现这个功能的吧,本文知识点较多,大家耐心学习,建议自己实践。对应代码、数据可在 GitHub - marco-meer/scifig_plot_examples_R: Scientific publication figure plotting examples with R[1] 中找到。
主要知识点
- 学会转化数据为图形所需的数据格式;
- 学会绘制三变量的箱线图;
- 学会绘制带抖动的散点图并修改透明度。
绘图
加载包
首先加载一些需要使用到的包。
library(ggplot2) # Grammar of graphics
设置主题
接下来,为了方便起见,作者在绘图前设置好了主题,并将该函数命名为 my_theme
。
这一部分在第一篇推文[]给出,代码将在文末中完整代码给出。
手动修改大部分面板,具体可以参考本篇文章[2]。或者观看我在 B 站发布的《R 语言可视化教程》,里面也有一些简单主题设置介绍。
导入数据
首先使用 read.csv()
导入数据,其中一个数据前几行如下所示。
data_Cwt_E8.5 = read.csv( "./data_Cwt_E8.5.csv") data_Cwt_E9.5 = read.csv( "./data_Cwt_E9.5.csv") data_Cwt_E10.5 = read.csv("./data_Cwt_E10.5.csv") data_Cwt_E11.5 = read.csv("./data_Cwt_E11.5.csv") data_Cmu_E8.5 = read.csv( "./data_Cmu_E8.5.csv") data_Cmu_E9.5 = read.csv( "./data_Cmu_E9.5.csv") data_Cmu_E10.5 = read.csv("./data_Cmu_E10.5.csv") data_Cmu_E11.5 = read.csv("./data_Cmu_E11.5.csv") ) head(data_Cwt_E8.5) # X42.0231534315441 # 1 48.60862 # 2 59.44292 # 3 44.47093 # 4 45.87919 # 5 37.43912 # 6 54.70787
之后,使用data.frame()
转化数据成 ggplot 所需要的格式。这里作者使用基础包中的 rep()
一列列的构造数据。当然如果你会使用 tidyverse
,可以换种方式整理数据。具体可以参考:《R语言教程》[3]和R 数据科学[4],或者公众号相应的数据科学系列文章。
data_C = data.frame( "type" = c( rep( "wildtype", nrow(data_Cwt_E8.5) + nrow(data_Cwt_E9.5) + nrow(data_Cwt_E10.5) + nrow(data_Cwt_E11. ), rep( "mutant", nrow(data_Cmu_E8.5) + nrow(data_Cmu_E9.5) + nrow(data_Cmu_E10.5) + nrow(data_Cmu_E11.5) ) ), "dev_stage" = c( rep("E8.5", nrow(data_Cwt_E8.5)), rep("E9.5", nrow(data_Cwt_E9.5)), rep("E10.5", nrow(data_Cwt_E10.5)), rep("E11.5", nrow(data_Cwt_E11.5)), rep("E8.5", nrow(data_Cmu_E8.5)), rep("E9.5", nrow(data_Cmu_E9.5)), rep("E10.5", nrow(data_Cmu_E10.5)), rep("E11.5", nrow(data_Cmu_E11.5)) ), "trachea_length" = c( data_Cwt_E8.5[, 1] , data_Cwt_E9.5[, 1] , data_Cwt_E10.5[, 1] , data_Cwt_E11.5[, 1] , data_Cmu_E8.5[, 1] , data_Cmu_E9.5[, 1] , data_Cmu_E10.5[, 1] , data_Cmu_E11.5[, 1] ) ) head(data_C) # type dev_stage trachea_length # 1 wildtype E8.5 48.60862 # 2 wildtype E8.5 59.44292 # 3 wildtype E8.5 44.47093 # 4 wildtype E8.5 45.87919 # 5 wildtype E8.5 37.43912 # 6 wildtype E8.5 54.70787
这里得到的数据,一共有三列,不同的数据集的数据值在 trachea_length
中,type
和 dev_stage
为离散数据。
绘图步骤详解
这幅图的绘图代码比较传统,但是还是有些细节需要和大家分享下。
基础版本
使用 geom_boxplot()
绘制箱线图,geom_point()
加入散点图,注意这里使用了 position = position_jitterdodge()
使得图形相对分散开,使用 alpha
修改图形透明度。
ggplot(data=data_C, aes(x=dev_stage, y=trachea_length, fill=type))+ geom_boxplot() + geom_point(position=position_jitterdodge(), # jitter for h-dist, dodge for grouped dists pch=21, #圆形 alpha=0.4)
可以看到,这幅图基本已经完成,为了提升美观,和图片的可读性,我们又做了后续的处理。
微调主题
首先,修改 x 轴标签 (scale_x_discrete
),填充颜色配色(scale_fill_manual
)。
scale_x_discrete(limits=c("E8.5","E9.5","E10.5","E11.5")) + scale_fill_manual(values=c('#f2a340','#998fc2'))
之后添加主题,使用先前设定好的主题函数 my_theme()
与其他细节调整。
my_theme()
的代码,在文末完整版代码中会给出。
my_theme() + theme(legend.position = c(0.18,0.95), legend.title = element_blank(), legend.key = element_blank() ) + scale_y_continuous(expand = c(0, 0), breaks=c(seq(20,120,by=20)), limits = c(20,120) )+ xlab("developmental stage (days)") + ylab(expression(paste("tracheal length (",~mu*m,")")))
完整代码
# Panel C ---- library(ggplot2) base_size = 12 my_theme <- function() { theme( aspect.ratio = 1, axis.line =element_line(colour = "black"), # shift axis text closer to axis bc ticks are facing inwards axis.text.x = element_text(size = base_size*0.8, color = "black", lineheight = 0.9, margin=unit(c(0.3,0.3,0.3,0.3), "cm")), axis.text.y = element_text(size = base_size*0.8, color = "black", lineheight = 0.9, margin=unit(c(0.3,0.3,0.3,0.3), "cm")), axis.ticks = element_line(color = "black", size = 0.2), axis.title.x = element_text(size = base_size, color = "black", margin = margin(t = -5)), # t (top), r (right), b (bottom), l (left) axis.title.y = element_text(size = base_size, color = "black", angle = 90, margin = margin(r = -5)), axis.ticks.length = unit(-0.3, "lines"), legend.background = element_rect(color = NA, fill = NA), legend.key = element_rect(color = "black", fill = "white"), legend.key.size = unit(0.5, "lines"), legend.key.height =NULL, legend.key.width = NULL, legend.text = element_text(size = 0.6*base_size, color = "black"), legend.title = element_text(size = 0.6*base_size, face = "bold", hjust = 0, color = "black"), legend.text.align = NULL, legend.title.align = NULL, legend.direction = "vertical", legend.box = NULL, panel.background = element_rect(fill = "white", color = NA), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), plot.title = element_text(size = base_size, color = "black"), ) } data_Cwt_E8.5 = read.csv( "./data_Cwt_E8.5.csv") data_Cwt_E9.5 = read.csv( "./data_Cwt_E9.5.csv") data_Cwt_E10.5 = read.csv("./data_Cwt_E10.5.csv") data_Cwt_E11.5 = read.csv("./data_Cwt_E11.5.csv") data_Cmu_E8.5 = read.csv( "./data_Cmu_E8.5.csv") data_Cmu_E9.5 = read.csv( "./data_Cmu_E9.5.csv") data_Cmu_E10.5 = read.csv("./data_Cmu_E10.5.csv") data_Cmu_E11.5 = read.csv("./data_Cmu_E11.5.csv") head(data_Cwt_E8.5) # format data to ggplot's liking data_C = data.frame( "type" = c( rep( "wildtype", nrow(data_Cwt_E8.5) + nrow(data_Cwt_E9.5) + nrow(data_Cwt_E10.5) + nrow(data_Cwt_E11.5) ), rep( "mutant", nrow(data_Cmu_E8.5) + nrow(data_Cmu_E9.5) + nrow(data_Cmu_E10.5) + nrow(data_Cmu_E11.5) ) ), "dev_stage" = c( rep("E8.5", nrow(data_Cwt_E8.5)), rep("E9.5", nrow(data_Cwt_E9.5)), rep("E10.5", nrow(data_Cwt_E10.5)), rep("E11.5", nrow(data_Cwt_E11.5)), rep("E8.5", nrow(data_Cmu_E8.5)), rep("E9.5", nrow(data_Cmu_E9.5)), rep("E10.5", nrow(data_Cmu_E10.5)), rep("E11.5", nrow(data_Cmu_E11.5)) ), "trachea_length" = c( data_Cwt_E8.5[, 1] , data_Cwt_E9.5[, 1] , data_Cwt_E10.5[, 1] , data_Cwt_E11.5[, 1] , data_Cmu_E8.5[, 1] , data_Cmu_E9.5[, 1] , data_Cmu_E10.5[, 1] , data_Cmu_E11.5[, 1] ) ) head(data_C) panel_C <- ggplot(data=data_C, aes(x=dev_stage, y=trachea_length, fill=type))+ geom_boxplot() + geom_point(position=position_jitterdodge(), # jitter for h-dist, dodge for grouped dists pch=21, #圆形 alpha=0.4) + # transparency scale_x_discrete(limits=c("E8.5","E9.5","E10.5","E11.5")) + scale_fill_manual(values=c('#f2a340','#998fc2')) + # custom colors in hex code my_theme() + theme(legend.position = c(0.18,0.95), legend.title = element_blank(), legend.key = element_blank() ) + scale_y_continuous(expand = c(0, 0), breaks=c(seq(20,120,by=20)), limits = c(20,120) )+ xlab("developmental stage (days)") + ylab(expression(paste("tracheal length (",~mu*m,")"))) panel_C