前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >R- 组合图(折线+条形图)绘制

R- 组合图(折线+条形图)绘制

作者头像
DataCharm
发布2021-02-22 12:04:23
3K0
发布2021-02-22 12:04:23
举报

就是下面这张图,在途中用条形图展示了不同季节样本浮游动物的组成情况,同时使用带误差棒的折线图来表示浮游动物生物量的变化,相当于在一幅图中同时展示了群落的相对丰度和绝对丰度

对于这种图我一直都是使用R的base函数来完成的,代码其事并不复杂涉及到的无非就是plot、barplot、axis、text、mtext、par等几个基本的函数。

使用base函数进行画图有一个缺点,就是一旦更换数据之后,图像中各种元素所处的位置会发生一些变化,也就是说不同的数据使用同样的代码进行绘图,需要根据出图来调整一些参数的具体数值

其实我更喜欢分享这种绘图代码,虽然比ggplot2的代码用起来要费事一些,但是可以强迫大家去学习代码中每一个参数的具体含义,通过修改参数的数值也能够理解代码如何调整,通过几个图像的学习,你就会发现自己画一个图也不是什么难事,我想这才是分享应该有的意义。

绘图过程

接下来介绍绘图的过程,既然是同时展示相对丰度和绝对丰度,那就必然需要两个绘图数据文件。

第一个文件是个组样本中不同物种相对丰度的平均值,另一个文件为个组样品中总生物量的平均值及其标准偏差。

请在公众号后台回复“Season”获取绘图示例文件。

首先要导入绘图数据。

代码语言:javascript
复制
dr <- read.table("R.Season.txt",header = TRUE,row.names = 1,sep = "\t")
dt <- read.table("Season.txt",header = TRUE,row.names = 1,sep = "\t")

将相对丰度文件转换为矩阵形式,并定义一个色卡用于颜色填充。

代码语言:javascript
复制
dr <- as.matrix(dr)
Palette <- c("#B2182B","#E69F00","#56B4E9","#009E73","#F0E442","#0072B2","#D55E00","#CC79A7","#CC6666","#9999CC","#66CC99")

对相对丰度文件进行处理,选取丰度排名前十的物种,并将剩余物种合并为Others。

代码语言:javascript
复制
sum <- apply(dr,1,sum)
dr <- cbind(dr,sum)
dr <- as.data.frame(dr)
dr <- dr[order(dr[,"sum"],decreasing = T),]
dr <- subset(dr, select = -sum)
dr <- dr[1:10,]
dr <- t(dr)
sum <- apply(dr,1,sum) 
Others <- 1-sum
dr <- cbind(dr,Others)
dr <- t(dr)

这里的逻辑很简单,首先计算每一个物种在所有样本中相对丰度的总和,之后按照其数值高低对数据进行重排,保留丰度排名前十的物种数据,之后计算这些物种在各样本中的丰度总和,进而求出Others对应的数值。

接下来进行绘图,首先定义图像输出形式和绘图区域范围。

代码语言:javascript
复制
png(filename = "Season.zoo.png",width = 12000,height = 9000,res = 600)
par(mar=c(6.3,8,4,20))
par(xpd = TRUE)

png表示绘图完成后以png格式输出图像,height和width代表图像输出的大小,注意该数值如果进行修改,会导致图像中各元素的位置发生变化,需要根据出图效果进行调整。

在par中使用mar定义绘图区域,4个数值分别对应下、左、上、右4个方向的绘图边界,这里由于要在右侧放置图里,因此右侧数值较大。

xpd = TRUE表示可以将图像绘制在绘图区之外,也就是定义的边界位置也能显示图像。

接下来绘制条形图。

代码语言:javascript
复制
bar1 <- barplot(dr,names.arg = c(rep("",3)),space = 0.1,col = Palette,
                border = "white",xlim = c(0,5),axes = F,ylim = c(0,1))
axis(side = 2,at = c(0,0.2,0.4,0.6,0.8,1),labels = FALSE,line = -1.55,lwd = 5,lwd.ticks = 5)
text(x=-0.14,y = c(0,0.2,0.4,0.6,0.8,1),labels = c("0%","20%","40%","60%","80%","100%"),
     font = 2,cex = 2.5,adj = c(1,0.5))

使用barplot绘制条形图,这里要注意应用axes = F将坐标轴去除,并使用names.arg将横坐标的标签定义为空,注意有几组其对应的数字就设置为几,xlim的范围从0至样本组数目+2。

使用axis在左侧添加相对丰度对应的坐标轴,side = 2代表左侧。

使用text添加其对应的标签,注意这里的line用于调整坐标轴的位置,如果左侧空间不够,需要调整上一步par内mar中的第二个数值。

条形图绘制完成之后绘制折线图。

代码语言:javascript
复制
par(xpd = TRUE)
par(new = T)
par(mar = c(6.3,8,4,20))
plot(bar1,y=dt$Total,type = "b",col = "black",axes = F,xlim = c(0,5),xlab = "",ylab = "",
     ylim = c(-1000,3000),pch = 19,bg = "black",cex = 5,lwd = 7)

注意这里因为是一副新的图像,所以一定要添加par(new = T),不然条形图就被覆盖了,这里绘图区域要与上一步条形图的绘图区保持一致。

使用plot添加折线图,type定义为b表示折线+点,axes同样设置为F去除坐标轴,xlim保持与条形图一致,xlab和ylab均设置为空,ylim根据具体的数据进行调整。

使用axis和text添加横坐标轴及其对应标签。

代码语言:javascript
复制
axis(side = 1,at = bar1,line = 1,labels = FALSE,lwd = 5,lwd.ticks = 5)
text(x = bar1,y = -1350,labels = colnames(dr),cex = 3.2, font = 2)

side = 1为下方,at = bar1表示按照条形图的横坐标匹配坐标轴间隔,labels = FALSE表示不显示标签。

使用text添加横坐标标签时,要注意y的数值,这个需要根据上一步折线图中ylim的范围进行调整。

使用axis在右侧添加总生物量对应的纵坐标,side = 4表示右侧,at根据折线图ylim的范围进行调整,line调整坐标轴与图像的距离。

代码语言:javascript
复制
axis(side = 4,at = c(-1000,0,1000,2000,3000),line = -23,las = 2,cex.axis = 2.5,lwd = 5,lwd.ticks = 5,font = 2)
mtext("Relative abundance",side = 2,line = 5,font = 2,cex = 4)
mtext("Total zooplankton density (ind./L)",side = 4,line = -15,font = 2,cex = 4)

接下来使用mtext添加两个纵坐标轴对应的labe文字,注意根据出图情况调整line的数值,以保证文字处于合理的位置。

使用arrows函数以箭头的形式添加折线图的误差棒。

代码语言:javascript
复制
arrows(x0 = bar1,y0 = dt$Total,x1 = bar1,y1 = dt$Total+dt$Sd,col = "black",angle = 90,length = 0.5,lwd = 7)
arrows(x0 = bar1,y0 = dt$Total,x1 = bar1,y1 = dt$Total-dt$Sd,col = "black",angle = 90,length = 0.5,lwd = 7)

angle = 90表示箭头的两边都与中间的线成90度夹角,也就形成了误差棒应有的效果。

最后添加图例。

代码语言:javascript
复制
par(xpd=TRUE)
par(new = T)
plot(0:1, 0:1, type="n", xlab="",ylab="", axes=FALSE)
legend(0.85,1.0,legend = rownames(dr),fill = Palette,bty = "n",ncol = 1,cex = 2.5,text.font = 4)
legend(0.87,0.52,legend = c("Total zooplankton"),pch = 19,col = "black",bty = "n",cex = 2.5,pt.cex = 3.3,text.font = 2,text.width = 0.2,x.intersp = 1.35,lty = 1,lwd = 5)
dev.off()

添加图例之前,同样要使用par(new = T)定义一个新的绘图空间,之后使用plot函数添加一个完全空白的图像。

这里需要添加两个图里,分别对应条形图和折线图。

要注意调整两个图里添加的位置,以及折线图腿中文字与图形元素的间距,是的两个图里看起来像是一个。

最后使用dev.off()关闭绘图区域并保存图像。

⚠️使用该代码绘制自己数据的图像前,一定要做到能看懂代码,知道根据需求调整什么参数!!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DataCharm 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 绘图过程
相关产品与服务
图数据库 KonisGraph
图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档