R语言中类似pretty函数的二维版:自动确定多图排版的mfrow参数
R语言中类似pretty函数的二维版:自动确定多图排版的mfrow参数
刚好之前批量画多图的时候也纠结过这个问题!R里确实没有内置的“二维版pretty”函数直接给par(mfrow)喂参数,但自己写个轻量小函数就能完美解决,还能按自己的排版偏好定制逻辑~
我先分享一个我常用的版本,核心思路是根据总图数自动算出尽量均衡的行列数,要么刚好填满不留空白,要么尽量接近正方形(哪怕留几个空位):
pretty_mfrow <- function(n_plots) { # 单个图直接返回1×1布局 if (n_plots == 1) { return(c(1, 1)) } # 以总图数的平方根为基准,找接近的整数行列 sqrt_n <- sqrt(n_plots) rows <- floor(sqrt_n) cols <- ceiling(sqrt_n) # 先保证行列乘积能放下所有图 while (rows * cols < n_plots) { rows <- rows + 1 } # 优化:避免出现1×10这种极端长条布局,让行列数尽量接近 if (cols - rows > 1 && rows * (cols - 1) >= n_plots) { cols <- cols - 1 } # 反过来行数太多的情况也调整 else if (rows - cols > 1 && (rows - 1) * cols >= n_plots) { rows <- rows - 1 } # 最后保证行数≤列数,符合横向阅读的习惯 if (rows > cols) { return(c(cols, rows)) } else { return(c(rows, cols)) } }
来测试你提到的几个场景:
- 9个图:
pretty_mfrow(9)返回c(3,3),刚好是完美的3×3正方形布局; - 10个图:这个函数会返回
c(2,5),2×5刚好填满所有图,没有空白;如果你更偏爱接近正方形的布局(哪怕留空位),可以用下面这个优先保证行列接近的版本:
# 优先接近正方形的版本,允许留空白 pretty_mfrow_square <- function(n_plots) { if (n_plots == 1) { return(c(1, 1)) } sqrt_n <- sqrt(n_plots) # 生成可能的行数列举范围 possible_rows <- seq(1, ceiling(sqrt_n) * 2) possible_cols <- ceiling(n_plots / possible_rows) # 找行列差最小的组合 diffs <- abs(possible_rows - possible_cols) best_idx <- which.min(diffs) rows <- possible_rows[best_idx] cols <- possible_cols[best_idx] # 确保能放下所有图 if (rows * cols < n_plots) { cols <- cols + 1 } # 保证行数≤列数 if (rows > cols) { return(c(cols, rows)) } else { return(c(rows, cols)) } }
这个版本里,pretty_mfrow_square(10)会返回c(3,4),也就是3行4列的布局,留2个空位但更接近正方形。
用的时候超简单,绘图前调用函数就行:
# 比如要画12个图 par(mfrow = pretty_mfrow(12)) for (i in 1:12) { plot(rnorm(100), main = paste("Plot", i)) }
其实核心就是根据自己的排版需求,定义“什么是‘好看’的布局”,然后把这个逻辑写成代码就行,完全不需要额外的包,用base R就能搞定~
备注:内容来源于stack exchange,提问作者AdamO
相关产品推荐
相关产品推荐

