如何使用ggplot在指定坐标位置放置多个绘图对象?
把ggplot子图嵌入网格指定位置的通用方法
需求说明
此前已有不少关于ggplot叠加绘图的问题,但本次需求不同:要在ggplot创建的网格图形的指定坐标位置,放置多个ggplot绘图对象。比如将饼图列表按行对应到网格的每个单元格(如plot_list[[1]]对应A,A位置),且方法需具备通用性,适配任意大小的网格和绘图数量。
示例数据与基础图形
先按示例生成数据、网格图形和子图列表:
1. 创建数据
set.seed(100) m <- matrix(runif(9, -1, 1), ncol = 3) rownames(m) <- colnames(m) <- LETTERS[1:3] m[lower.tri(m)] = t(m)[lower.tri(m)] diag(m) <- 0 col1 <- colorRampPalette(RColorBrewer::brewer.pal(10,"BrBG"))
2. 生成网格图形
library(ggplot2) library(reshape2) df <- reshape2::melt(m) df$abs <- abs(df$value) df$Var1 <- factor(df$Var1, levels = colnames(m)) ggrid <- ggplot(df, aes(x = Var1, y = Var2)) + geom_tile(aes(width = 1, height = 1), fill = NA, color = "grey50") + scale_x_discrete(position = "top", expand = c(0, 0)) + scale_y_discrete(limits = rev(levels(df$Var1)), expand = c(0, 0)) + theme_bw() + theme( aspect.ratio = 1, panel.grid = element_blank() )
3. 创建子图列表(示例为饼图)
plot_list <- list() for(i in 1:nrow(df)){ plot_list[[i]] <- ggplot(df, aes(x = "", y = value, fill = Var1)) + geom_col(color = "black") + coord_polar(theta = "y") + theme_void() + theme(legend.position = 'none') }
通用嵌入方法
使用grid包将子图转为图形对象(grob),再通过annotation_custom精准嵌入到网格的每个单元格中:
library(grid) # 获取网格的行列数 n_rows <- length(levels(df$Var1)) n_cols <- length(levels(df$Var2)) # 循环嵌入每个子图 for(i in seq_along(plot_list)){ # 获取当前单元格的离散坐标位置(1,2,...n) x_pos <- as.integer(df$Var1[i]) y_pos <- as.integer(df$Var2[i]) # 将ggplot对象转为grob格式 sub_grob <- ggplotGrob(plot_list[[i]]) # 嵌入到对应单元格,通过调整差值控制子图大小 ggrid <- ggrid + annotation_custom( grob = sub_grob, xmin = x_pos - 0.4, xmax = x_pos + 0.4, ymin = y_pos - 0.4, ymax = y_pos + 0.4 ) } # 输出最终图形 print(ggrid)
通用性说明
- 适配任意MxN的网格结构,只要
df中的Var1和Var2对应网格的行列标签,就能自动匹配子图位置 - 子图类型无限制,任意ggplot对象都可嵌入,只要数量与网格单元格数一致
- 调整
xmin/xmax、ymin/ymax的差值,可控制子图在单元格内的显示大小,避免超出网格线
内容的提问来源于stack exchange,提问作者Electrino
相关产品推荐
相关产品推荐

