• 七 R语言|箱须图、饼图的绘制


    仿制一张箱须图,内容涉及boxplot()函数的使用以及利用jitter在箱子内部显示样品分布

    原文链接:七 R语言|箱须图、饼图的绘制 

    原图展示

    依然与前两天推文的参考图来自同一篇文章,文章使用marker微生物计算了一个疾病指数,之后使用箱须图比较了疾病和健康样本中疾病指数的差异。

    今天就来仿照绘制一下这幅图,我绘制出来的最终图像是下面这个样子。

    还是照例先给出完成的绘图代码:

    gdi <- read.table("GDI.txt",header = TRUE,row.names = 1,sep = "\t")
    tiff(filename = "GDI.tif",width = 5400,height = 7200,compression = "lzw",res = 600,type = "windows")par(mar = c(5,8,1,2))par(xpd = TRUE)box <- boxplot(GDI~Group,data = gdi,col = "grey80",lwd = 3,range = 0,axes = FALSE,ylim = c(-0.15,0.15),xlab = "",ylab = "")axis(side = 1,at = c(1,2),labels = c("",""),lwd = 3)segments(x0 = 0.42,y0 = -0.162,x1 = 2.5,y1 = -0.162,lwd = 4)text(x = c(1,2),y = -0.175,labels = c("Disease","Healthy"),cex = 3)axis(side = 2,at = c(-0.15,-0.10,-0.05,0,0.05,0.10,0.15),labels = c("","","","","","",""),lwd = 3)text(x = 0.37,y = c(-0.15,-0.05,0.05,0.15),labels = c("-0.15","-0.05","0.05","0.15"),adj = c(1,0.5),cex = 2.5)segments(x0 = 0.42,y0 = -0.162,x1 = 0.42,y1 = 0.16,lwd = 4)mtext(side = 2,text = "GDI index",cex = 3.5,line = 5)segments(x0 = 1,y0 = 0.08,x1 = 1,y1 = 0.11,lwd = 4)segments(x0 = 1,y0 = 0.11,x1 = 2,y1 = 0.11,lwd = 4)segments(x0 = 2,y0 = 0.11,x1 = 2,y1 = -0.07,lwd = 4)text(x = 1.5,y = 0.117,labels = "***",cex = 6)jitter <- jitter(c(rep(1,11),rep(2,11)))points(x = jitter,y = gdi$GDI,col = "black",bg = "white",cex = 3,lwd= 3,pch = 21)dev.off()

    绘图数据十分简单,就是两列数据,第一列为用于绘图的具体数值,第二列是分组


    绘图过程详解

    数据导入和绘图区设置

    首先导入绘图数据并设置绘图区大小。​​​​​​​

    gdi <- read.table("GDI.txt",header = TRUE,row.names = 1,sep = "\t")
    par(mar = c(5,8,1,2))par(xpd = TRUE)

    ⚠️ 下方和左侧要留出大一点的区域,用于样品组的名称和纵坐标,而上方和右侧的边界要尽量小

    将绘图参数定义为可以在绘图区外显示,从而使得绘图参数的显示能够在绘图边界显示。

    箱须图绘制

    首先进行基本箱须图的绘制。​​​​​​​

    box <- boxplot(GDI~Group,data = gdi,col = "grey80",lwd = 3,range = 0,axes = FALSE,ylim = c(-0.15,0.15),xlab = "",ylab = "")

    boxplot()命令​​​​​​​

    boxplot(x, ..., range = 1.5, width = NULL, varwidth = FALSE, notch = FALSE, outline = TRUEnames, plot = TRUE, border = par("fg"), col = NULL, log = "", pars = list(boxwex = 0.8, staplewex = 0.5, outwex = 0.5),horizontal = FALSEadd = FALSEat = NULL)

    各参数意义:

    • range规定box外的whiskers数据的选定标准;

    • width规定box的相对宽度;

    • varwidth为True时,按照width的比例基于绘图区的大小进行箱的绘制;

    • notch规定是否将长条形的箱图绘制为在中位数位置有凹槽的箱图;

    • outline是否绘制outliers;

    • names各组箱的标签名

    • plot是否绘图;

    • border规定outline的颜色;

    • col规定箱体的填充颜色;

    • log规定x中的数据是否进行log变换;

    • boxwex、staplewex和outwex规定图像中不同部分的线宽;

    • horizontal是否绘制水平图;

    • add规定是否在现有图像的基础上进行绘图;

    • at规定绘图的位置。

    在本次绘图中,使用公式定义绘图数据和方式

    GDI~Group,~左边为响应变量,右边为解释变量,可以简单的理解为左边为y轴绘图数据,右边为x轴绘图数据。

    添加坐标轴

    由于单纯的使用axis()命令添加坐标轴,无法呈现出一种坐标轴在原点交叉的状态,因而使用axis()和segment()配合,最终达到x和y轴交汇并向外侧部分延伸的效果。​​​​​​​

    axis(side = 1,at = c(1,2),labels = c("",""),lwd = 3)segments(x0 = 0.42,y0 = -0.162,x1 = 2.5,y1 = -0.162,lwd = 4)axis(side = 2,at = c(-0.15,-0.10,-0.05,0,0.05,0.10,0.15),labels = c("","","","","","",""),lwd = 3)text(x = 0.37,y = c(-0.15,-0.05,0.05,0.15),labels = c("-0.15","-0.05","0.05","0.15"),adj = c(1,0.5),cex = 2.5)segments(x0 = 0.42,y0 = -0.162,x1 = 0.42,y1 = 0.16,lwd = 4)

    ⚠️ 通过调整线段的位置和长度,时其能够正好覆盖原本的坐标轴,并且在两个坐标轴交汇的位置结束。

    之后添加分组标签和纵轴标签。​​​​​​​

    text(x = c(1,2),y = -0.175,labels = c("Disease","Healthy"),cex = 3)mtext(side = 2,text = "GDI index",cex = 3.5,line = 5)

     
    

    差异性检验结果展示

    使用线段的形式构成一个U型框连接两个条形,之后利用文本给出组间差异性检验结果。​​​​​​​

    segments(x0 = 1,y0 = 0.08,x1 = 1,y1 = 0.11,lwd = 4)segments(x0 = 1,y0 = 0.11,x1 = 2,y1 = 0.11,lwd = 4)segments(x0 = 2,y0 = 0.11,x1 = 2,y1 = -0.07,lwd = 4)text(x = 1.5,y = 0.117,labels = "***",cex = 6)

    具体的参数数值根据绘图数据进行调整。

    样品分布点添加

    使用jitter添加样品在不同组内的分布情况,首先要定义jitter参数。

    jitter <- jitter(c(rep(1,11),rep(2,11)))

    这里要根据绘图数据进行调整,jitter用于定义分布点在x轴的位置,我的数据只有两组,两个箱子在x轴的位置分别为1和2,每组有11个样本,因而jitter为连续11个1之后连续11个2.

    ⚠️ 我的数据中分组为“Disease”和“Healthy”,R中默认是以字母顺序展示相关的参数,因而“Disease”位于左侧,而“Healthy”位于右侧,而我的绘图数据文件同样是“Disease”组在前,“Healthy”在后,如果你的绘图数据中排在前面的分组字母顺序靠后,则需要调整jitter的顺序,使得jitter中x轴对应箱子的位置与绘图数据分组排序保持一致

    比如如果我的绘图数据中“Healthy”组排在前面,那么我就需要修改命令为:

    jitter <- jitter(c(rep(2,11),rep(1,11)))

    接下来添加样本分布点。​​​​​​​

    points(x = jitter,y = gdi$GDI,col = "black",bg = "white",cex = 3,lwd= 3,pch = 21)

    ⚠️ jitter添加的样本点在y轴的位置是根据绘图数据固定的,而在x轴的横向分布是随机的,因而可以多生成几次图像之后选择最好的展示效果

    饼图绘制方法,主要涉及的函数就是pie()和pie3D()

    pie函数绘制饼图

    pie函数是R自带的一个基础函数,专门用于绘制饼图,还是照例先给出使用参数。​​​​​​​

    pie(x, labels = names(x), edges = 200, radius = 0.8,    clockwise = FALSE, init.angle = if(clockwise) 90 else 0,    density = NULL, angle = 45, col = NULL, border = NULL,    lty = NULL, main = NULL, ...)

    各参数意义:

    • x,绘制饼图的数据,数据的大小在饼图中用面积反应;

    • labels,图像中不同扇形的标签,默认为数据的名字,也可自定义;

    • edges,规定饼图的圆环采用多少个连续的边构成,也就是说可以将饼图变为多边形图;

    • radius,规定圆的半径;

    • colckwise,TRUE时饼图为顺时针方向绘制,FALSE时为逆时针方向绘制;

    • init.angle,规定饼图第一个数值开始绘制时的起始角度;

    • density,是否绘制阴影线;

    • angle,阴影线的角度;

    • col,扇区的颜色;

    • border,边界的颜色;

    • lty,边界的线型

    • main,标题内容。

    接下来进入正题,开始图像的绘制,首先随便建立一个绘图的数据,饼图的数据其实很简单,就两列,一列是绘制饼图个扇区的数值,另一个是其对应的名字。​​​​​​​

    a <- c("A","B","C","D","E","F","G")<- c(17,13,8,5,10,2,9)

    之后对数据进行一些处理,计算每一个绘图数据所占的比例,并制作响应的标签。​​​​​​​

    pct <- round(b/sum(b)*100)  lab <- paste(a," ",pct,"%",sep="")d <- data.frame(a,b,lab)

    将绘图数据按照数值进行排序。

    d<- d[order(d[,"b"]),]

    接下来绘制图像。​​​​​​​

    library(RColorBrewer)pie(d[,"b"],labels=NA,clockwise=T,col=brewer.pal(7,"Set1"),    border="white",radius=0.9,cex=0.8,main="Pie chart")#添加图例legend("right",legend = lab,bty = "n",inset = c(-0.4,0),       xpd = T,fill = brewer.pal(7,"Set1"))

    处理以图例形式展示各扇形形成之外,还有一种方式是在扇形的附近进行文字标注。​​​​​​​

    pie(d$b,labels=d$lab,col=rainbow(length(d$lab)),    main="Pie Chart with Percentage")


    pie3D绘制3D饼图

    pie3D是属于plotrix包的一个函数,可以绘制具有3D结构的饼图,其具体参数如下:​​​​​​​

    pie3D(x,edges=NA,radius=1,height=0.1,  theta=pi/6,start=0,border=par("fg"),  col=NULL,labels=NULL,labelpos=NULL,  labelcol=par("fg"),labelcex=1.5,  sector.order=NULL,explode=0,shade=0.8,  mar=c(4,4,4,4),pty="s",...)

    各参数意义:

    • x,代表饼图各部分比例的数值向量;

    • edges,形成圆形所需的线的个数,可以用此参数绘制多边形图;

    • radius,饼图的半径;

    • height,饼图的高度;

    • theta,投射图的观察角度;

    • start,在什么角度开始绘制第一个部分;

    • border,各部分边界的颜色;

    • col,各部分的填充颜色;

    • labels,各部分的标签;

    • labelpos,各部分标签的位置;

    • labelcol,标签的颜色;

    • labelcex,标签的大小;

    • sector.order,规定各部分的绘制顺序;

    • explode,饼图各部分的间距;

    • shade,规定3D图的阴影;

    • mar,饼图的边界;

    • pty,规定饼图是否绘制在正方体区域中,s代表正方体,m代表长方体。

    还是用刚才的数据进行图形的绘制。​​​​​​​

    library(plotrix)pie3D(d$b, labels=d$lab, explode=0.1, height = 0.2,      radius = 0.8, main="3D Pie Chart")

    声明: 本号旨在传播、传递、交流,对相关文章内容观点保持中立态度。涉及内容如有侵权或其他问题,请与本号联系,第一时间做出撤回。

  • 相关阅读:
    八大元素定位方法(Python/Java)
    数据科学AB测试(说人话系列)
    聊聊我的试用期总结(不知名公司算法工程师
    CSS3 按钮
    元素定位(绝对、相对、粘滞、固定)
    Spring5之IOC容器的底层原理简单理解
    pyhton内置的数据类型(二)
    deepin(深度)系统下qt5.12.0的程序打包发布到linux云服务器上
    记录--5个知识点,让 Vue3 开发更加丝滑
    如何将CAD的内置对话框作为当前对话框的子对话框调出
  • 原文地址:https://blog.csdn.net/weixin_58566962/article/details/126629699