美文网首页计算机@linux_python_R 技术帖
R绘图_ggpubr: Publication Ready Pl

R绘图_ggpubr: Publication Ready Pl

作者: 谢俊飞 | 来源:发表于2020-02-28 19:07 被阅读0次
    • 火狐截图_2020-02-11T08-36-22.554Z.png

    Articles - ggpubr: Publication Ready Plots

    • ggplot2 - Easy Way to Mix Multiple Graphs on The Same Page

    作者: kassambara
    日期:01/09/2017
    翻译:谢俊飞

    在同一页面上排列多个ggplot2图形,标准R函数 par()layout()并不能满足需求。
    基本解决方案是使用gridExtra 包,该软件包具有以下功能:

    • grid.arrange()arrangeGrob()在一页上排列多个ggplots;
    • marrangeGrob() 用于在多个页面上排列多个ggplots。

    但是,这些功能并不能对齐绘图面板 ; 取而代之的是,将图简单地按原样放置到网格中,因此轴并不能对齐。
    如果需要进行轴对齐,则可以切换到Cowplot包,该程序包包含带有align参数的函数 plot_grid()。 但是,Cowplot包不包含任何用于多页布局的解决方案。 因此,我们提供了函数ggarrange() [ggpubr包],这是对plot_grid()函数的包装,可在多个页面上排列多个ggplots。 它还可以为多个图创建通用的唯一图例。

     #组织架构图
     R base package
            par()和 layout()
    gridExtra package
            一页排图:grid.arrange()  和 arrangeGrob()
            多页排图:marrangeGrob()
    Cowplot package
            轴对齐:plot_grid( align = " ")
    ggpubr package
            多页布局:ggarrange()
    

    本文将逐步向你展示如何使用以下R包(ggpubrcowplotgridExtra)中的帮助功能,在同一页面上以及在多个页面上组合多个ggplots图形。 我们还将介绍如何将已排列的图片导出到文件中。

    准备工作

    • 需要的R包

    你需要安装R包ggpubr(版本> = 0.1.3),以轻松创建基于ggplot2的发布就绪图。
    我们建议从GitHub安装最新的开发版本,如下所示:

    if (!requireNamespace("BiocManager", quietly = TRUE))
        install.packages("BiocManager")
    BiocManager::install("ggpubr")
    

    请注意,安装ggpubr会自动安装gridExtracowplot软件包。 因此无需重新安装。

    加载ggpubr

    library(ggpubr)
    
    • 数据集演示

    数据: ToothGrowth 和 mtcars 数据集.

    # ToothGrowth
    data("ToothGrowth")
    head(ToothGrowth)
    
    # mtcars 
    data("mtcars")
    mtcars$name <- rownames(mtcars)
    mtcars$cyl <- as.factor(mtcars$cyl)
    head(mtcars[, c("name", "wt", "mpg", "cyl")])
    

    绘制图片

    在这里,我们将使用ggpubr中基于ggplot2的绘图功能。 你可以使用任何ggplot2函数来创建所需的绘图,以便以后进行排列。

    我们先创建4个不同的图

    • 使用ToothGrowth数据集的箱形图和点图
    • 使用mtcars数据集的条形图和散点图
      在下一部分中,你将学习如何使用特定功能来组合这些图。
    • 绘制箱形图和点图:
    # Box plot (bp)
    bxp <- ggboxplot(ToothGrowth, x = "dose", y = "len",
                     color = "dose", palette = "jco") 
    bxp
    # Dot plot (dp)
    dp <- ggdotplot(ToothGrowth, x = "dose", y = "len",
                    color = "dose",palette = "jco", binwidth = 1)
    dp
    
    图片.png
    • 绘制排序的条形图和散点图:
      创建有序的条形图。 通过分组变量"cyl"更改填充颜色。 排序将在整体范围内进行,但不会按组进行。
    # 条形图(bp)
    bp <- ggbarplot(mtcars, x = "name", y = "mpg",
              fill = "cyl",               # 通过"cyl"更改填充颜色
              color = "white",            # 将栏边框颜色设置为白色
              palette = "jco",            #  jco颜色板. 查看 ?ggpar
              sort.val = "asc",           # 按升序排序
              sort.by.groups = TRUE,      # 每个组内排序
              x.text.angle = 90           #垂直旋转x轴文本
              )
    bp + font("x.text", size = 8)
    # 散点图 (sp)
    sp <- ggscatter(mtcars, x = "wt", y = "mpg",
                    add = "reg.line",               # 添加回归线
                    conf.int = TRUE,                #添加置信区间
                    color = "cyl", palette = "jco", # 按组"cyl"更改颜色
                    shape = "cyl"                   # 按组"cyl"更改点的形状
                    )+
      stat_cor(aes(color = cyl), label.x = 3)       # 添加相关系数
    sp
    
    图片.png

    在一页上排列图片

    要在一个页面上排列多个图片,我们将使用ggarrange()[在ggpubr中],它是对plot_grid()[在cowplot包中]函数的包装。 与标准函数plot_grid()相比,ggarange()可以在多个页面上排列多个图片。

    ggarrange(bxp, dp, bp + rremove("x.text"), 
              labels = c("A", "B", "C"),
              ncol = 2, nrow = 2)
    
    图片.png

    另外,你也可以使用功能* plot_grid()* [cowplot包]:

    library(cowplot)
    plot_grid(bxp, dp, bp + rremove("x.text"), 
              labels = c("A", "B", "C"),
              ncol = 2, nrow = 2)
    

    或者,函数grid.arrange() [gridExtra包]:

    library("gridExtra")
    grid.arrange(bxp, dp, bp + rremove("x.text"), 
                 ncol = 2, nrow = 2)
    

    注释排列的图形

    R函数:annotate_figure() [ ggpubr包]

    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"
                    )
    
    图片.png

    注意,函数annotate_figure()支持任何ggplots。

    对齐绘图面板

    一个真实的例子是,例如,当绘制生存曲线并将风险表放置在主图下时。
    为了说明这种情况,我们将使用survminer包。 首先,使用install.packages("survminer")安装,然后键入以下内容:

    # 拟合生存曲线
    library(survival)
    fit <- survfit( Surv(time, status) ~ adhere, data = colon )
    # 绘制生存曲线
    library(survminer)
    ggsurv <- ggsurvplot(fit, data = colon, 
                         palette = "jco",                              # jco颜色板
                         pval = TRUE, pval.coord = c(500, 0.4),        # 添加p值
                         risk.table = TRUE                             # 添加风险表
                         )
    names(ggsurv)
    

    ggsurv是一个包含以下组件的列表:

    • 图:生存曲线
    • 表格:风险表图
      你可以如下安排生存图和风险表:
    ggarrange(ggsurv$plot, ggsurv$table, heights = c(2, 0.7),
              ncol = 1, nrow = 2)
    
    图片.png

    可以看出,生存图和风险表的轴未垂直对齐。 要对齐它们,请指定参数align,如下所示。

    ggarrange(ggsurv$plot, ggsurv$table, heights = c(2, 0.7),
              ncol = 1, nrow = 2, align = "v")
    
    图片.png

    更改图的列/行跨度

    • 使用ggpubr包

    我们将使用嵌套的ggarrange()函数来更改图表的列/行跨度。
    例如,使用下面的R代码:

    • 散点图(sp)将位于第一行并跨越两列
    • 箱形图(bxp)和点形图(dp)将首先进行排列,并分别存在于第二行和两列中
    ggarrange(sp,                                                 # 第一行散点图
              ggarrange(bxp, dp, ncol = 2, labels = c("B", "C")), # 第二行箱线图和点图
              nrow = 2, 
              labels = "A"                                        # 散点图的标签
              ) 
    
    图片.png
    • 使用cowplot包

    • ggdraw()* + draw_plot() + draw_plot_label() [cowplot包]函数的组合可用于将图形放置在具有特定大小的特定位置。
      ggdraw(), 初始化一个空的绘图画布:
    ggdraw()
    

    请注意,默认情况下,坐标从0到1,并且点(0,0)在画布的左下角(请参见下图)。


    图片.png

    draw_plot(). 将绘图放置在绘图画布上的某个位置:

    draw_plot(plot, x = 0, y = 0, width = 1, height = 1)
    
    • plot:要放置的绘图(ggplot2或gtable)
    • x,y:绘图左下角的x / y位置。
    • width, height:图的宽度和高度

    draw_plot_label()。 在图的左上角添加图标签。 它可以处理带有关联坐标的标签向量。

    draw_plot_label(label, x = 0, y = 1, size = 16, ...)
    
    • label:要绘制的标签向量
    • x,y:分别包含标签的x和y位置的向量
    • size:要绘制的标签的字体大小
      例如,你可以组合多个具有特定位置和大小的图,如下所示:
    library("cowplot")
    ggdraw() +
      draw_plot(bxp, x = 0, y = .5, width = .5, height = .5) +
      draw_plot(dp, x = .5, y = .5, width = .5, height = .5) +
      draw_plot(bp, x = 0, y = 0, width = 1, 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))
    
    图片.png
    • 使用gridExtra包

    rangingGrop() [gridExtra包]函数有助于更改绘图的行、列跨度。
    例如,使用下面的代码:

    • 散点图(sp)将位于第一行并跨越两列
    • 箱形图(bxp)和点形图(dp)将位于第二行,两个不同列中的两个图
    library(gridExtra)
    grid.arrange(sp,                             # 第一行,一个图跨越两列
                 arrangeGrob(bxp, dp, ncol = 2), # 第二行,在2个不同的列中包含2个图
                 nrow = 2)                       # 行数
    
    图片.png

    也可以在grid.arrange()函数中使用参数layout_matrix来创建复杂的布局。
    在layout_matrix下面的R代码中,是2x2矩阵(2列2行)。 第一行全为1,这是第一幅图所在的地方,横跨两列; 第二行包含图2和3,各占据一列。

    grid.arrange(bp,                                    # 条形图横跨两列
                 bxp, sp,                               # 箱形图和散点图
                 ncol = 2, nrow = 2, 
                 layout_matrix = rbind(c(1,1), c(2,3)))
    
    图片.png

    请注意,也可以使用辅助函数draw_plot_label()[cowplot包]注释grid.arrange()函数的输出。

    为了轻松注释grid.arrange()/ rangeGrob()输出(一个gtable),你应该首先使用函数as_ggplot()[ggpubr包]将其转换为ggplot。 接下来,你可以使用函数draw_plot_label()[在cowplot中]对其进行注释。

    library("gridExtra")
    library("cowplot")
    # 使用arrangeGrob排列图片
    # 返回gtable (gt)
    gt <- arrangeGrob(bp,                               #条形图跨越两列
                 bxp, sp,                               # 箱线图和散点图
                 ncol = 2, nrow = 2, 
                 layout_matrix = rbind(c(1,1), c(2,3)))
    # Add labels to the arranged plots
    p <- as_ggplot(gt) +                                     # 转换为ggplot
      draw_plot_label(label = c("A", "B", "C"), size = 15,
                      x = c(0, 0, 0.5), y = c(1, 0.5, 0.5))  # 添加标签
    p
    
    图片.png

    在上面的R代码中,我们使用rangingGrob()代替了grid.arrange()
    请注意,这两个函数之间的主要区别在于,grid.arrange()会自动输出排列图。
    由于我们想在绘制图形之前对其进行注释,因此在这种情况下,最好使用函数arrangeGrob()

    • 使用grid 包

    可以在grid.layout()函数的帮助下使用grid 包来创建复杂的布局。 它还提供了辅助函数viewport()来定义布局上的区域或视口。 函数print()用于将图放置在指定区域中。

    不同的步骤可以总结如下:

    1. 创建图:p1,p2,p3,…
    2. 使用函数grid.newpage()移至网格设备上的新页面
    3. 创建一个布局2X2-列数= 2; 行数= 2
    4. 定义网格视口:图形设备上的矩形区域
    1. 将图打印到视口中
    library(grid)
    # 移至新页面
    grid.newpage()
    # 创建布局:nrow = 3,ncol = 2
    pushViewport(viewport(layout = grid.layout(nrow = 3, ncol = 2)))
    # 辅助功能,用于在布局上定义区域
    define_region <- function(row, col){
      viewport(layout.pos.row = row, layout.pos.col = col)
    } 
    # 排列图片
    print(sp, vp = define_region(row = 1, col = 1:2))   # 横跨两列
    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))
    
    图片.png

    将通用图例用于组合的图.

    将共用图例放在排列图的边缘,可以将ggarrange()[ggggbr包]与以下参数一起使用:

    • common.legend = TRUE:将公共图例放在页边
    • legend:指定图例位置。 允许的值包括(“ top”,“ bottom”,“ left”,“ right”)之一
    ggarrange(bxp, dp, labels = c("A", "B"),
              common.legend = TRUE, legend = "bottom")
    
    图片.png

    具有边际密度图的散点图

    # 按组 ("Species")着色散点图
    sp <- ggscatter(iris, x = "Sepal.Length", y = "Sepal.Width",
                    color = "Species", palette = "jco",
                    size = 3, alpha = 0.6)+
      border()                                         
    # x(上图)和y(右图)的边际密度图
    xplot <- ggdensity(iris, "Sepal.Length", fill = "Species",
                       palette = "jco")
    yplot <- ggdensity(iris, "Sepal.Width", fill = "Species", 
                       palette = "jco")+
      rotate()
    # 清理
    yplot <- yplot + clean_theme() 
    xplot <- xplot + clean_theme()
    #排列图片
    ggarrange(xplot, NULL, sp, yplot, 
              ncol = 2, nrow = 2,  align = "hv", 
              widths = c(2, 1), heights = c(1, 2),
              common.legend = TRUE)
    
    图片.png

    混排表格,文本和图片

    在本部分中,我们将展示如何在图表旁边绘制表格和文本。 使用 iris数据集。我们首先创建以下图:

    1. 变量“ Sepal.Length”的密度图。 R函数:ggdensity()[ggpubr包]
    2. 摘要表,其中包含Sepal.Length的描述统计量(平均值,标准差,…)。
    • 用于计算描述性统计信息的R函数:desc_statby()[ggpubr包]。
    • 用于绘制文本表的R函数:ggtexttable()[ggpubr包]。
    1. 文字段落。 R函数:ggparagraph[ggpubr包]。
      我们使用函数ggarrang()[ggpubr包]来完成排列、组合三个图
    # "Sepal.Length"密度图
    #::::::::::::::::::::::::::::::::::::::
    density.p <- ggdensity(iris, x = "Sepal.Length", 
                           fill = "Species", palette = "jco")
    #绘制Sepal.Length汇总表
    #::::::::::::::::::::::::::::::::::::::
    # 按组计算描述性统计
    stable <- desc_statby(iris, measure.var = "Sepal.Length",
                          grps = "Species")
    stable <- stable[, c("Species", "length", "mean", "sd")]
    # 汇总表图,主题中橙色
    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")
    #在同一页面上排列图
    ggarrange(density.p, stable.p, text.p, 
              ncol = 1, nrow = 3,
              heights = c(1, 0.5, 0.3))
    
    图片.png

    在图片中插入图形元素

    ggplot2中的*annotation_custom() *可用于在ggplot的绘图区域内添加表、图片或其他基于网格的元素。 格式为:

    annotation_custom(grob, xmin, xmax, ymin, ymax)
    
    • grob:要显示的外部图形元素
    • xmin,xmax:数据坐标中的x位置(水平位置)
    • ymin,ymax:数据坐标中的y位置(垂直位置)
    • 将表放在图中

    我们将使用在上一节中创建的图表density.p和stable.p。

    density.p + annotation_custom(ggplotGrob(stable.p),
                                  xmin = 5.5, ymin = 0.7,
                                  xmax = 8)
    
    图片.png
    • 将箱形图放在图中

    1. 使用iris数据集创建y ="Sepal.Width"和x ="Sepal.Length"的散点图。 R函数ggscatter()[ggpubr包]
    2. 分别创建具有透明背景的x和y变量的箱形图。 R函数:ggboxplot()[ggpubr]。
      将箱形图转换为在网格术语中称为“抓图”的图形对象。 R函数ggplotGrob()[ggplot2包]。
    3. 将箱形图样图块放入散点图内。 R函数:annotation_custom()[ggplot2包]。
      由于插入的箱线图与某些点重叠,因此箱线图使用透明背景。
    # 按组("Species")着色散点图
    #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    sp <- ggscatter(iris, x = "Sepal.Length", y = "Sepal.Width",
                    color = "Species", palette = "jco",
                    size = 3, alpha = 0.6)
    # 创建x / y变量的箱线图
    #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    # x变量的箱线图
    xbp <- ggboxplot(iris$Sepal.Length, width = 0.3, fill = "lightgray") +
      rotate() +
      theme_transparent()
    # y变量的箱线图
    ybp <- ggboxplot(iris$Sepal.Width, width = 0.3, fill = "lightgray") +
      theme_transparent()
    # 创建外部图形对象
    #在Grid中称为"grop"
    xbp_grob <- ggplotGrob(xbp)
    ybp_grob <- ggplotGrob(ybp)
    # 将箱线图放置在散点图内
    #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    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
    # 在散点图中插入xbp_grob
    sp + annotation_custom(grob = xbp_grob, xmin = xmin, xmax = xmax, 
                           ymin = ymin-yoffset, ymax = ymin+yoffset) +
      # 在散点图中插入ybp_grob
      annotation_custom(grob = ybp_grob,
                           xmin = xmin-xoffset, xmax = xmin+xoffset, 
                           ymin = ymin, ymax = ymax)
    
    图片.png
    • 将背景图像添加到ggplot2图形

    导入背景图像: 根据背景图像的格式,使用函数readJPEG()[jpeg包]或函数readPNG()[png包]。
    为测试以下示例,请确保已安装png软件包。 您可以使用install.packages("png")命令进行安装。

    # 导入图片
    library(jpeg)
    girl  <-  readJPEG("C:/Users/Administrator/Documents/jpeggirl01.jpg")
    

    将ggplot与背景图像合并。 R函数:background_image()[ggpubr包]。

    library(ggplot2)
    library(ggpubr)
    ggplot(iris, aes(Species, Sepal.Length))+
      background_image(girl)+
      geom_boxplot(aes(fill = Species), color = "white")+
      fill_palette("aaas")
    
    • Rplot01.png

    通过指定参数alpha来更改箱线图填充颜色的透明度。 值应为[0,1],其中0为完全透明,1为不透明。

    library(ggplot2)
    library(ggpubr)
    ggplot(iris, aes(Species, Sepal.Length))+
      background_image(img)+
      geom_boxplot(aes(fill = Species), color = "white", alpha = 0.5)+
      fill_palette("aaas")
    
    Rplot03.png

    另一个示例,覆盖了China地图和ggplot2:

    china <- readJPEG("C:/Users/Administrator/Documents/china.jpg")
    ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) +
      background_image(china)+
      geom_point(aes(color = Species), alpha = 0.6, size = 5)+
      color_palette("jco")+
      theme(legend.position = "top")
    
    • Rplot05.png

    多页排图

    如果有一系列图片,比如20个,需要排列这些图并将它们放置在多页上。 每页有4个地块,则需要5页才能容纳20个图。
    函数ggarrange()[ggpubr包]提供了一种方便的解决方案,可以在多个页面上排列多个ggplots。 在指定参数nrow和ncol之后,函数ggarrange()会自动计算保存绘图列表所需的页数。 它返回一个排列好的图片列表。
    例如以下R代码:

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

    返回两页的列表,每页两个图。 你可以按如下所示可视化每个页面:

    multi.page[[1]] # 查看第一页
    multi.page[[2]] # 查看第二页
    

    您还可以使用函数ggexport()[ggpubr]将排列好的图导出到pdf文件:

    ggexport(multi.page, filename = "multi.page.ggplot2.pdf")
    

    请注意,也可以使用功能marrangeGrob()[gridExtra包]创建多页输出。

    library(gridExtra)
    res <- marrangeGrob(list(bxp, dp, bp, sp), nrow = 1, ncol = 2)
    # 到处为pdf文件
    ggexport(res, filename = "multi.page.ggplot2.pdf")
    # 交互式可视化
    res
    

    使用ggarrange()嵌套布局

    我们将重新排列在(@ref(mix-table-text-and-ggplot)) 和 (@ref(create-some-plots))部分中创建的绘图。

    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)
    
    图片.png

    导出图片

    R函数:ggexport()[ggpubr包]。
    首先,在iris数据集中创建与变量Sepal.Length,Sepal.Width,Petal.Length和Petal.Width对应的4个图片。

    plots <- ggboxplot(iris, x = "Species",
                       y = c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width"),
                       color = "Species", palette = "jco"
                       )
    plots[[1]]  # 打印第一张图
    plots[[2]]  # 打印第二个图,依此类推...
    

    接下来,您可以将单个图导出到文件(pdf,eps或png)(每页一个图)。 也可以每页2个排列的图片。

    • 将单个图导出到pdf文件(每页一个图):
    ggexport(plotlist = plots, filename = "test.pdf")
    

    排列和导出。 在同一页面上指定nrow和ncol以展示多个图:

    ggexport(plotlist = plots, filename = "test.pdf",
             nrow = 2, ncol = 1)
    

    致谢

    我们衷心感谢所有ggpubr依赖包的开发人员所做的努力:

    相关文章

      网友评论

        本文标题:R绘图_ggpubr: Publication Ready Pl

        本文链接:https://www.haomeiwen.com/subject/iruxhhtx.html