在2018年10月CRAN更新的R包中,发现了一个挺有意思的R包——customLayout,听名字就很神奇。它可以用来完成自由拼图,可以使用矩阵自定义图形位置和顺序,用数字来定义每一个模块的长宽比,试用了一遍简直爱不释手,在这里分享给大家。这个包不仅支持数字拼图,还支持R内置的base绘图对象、grid绘图对象等(也就是支持ggplot2对象)。

加载相关的R包

1
2
library(customLayout)
library(magrittr)

简单拼图

1
2
3
4
5
lay1 = lay_new(
  mat = matrix(1:4, ncol = 2),
  widths = c(3, 2),
  heights = c(2, 1))  
lay_show(lay1)

其中mat指定要拼图的数字矩阵,将1:4数字按照纵向顺序拼成两行,其中宽度比为3:2,高度比为2:1。

1
2
3
4
5
lay2 = lay_new(
  mat = matrix(1:4, ncol = 2),
  widths = c(3, 5),
  heights = c(2, 4))  
lay_show(lay2)

含义同上,只是改变了宽度比和高度比。

将lay1和lay2顺次横向或纵向拼接在一张图上

1
2
3
lay1 %>%
  lay_bind_col(lay2, widths = c(3, 1)) %>%
  lay_show()

以上过程将前两个例子横向拼接,两个模块对象仍然支持设置宽度比例3:1。

1
2
3
lay1 %>%
  lay_bind_row(lay2, heights = c(5, 3)) %>%
lay_show()

以上过程将前两个例子纵向拼接,两个模块对象仍然支持设置宽度比例5:2。

两个模块对象拼接

1
2
3
4
5
6
lay3 = lay_new(matrix(1:3))
lay1 %>%
  lay_bind_col(lay2, widths = c(3, 1)) %>%
  lay_bind_row(lay3, heights = c(5, 2)) %>%
  lay_bind_col(lay3,widths = c(2,1)) %>%
  lay_show()

不同层级的对象仍然支持拼接在一起。

将一个模块嵌入到另一个模块特定位置

1
2
3
lay1 %>%
  lay_split_field(field = 4, lay2) %>%
  lay_show()

这里就将lay2嵌入到lay1模块的第四个区域,但lay1和lay2内部的布局结构仍然保持不变。

关于图像对象的布局与拼接

基础绘图对象的拼接

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 布局准备
lay1 %>%
  lay_bind_col(lay3, widths = c(3, 1))->cl
lay_set(cl) # 初始化绘图区域

# 增加图
set.seed(123)
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)

ggplot2图形对象的拼接

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
library(ggplot2)
library(gcookbook)

# 生成三幅图
csub <- subset(climate, Source=="Berkeley" & Year >= 1900)
csub$pos <- csub$Anomaly10y >= 0
ggplot(csub, aes(x=Year, y=Anomaly10y, fill=pos)) +
  geom_bar(stat="identity", position="identity") ->p1

ggplot(uspopage, aes(x=Year, y=Thousands, fill=AgeGroup)) + 
  geom_area() ->p2

ggplot(heightweight, aes(x=ageYear, y=heightIn, colour=sex)) +
  geom_point() + 
  geom_smooth(method = "lm") ->p3

# 布局设置
lay_p1 = lay_new(mat = matrix(1))
lay_p1p2 = lay_new(mat = matrix(1:2, nrow = 1))

lay_p1 %>%
  lay_bind_row(lay_p1p2) ->cl_2

# 将三张图拼接
p_list = list(p1,p2,p3)
lay_grid(p_list, cl_2)