R成精系列-一页多图

在许多时候,我们需要将多张图表放在一起,当然我们可以用PS来处理,但是作为一个R的Master,怎么可能容忍这种事情发生。本文总结了如何在一页放多张绘画,供大家参考。在网友的提醒下,从新梳理了方法。

方法一:multiplot function

用函数来处理,但是效果不是很好。
This is the definition of multiplot. It can take any number of plot objects as arguments, or if it can take a list of plot objects passed to plotlist.

# Multiple plot function
#
# ggplot objects can be passed in ..., or to plotlist (as a list of ggplot objects)
# - cols:   Number of columns in layout
# - layout: A matrix specifying the layout. If present, 'cols' is ignored.
#
# If the layout is something like matrix(c(1,2,3,3), nrow=2, byrow=TRUE),
# then plot 1 will go in the upper left, 2 will go in the upper right, and
# 3 will go all the way across the bottom.
#
multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
  library(grid)

  # Make a list from the ... arguments and plotlist
  plots <- c(list(...), plotlist)

  numPlots = length(plots)

  # If layout is NULL, then use 'cols' to determine layout
  if (is.null(layout)) {
    # Make the panel
    # ncol: Number of columns of plots
    # nrow: Number of rows needed, calculated from # of cols
    layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
                    ncol = cols, nrow = ceiling(numPlots/cols))
  }

 if (numPlots==1) {
    print(plots[[1]])

  } else {
    # Set up the page
    grid.newpage()
    pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))

    # Make each plot, in the correct location
    for (i in 1:numPlots) {
      # Get the i,j matrix positions of the regions that contain this subplot
      matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))

      print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
                                      layout.pos.col = matchidx$col))
    }
  }
}

方法二:用ggpubr包

ggpubr包的全称为'ggplot2' Based Publication Ready Plots,基于ggplot2的出版级图形制作包。
Hadley Wickham创建的可视化包ggplot2可以流畅地进行优美的可视化,但是如果要通过ggplot2定制一套图形,尤其是适用于杂志期刊等出版物的图形,对于那些没有深入了解ggplot2的人来说就有点困难了,ggplot2的部分语法是很晦涩的。为此Alboukadel Kassambara创建了基于ggplot2的可视化包ggpubr用于绘制符合出版物要求的图形。
ggpubr的主要特点:
- ggpubr改写了一些ggplot的图形函数,省去了ggplot中许多晦涩的语法,对于初学者来说使用起来更容易。
-能够让非高级R用户绘制准出版级的精美图形;
- 更简单地设置图形的参数,包括颜色、标签;
- 轻松实现一页多图,添加图形注释;
- 为条形图、箱线图、线图等自动添加p值和显著性水平;
- ……
先放一张图


一页放多图
#安装ggpubr
library(ggpubr)
#未安装请用install.packages("ggpubr")安装
library(ggplot2)
library(tibble)
#生成图形数据
x<-1:1000
y<-1:1000
n<-rnorm(1000,0.5,1)
z<--x*(x-500)
data<-as.tibble(cbind(x,y,z,n,f))
#生成p1-p6六个ggplot图形对象
p1 <- ggplot(data = data,aes(x=n))+geom_density()
p2 <- ggplot(data = data,aes(x=n,y=y,color=x))+geom_point()
p3 <- ggplot(data = data,aes(x=x,y=z,color=x))+geom_line()+geom_point(x=x,y=n*100)
p4 <- ggplot(data = data,aes(x=n,color="red"))+geom_histogram()
p5 <- ggplot(data = data,aes(x=n,y=y*n,color=x))+geom_point()
p6 <- ggplot(data = data,aes(x=n))+geom_histogram(bins = 20,fill=1:20)+coord_polar()
#利用ggarrange将图像排列在一起
ggarrange(p1,p2,p3,p4,p5,p6,ncol = 2,nrow =3,widths = c(1,2),heights = c(1,1,2))

解读
一页放置多张图主要利用ggarrange()函数:

ggarrange(..., plotlist = NULL, ncol = NULL, nrow = NULL, labels = NULL,label.x = 0, label.y = 1, hjust = -0.5, vjust = 1.5,
font.label = list(size = 14, color = "black", face = "bold", family = NULL),
align = c("none", "h", "v", "hv"), widths = 1, heights = 1,
legend = NULL, common.legend = FALSE)

  • ...需要画的图对象,plotlist需要画的图清单,ncolnrow是要排列成几行几列
  • labels每个图的标签,label.x label.y hjust vjust font.label都是调整labels的位置参数,
  • align各个图的排列方式,是纵向还是横向排列,widthsheights调整各图的长宽比列
  • legend是各图的图例,commn.legend公共的图例

函数能画 "ggplot", "gtable", "grob", "recordedplot"等类, 或图形函数。

方法三:用gredExtra包grid.arrange函数

library(gridExtra)
#安装ggpubr时,会依赖于该包
grid.arrange(p1,p2,p3,p4,p5,p6,ncol=3,nrow=2)

方法四:用cowplot包的plot_grid函数

library("cowplot")
plot_grid(p1,p2,p3,p4,p5,p6,   labels = c("A", "B", "C","D","E","F"), ncol = 2, nrow = 3)

方法五: R的基础绘图函数par()layout()函数

许多时候我们会舍本逐末,追求一些高级的函数而忘记了R的基础绘图函数。对于R的基础画图函数画的图可以用parlayout处理。
par用于设置简单的几行几列,参数简单。
layout同过一个参数矩阵,构造图形布局。
同时同过width和height参数控制布局的比例,实现图形的任意布置。

  • 首先将一幅图进行切块。
  • 然后构建布局矩阵。
  • 设置长宽比例。
  • 最后填充图形。


    par画出的结果
布局矩阵

layout结果
attach(mtcars)
par(mfrow=c(3,2))
hist(wt)
hist(mpg)
hist(disp)
hist(carb)
hist(wt)
hist(mpg)
#用layout函数,将整张图切成9块,3*3矩阵,12放一张图,3和6放一张,89放一张,4和5 单独一张图;
#构造布局矩阵
mat<-matrix(c(1,1,2,3,4,2,0,5,5),3,3,byrow=TRUE)
mat
layout(mat)
hist(wt)
hist(mpg)
hist(disp)
hist(carb)
hist(wt)

上面的的方法存在一个问题,不同的函数画出的图没法放在一个页面里面。

方法六:grid包viewport函数

这里就会用到grid包,grid包以前是第三方包,随着其重要性,grid随着R包直接打包下载。grid包的核心是viewport,viewport中又可以嵌套viewport,多个viewport可以构成一颗树,详细的用法,我后续再出一篇博文介绍。
针对本文的例子我们用viewport将p1-p6。


grid一页多图
#新建一个绘图
grid.newpage()
#构建布局举证
l1<-grid.layout(4, 4)
#主节点
vpmain<-viewport(layout =l1 ,name = "main")
pushViewport(vpmain)
print(p1, vp=viewport(layout.pos.row=2:3, layout.pos.col=1:2))
print(p2, vp=viewport(layout.pos.row=1, layout.pos.col=1:2))
print(p3, vp=viewport(layout.pos.row=2:3, layout.pos.col=3))
print(p4, vp=viewport(layout.pos.row=1, layout.pos.col=3))
print(p5, vp=viewport(layout.pos.row=1:3, layout.pos.col=4))
print(p6, vp=viewport(layout.pos.row=4, layout.pos.col=4))

参考:
ggpubr: Publication Ready Plots

sessionInfo()信息

sessionInfo()

R version 3.5.1 (2018-07-02)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.6
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib
locale:
[1] zh_CN.UTF-8/zh_CN.UTF-8/zh_CN.UTF-8/C/zh_CN.UTF-8/zh_CN.UTF-8
attached base packages:
 [1] grid      parallel  stats4    stats     graphics  grDevices utils     datasets  methods  
[10] base     

参考网址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349

推荐阅读更多精彩内容