# ggplot2学习笔记之图形排列

R语言基本绘图函数中可以利用par()以及layout()来进行图形排列，但是这两个函数对于ggplot图则不太适用，本文主要讲解如何对多ggplot图形多页面进行排列。主要讲解如何利用包gridExtra、cowplot以及ggpubr中的函数进行图形排列。

## 绘制图形

``````#load packages
library(gridExtra)
library(cowplot)
library(ggpubr)
#dataset ToothGrowth and mtcars
mtcars\$name <- rownames(mtcars)
mtcars\$cyl <- as.factor(mtcars\$cyl)
``````
``````#First let's create some plots
#Box plot(bxp)
bxp <- ggboxplot(ToothGrowth, x="dose", y="len", color = "dose", palette = "jco")
#Dot plot(dp)
dp <- ggdotplot(ToothGrowth, x="dose", y="len", color = "dose", palette = "jco", binwidth = 1)
#An ordered Bar plot(bp)
bp <- ggbarplot(mtcars, x="name", y="mpg", fill="cyl", #change fill color by cyl
color="white", #Set bar border colors to white
palette = "jco", #jco jourbal color palette
sort.val = "asc", #Sort the value in ascending order
sort.by.groups = TRUE, #Sort inside each group
x.text.angle=90 #Rotate vertically x axis texts )
bp+font("x.text", size = 8)
``````
``````#Scatter plots(sp)
conf.int = TRUE, #Add confidence interval
color = "cyl", palette = "jco",#Color by group cyl
shape = "cyl" #Change point shape by groups cyl
)+
stat_cor(aes(color=cyl), label.x = 3) #Add correlation coefficientsp
``````

## 图形排列

• ggpubr::ggarrange()
``````ggarrange(bxp, dp, bp+rremove("x.text"), labels = c("A", "B", "C"), ncol = 2, nrow = 2)
``````
• cowplot::plot.grid()
``````plot_grid(bxp, dp, bp+rremove("x.text"), labels = c("A", "B", "C"), ncol = 2, nrow = 2)
``````
• gridExtra::grid.arrange()
``````grid.arrange(bxp, dp, bp+rremove("x.text"), ncol=2, nrow=2)
``````

## 排列图形注释

• ggpubr::annotate_figure()
``````figure <- ggarrange(sp, bp+font("x.text", size = 10), ncol = 1, nrow = 2)
annotate_figure(figure, top=text_grob("Visualizing mpg", color = "red",
face = "bold", size=14), bottom = text_grob("Data source:\n mtcars data set",
color = "blue", hjust = 1, x=1, face = "italic", size=10), left = text_grob("Figure arranged using ggpubr", color = "green", rot = 90),
right = "I'm done, thanks :-)!", fig.lab = "Figure 1", fig.lab.face = "bold")
``````

## 绘图面板对齐

• 绘制生存曲线
``````library(survival)
#Fit survival curves
fit <- survfit(Surv(time, status)~adhere, data = colon)
library(survminer)
ggsurv <- ggsurvplot(fit, data = colon, palette = "jco", #jco palette
pval = TRUE, pval.coord=c(500, 0.4), #Add p-value
risk.table = TRUE #Add risk table)
names(ggsurv)
``````
``````## [1] "plot" "table" "data.survplot" "data.survtable"
``````

ggsurv是一个包含两部分的list

• plot：生存曲线
• table：风险表
可以用ggarrange()进行排列这两者
``````ggarrange(ggsurv\$plot, ggsurv\$table, heights = c(2, 0.7), ncol = 1, nrow = 2)
``````

``````ggarrange(ggsurv\$plot, ggsurv\$table, heights = c(2, 0.7), ncol = 1, nrow = 2, align = "v")
``````

## 改变排列图的行列

``````ggarrange(sp, #First row with scatter plot(sp)
ggarrange(bxp, dp, ncol = 2, labels = c("B","C")),#Second row with box and dot plot
nrow = 2, labels = "A" #Labels of the scatter plot)
``````

## R包cowplot

cowplot::ggdraw()可以将图形置于特定位置, ggdraw()首先会初始化一个绘图面板， 接下来draw_plot()则是将图形绘制于初始化的绘图面板中，通过参数设置可以将图形置于特定位置。

``````draw_plot(plot, x=0, y=0, width=1, height=1)
``````

• plot:将要放置的图形
• x,y:控制图形位置
• width,height:图形的宽度和高度
• draw_plot_label():为图形添加标签
``````draw_plot_label(label, x=0, y=1, size=16, ...)
``````

• label:标签
• x,y:控制标签位置
• size:标签字体大小

``````ggdraw()+ draw_plot(bxp, x=0, y=0.5, width=0.5, height = 0.5)+
draw_plot(dp, x=0.5, y=0.5, width = 0.5, height = 0.5)+
draw_plot(bp, x=0, y=0, width = 1.5, height = 0.5)+
draw_plot_label(label = c("A", "B", "C"), size = 15, x=c(0, 0.5, 0), y=c(1, 1, 0.5))
``````

## R包gridExtra

gridExtra::arrangeGrop()改变行列分布

``````grid.arrange(sp, #First row with one plot spaning over 2 columns
arrangeGrob(bxp, dp, ncol = 2), #Second row with 2plots in 2 different columns
nrow=2) #number of rows
``````

``````grid.arrange(bp, #bar plot spaning two columns
bxp, sp, #box plot amd scatter plot
ncol=2, nrow=2, layout_matrix=rbind(c(1, 1), c(2, 3)))
``````

``````gt <- arrangeGrob(bp, bxp, sp, layout_matrix = rbind(c(1,1),c(2, 3)))
p <- as_ggplot(gt)+
draw_plot_label(label = c("A", "B", "C"), size = 15, x=c(0, 0, 0.5), y=c(1, 0.5, 0.5))
p
``````

## R包grid

R包grid中的grid.layout()可以设置复杂的图形布局，viewport()可以定义一个区域用来安置图形排列，print()则用来将图形置于特定区域。 总结起来步骤如下：

• 创建图形p1,p2,p3,…
• grid.newpage()创建一个画布
• 创建图形布局，几行几列
• 定义布局的矩形区域
• print：将图形置于特定区域
``````library(grid)
#Move to a new page
grid.newpage()
#Create layout:nrow=3, ncol=2
pushViewport(viewport(layout = grid.layout(nrow=3, ncol=2)))
#A helper function to define a region on the layout
define_region <- function(row, col){
viewport(layout.pos.row = row, layout.pos.col = col)}
#Arrange the plots
print(sp, vp=define_region(row=1, col=1:2)) #Span over two columns
print(bxp, vp=define_region(row=2, col=1))
print(dp, vp=define_region(row=2, col=2))
print(bp+rremove("x.text"), vp=define_region(row=3, col=1:2))
``````

## 设置共同图例

ggpubr::ggarrange()可以为组合图形添加共同图例

• common.legeng=TRUE:在图形旁边添加图例
• legend：指定legend的位置，主要选项有：top、bottom、left、right。
``````ggarrange(bxp, dp, labels = c("A", "B"), common.legend = TRUE, legend = "bottom")
``````

## 含有边际密度图的散点图

``````sp <- ggscatter(iris, x="Sepal.Length", y="Sepal.Width", color="Species",
palette = "jco", size=3, alpha=0.6)+border()
#Marginal density plot of x(top panel) and y(right panel)
xplot <- ggdensity(iris, "Sepal.Length", fill="Species",palette = "jco")
yplot <- ggdensity(iris, "Sepal.Width", fill="Species", palette = "jco")+rotate()
#Clean the plots
xplot <- xplot+clean_theme()
yplot <- yplot+clean_theme()
#Arrange the plots
ggarrange(xplot, NULL, sp, yplot, ncol = 2, nrow = 2, align = "hv", widths = c(2, 1),
heights = c(1, 2), common.legend = TRUE)
``````

## ggplot图、文本、表格组合

``````density.p <- ggdensity(iris, x="Sepal.Length", fill="Species", palette = "jco")
#Compute the summary table of Sepal.Length
stable <- desc_statby(iris, measure.var = "Sepal.Length", grps = "Species")
stable <- stable[, c("Species", "length", "mean", "sd")]
#Summary table plot, medium and theme
stable.p <- ggtexttable(stable, rows = NULL, theme = ttheme("mOrange"))
text <- paste("iris data set gives the measurements in cm", "of the variables sepal length and width", "and petal length and width, respectively,", "for 50 flowers from each of 3 species of iris.", "The species are Iris setosa, versicolor, and virginica.", sep = " ")
text.p <- ggparagraph(text = text, face = "italic", size = 11, color = "black")
#Arrange the plots on the same page
ggarrange(density.p, stable.p, text.p, ncol = 1, nrow = 3, heights = c(1, 0.5, 0.3))
``````

## ggplot图形中嵌入图形元素

ggplot2::annotation_custom()可以添加各种图形元素到ggplot图中

``````annotation_custom(grob, xmin, xmax, ymin, ymax)
``````

• grob:要添加的图形元素
• xmin, xmax: x轴方向位置（水平方向）
• ymin, ymax: y轴方向位置（竖直方向）

## ggplot图形中添加table

``````density.p+annotation_custom(ggplotGrob(stable.p), xmin = 5.5, xmax = 8, ymin = 0.7)
``````

## ggplot图形中添加box plot

``````sp <- ggscatter(iris, x="Sepal.Length", y="Sepal.Width", color = "Species", palette = "jco", size = 3, alpha=0.6)
xbp <- ggboxplot(iris\$Sepal.Length, width = 0.3, fill = "lightgray")+ rotate()+theme_transparent()
ybp <- ggboxplot(iris\$Sepal.Width, width = 0.3, fill="lightgray")+theme_transparent()
# Create the external graphical objects
# called a "grop" in Grid terminology
xbp_grob <- ggplotGrob(xbp)
ybp_grob <- ggplotGrob(ybp)
#place box plots inside the scatter plot
xmin <- min(iris\$Sepal.Length)
xmax <- max(iris\$Sepal.Length)
ymin <- min(iris\$Sepal.Width)
ymax <- max(iris\$Sepal.Width)
yoffset <- (1/15)*ymax
xoffset <- (1/15)*xmax
# Insert xbp_grob inside the scatter plots
p+annotation_custom(grob = xbp_grob, xmin = xmin, xmax = xmax,
ymin = ymin-yoffset, ymax = ymin+yoffset)+
# Insert ybp_grob inside the scatter plot
annotation_custom(grob = ybp_grob, xmin = xmin-xoffset,
xmax=xmin+xoffset, ymin=ymin, ymax=ymax)
``````

## ggplot图形添加背景

``````#import the imageimg.file <- system.file(file.path("images", "background-image.png"), package = "ggpubr")
``````

``````library(ggplot2)
library(ggpubr)
ggplot(iris, aes(Species,Sepal.Length))+
background_image(img)+
geom_boxplot(aes(fill=Species), color="white")+ fill_palette("jco")
``````

## 修改透明度

``````ggplot(iris, aes(Species,Sepal.Length))+
background_image(img)+geom_boxplot(aes(fill=Species), color="white", alpha=0.5)+
fill_palette("jco")
``````

## 多页排列

``````multi.page <-ggarrange(bxp, dp, bp, sp, nrow = 1, ncol = 2)
``````

``````multi.page[[1]]
``````
``````multi.page[[2]]
``````

## 利用ggarrange()嵌套布局

``````p1 <- ggarrange(sp, bp+font("x.text", size = 9), ncol = 1, nrow = 2)
p2 <- ggarrange(density.p, stable.p, text.p, ncol = 1, nrow = 3,
heights = c(1, 0.5, 0.3))
ggarrange(p1, p2, ncol = 2, nrow = 1)
``````

## SessionInfo

``````sessionInfo()
## R version 3.4.1 (2017-06-30)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 15063)
##
## Matrix products: default
##
## locale:
## [1] LC_COLLATE=Chinese (Simplified)_China.936
## [2] LC_CTYPE=Chinese (Simplified)_China.936
## [3] LC_MONETARY=Chinese (Simplified)_China.936
## [4] LC_NUMERIC=C
## [5] LC_TIME=Chinese (Simplified)_China.936
##
## attached base packages:
## [1] grid stats graphics grDevices utils datasets methods
## [8] base
##
## other attached packages:
## [1] survminer_0.4.0 survival_2.41-3 ggpubr_0.1.5 magrittr_1.5
## [5] cowplot_0.8.0 ggplot2_2.2.1 gridExtra_2.2.1
##
## loaded via a namespace (and not attached):
## [1] zoo_1.8-0 purrr_0.2.3 reshape2_1.4.2
## [4] splines_3.4.1 lattice_0.20-35 colorspace_1.3-2
## [7] htmltools_0.3.6 yaml_2.1.14 survMisc_0.5.4
## [10] rlang_0.1.2 foreign_0.8-69 glue_1.1.1
## [13] bindrcpp_0.2 bindr_0.1 plyr_1.8.4
## [16] stringr_1.2.0 munsell_0.4.3 gtable_0.2.0
## [19] ggsci_2.7 psych_1.7.5 evaluate_0.10.1
## [22] labeling_0.3 knitr_1.17 parallel_3.4.1
## [25] broom_0.4.2 Rcpp_0.12.12 xtable_1.8-2
## [28] scales_0.4.1 backports_1.1.0 cmprsk_2.2-7
## [31] km.ci_0.5-2 mnormt_1.5-5 png_0.1-7
## [34] digest_0.6.12 stringi_1.1.5 dplyr_0.7.2
## [37] KMsurv_0.1-5 rprojroot_1.2 tools_3.4.1
## [40] lazyeval_0.2.0 tibble_1.3.3 tidyr_0.7.0
## [43] pkgconfig_2.0.1 Matrix_1.2-11 data.table_1.10.4
## [46] assertthat_0.2.0 rmarkdown_1.6 R6_2.2.2
## [49] nlme_3.1-131 compiler_3.4.1
``````

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

### 推荐阅读更多精彩内容

• 简介 文章较长，点击直达我的博客，浏览效果更好。本文内容基本是来源于STHDA，这是一份十分详细的ggplot2使...
taoyan阅读 50,361评论 7 158
• Matplotlib 入门教程 来源：Introduction to Matplotlib and basic l...
布客飞龙阅读 31,669评论 5 162
• 一、 这是今天的晚饭，蛋炒饭。 大宝看到这图片，感叹：这卖相可以啊，你终于学会摆拍了。 我说：哼，我那是懒得摆拍，...
冰小喵的猫粮阅读 361评论 0 2
• 01 吃过不少桑椹，但真没吃过像昨天那么甜的桑椹。 昨天应一个朋友的邀请，去另一朋友家玩。因为那里有山有水，我很喜...
西瓜甜甜啦阅读 820评论 34 18