【R分享|实战】地表最全R拼图教程,告别AI和PS

 今日推文较长,请先收藏并空时学习。相信你一定有所收获。”   --科白君
"R实战"专题·第16篇
  编辑 | 科白维尼
  4830字 |12分钟阅读
本期推送内容
利用R语言让拼图变得更加轻松和省时。众所周知,一张完整的图是由多种多样的图形组合而成。通常,我们先绘制好每一张图后,然后再利用其他软件(例如PS、AI等等)来完成整张图的拼凑。R语言能够完成的工作有很多(拼图就是其中一项),并且非常出色。在拼图这项功能测试中R语言里能够给大家交出一份完美的答卷今天,主要介绍R语言中较为常用的四个拼图包(ggpubr,patchwork,cowplot,customLayout)。每个包各有特色,我主要讲解如何使用这三个包的拼图功能,以及一些个人感悟和建议。冲冲冲~
01

为什么要学习R语言的拼图功能

在不认识R语言之前,通常我们会利用PS或者AI来解决自己拼图的需求。但是当你的图绘制的越来越多,拼图的工作量就变得更加繁琐和枯燥,这也会大大影响了你的心情和工作效率。同时,这么多的网格线容易看得眼睛疼(一脸苦涩,经历过的同学肯定深有体会)。这时,R语言的拼图优势一下就显现出来了,我们只需要看懂代码利用几条简单的命令就可以让几张甚至几十张图瞬间完成,真是太完美了。既然,已经开始学习R语言,应该学多些有用的技能,来减轻我们的工作量和重复性的工作,这才是编程软件所在的魅力吧!

02

R语言拼图包

R语言能够完成拼图的包应该有多种。在这篇推文中,我给大家总结了地表最常用的四种拼图包,分别是patchwork、cowplot、ggpubr、customLayout。这几个拼图包都可以与绘图神器"ggplot2"包完美的结合,必须掌握。此外,如果我们把这几个包都掌握了就可以与AI、PS真正地say goodbye了~ 

接下来,直接介绍各个包的使用情况:

1)"ggpubr"包中的 ggarrange()函数

#拼图包--ggpubr

#看看ggarrange函数介绍
?ggarrange()

#利用自带的数据集
data("ToothGrowth")

#将数据集赋值给df
df <- ToothGrowth

#将df数据中dose列中的向量转换成因子型(as.factor)
df$dose <- as.factor(df$dose)

# 绘制多张图
# 箱线图
bxp <- ggboxplot(df, x = "dose", y = "len",
                 color = "dose", palette = "jco")
# 点图
dp <- ggdotplot(df, x = "dose", y = "len",
                color = "dose", palette = "jco")
# 密度图
dens <- ggdensity(df, x = "len", fill = "dose", palette = "jco")

# 利用ggarrange函数完成拼图
ggarrange(bxp, dp, dens, ncol = 2, nrow = 2)
# bxp dp dens分别是前面所绘制的三种图,然后我们按2行2列完成拼图

# 对多个图使用通用的图例
ggarrange(bxp, dp, dens, common.legend = TRUE)
# common.legend=T即可

学习新内容前还是老样子,先help查阅对应函数的命令语法和具体的例子:

了解函数中的参数含义及用法:

拼图结果1:

拼图结果2(共用图例):

更改图例位置(将图例放在整图的右边):

ggarrange(bxp, dp, dens, common.legend = TRUE, legend="right")

给每张子图添加标签(A,B,C):

ggarrange(bxp, dp, dens,
common.legend = TRUE,
legend = "top",
labels = c("A","B","C"))
该包还有很多功能,可以根据自己需求进行学习,这里不再深入拓展~
2)"patchwork"包,不需要任何函数。
该包加载后,支持直接p1+p2拼图,非常简单;布局代码尽管繁多,但是易理解好记;可以统一修改所有子图。直接上代码:
#加载R包
library(ggplot2)
library(patchwork)

?patchwork

#绘制散点图
p1 <- ggplot(mtcars) +
  geom_smooth(aes(hp, wt)) +
  ggtitle('Plot A')

#绘制箱线图
p2 <- ggplot(mtcars) +
  geom_boxplot(aes(gear, disp, group = gear)) +
  ggtitle('Plot B')

#完成拼图
#可以使用“+” 或者“/”
p1 + p2
p1 / p2

绘制结果:

进一步我们看看多图绘制并拼图
p3 <- ggplot(mtcars) +
  geom_point(aes(hp, drat, colour = cyl)) +
  ggtitle('Plot C')

p4 <- ggplot(mtcars) +
  geom_bar(aes(vs)) +
  facet_wrap(~cyl) +
  ggtitle('Plot D')

p1 + p2 + p3 + p4

调节子图的宽度,通过plot_layout(widths = c(3, 1))来设置宽度比例为3:1

p1+p2+plot_layout(width=c(3,1))
p1+p2+plot_layout(width=unit(c(9,3), c("cm","cm")))

图没错,如果直接指定图片的实际宽度为9cm和3cm。与上图的区别在于,指定比例,当绘图区域的宽度发生变化的时候,图片的宽度也会跟着发生变化,但保持比例为3:1。如果直接指定了实际的宽度,不论你的绘图区域的宽度如何发生变化,图片的宽度始终保持不变。所以从这个图与白色画布背景不完全匹配就能看出明显的区别。

我们再看看多张图的比例变化:

p1+p2+p3+plot_layout(width=c(1,2,3))

同时调节宽度和高度:

p1+p2+p3+p4+
plot_layout(widths = c(1.5, 1.5),height=c(2,1))

还可以利用小括号调节图片排版(括号主要存在一个优先级):

p1 / (p2 | p3) # / 斜杠前表示在整个画布的上方,后表示在下方。
# | 竖线符号则表示左右的顺序位置。可以根据自己需求继续添加竖线及要表达的图

如果想要特别突出重点核心图,利用plot_spacer()函数,创建了一个空的透明补丁,可以添加该补丁来将其他图分开。代码如下:

(plot_spacer()+p1+plot_spacer()+
    plot_layout(widths = c(1,8,1)) #调节空白占位图和图A的宽度
 ) / (p2+p3+p4)

# 相当于plot_spacer()这个函数添加了一个补丁,
# 也就是整张图的上方画了一张空白补丁和一张p1和一张空白补丁,‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
# 然后用plot_layout()对上方进行比例的设定。下方则是p2、p3、p4

3)cowplot包中plot_grid()函数用于组合图形,简单看看代码:

library(ggplot2)
library(cowplot)
A <- ggplot(iris, aes(x = Sepal.Length,
y = Petal.Length, colour = Species)) +
  geom_point(size=2.5)

B <- ggplot(diamonds, aes(clarity, fill = cut)) +
  geom_bar() +
  theme(axis.text.x = element_text(angle=45, vjust=0.5, color = "black"),
        axis.text.y = element_text(color = "black"))
?plot_grid()
C <- plot_grid(A, B, labels = c("A", "B"))
C

绘制结果如下:

也可以按行排列:

plot_grid(A, B, labels = c("A", "B"), nrow = 2)

还可以根据自己的需求设置一个合理地布局,你也可以精确地指定布局画多少行多少列。

plot_grid(A, NULL, B, A, NULL, B,
          labels = c("A", "B", "C", "D", "E", "F"), nrow = 2, ncol = 3)

4)最后一个是customLayout包,需要熟悉该包中常用的几个函数:

创建并组合布局:lay_new();预览当前布局:lay_show();拼接图形:lay_bind_col()

#加载所需要的R包
library(customLayout)
library(magrittr)

#查看函数用法
?lay_new()

#mat说明各图形位置的矩阵,是4张图并设置为2列2行布局
lay <- lay_new(
  mat = matrix(1:4, ncol = 2),
  widths = c(3, 2),
  heights = c(2, 1))
#左宽度占整图的3份,右宽度占2份
#上方高度占2份,下占1份

lay_show(lay) #查看当前布局

再尝试一个布局(需要注意的是widths针对的是ncol的数量,而heights针对的是nrow的数量):

lay2 = lay_new(matrix(1:6, nrow = 3, ncol=2),
widths = c(1,1))

lay_show(lay2)

接着,学习一下拼接代码:

lay3 <- lay_bind_col(lay, lay2, widths = c(2,2 ))
lay_show(lay3)

#初始化绘图区域
lay_set(lay3)

#在设置好的绘图区域中添加图
plot(1:100 + rnorm(100))
plot(rnorm(100), type = "l")
hist(rnorm(500))
acf(rnorm(100))
pie(c(3, 4, 6), col = 2:4)
pie(c(3, 2, 7), col = 2:4 + 3)
pie(c(5, 4, 2), col = 2:4 + 6)
pie(c(3, 4, 6), col = 2:4)
pie(c(3, 2, 7), col = 2:4 + 3)
pie(c(5, 4, 2), col = 2:4 + 6)

03

关于R语言拼图的个人感悟和建议

1)如果是需求较少,只是为了把所绘制的图形拼到一起,用patchwork包比较方便,因为该包不需要任何函数,把绘制的图直接按顺序拼凑在一起就可以。
2)如果是需求比较多比如要突出重点的图,或者按比例大小调节的。可以使customLayout包中的lay_new()函数
3)要熟悉不同函数对行列或者长宽的命令语法,特别是在customLayout中,widths针对ncol的数量(比如:ncol=3,那么widths=c(1,1,1)),heights针对nrow的数量
4)这些拼图包都可以与ggplot2包联用,我们还可以再用上export包,将绘制好的图拼好,再利用export包中graph2ppt函数将其以PPT格式导出,第一可以减小图片占用太多的内存(投稿时候对每张图的大小是有要求的,一般不超过3-5M),第二可以保证图片的清晰度(因为可以转化成pdf矢量图),第三方便日后对图进行微调和修改,第四可以少学几个软件(PS、AI)。
(0)

相关推荐