如何在R中为两个相关矩阵的geom_tile添加箭头?
在两个相关矩阵热力图之间添加箭头的实现方法
当然可以自动生成你需要的箭头,下面提供两种基于R的实现方案,直接复用你原有的代码逻辑:
方案一:基于grid包手动定位箭头
这种方法通过grid系统的viewport精准控制绘图位置,适合需要精细调整箭头位置的场景:
library(gridExtra) library(ggplot2) library(grid) library(purrr) library(reshape2) # 补充melt函数依赖包 # 生成模拟数据 X <- data.frame("x1" = rnorm(100, 0, 1), "x2" = rnorm(100, 0, 1), "x3" = rnorm(100, 0, 1)) # 定义热力图绘制函数 plotCors <- function(df) { ggplot(df, aes(x = X1, y = X2, fill = value)) + geom_tile() + labs(x = "", y = "") # 移除轴标签,让布局更紧凑 } # 生成两个相关矩阵的melt数据,第二个矩阵交换x2和x3的顺序 cor1 <- melt(cor(X)) cor2 <- melt(cor(X)) cor2$X1 <- factor(cor2$X1, levels = c("x1", "x3", "x2")) cor2$X2 <- factor(cor2$X2, levels = c("x1", "x3", "x2")) plots_list <- map(list(cor1, cor2), plotCors) # 创建新的绘图页面 grid.newpage() # 设置两个图的布局视口,中间预留箭头空间 vp_left <- viewport(x = 0.225, y = 0.5, width = 0.45, height = 1) vp_right <- viewport(x = 0.775, y = 0.5, width = 0.45, height = 1) # 绘制左右两个热力图 print(plots_list[[1]], vp = vp_left) print(plots_list[[2]], vp = vp_right) # 绘制第一个箭头:左图x2单元格 → 右图x3单元格 grid.segments(x0 = 0.45, y0 = 0.5, x1 = 0.55, y1 = 0.5, arrow = arrow(type = "open", length = unit(0.1, "inches")), gp = gpar(lwd = 1.5)) # 绘制第二个箭头:左图x3单元格 → 右图x2单元格 grid.segments(x0 = 0.45, y0 = 0.167, x1 = 0.55, y1 = 0.167, arrow = arrow(type = "open", length = unit(0.1, "inches")), gp = gpar(lwd = 1.5))
方案二:基于patchwork包快速布局(更简洁)
patchwork包简化了多图布局,适合快速实现需求:
library(patchwork) library(ggplot2) library(reshape2) library(grid) # 模拟数据和绘图函数同方案一 X <- data.frame("x1" = rnorm(100, 0, 1), "x2" = rnorm(100, 0, 1), "x3" = rnorm(100, 0, 1)) plotCors <- function(df) { ggplot(df, aes(x = X1, y = X2, fill = value)) + geom_tile() + labs(x = "", y = "") } cor1 <- melt(cor(X)) cor2 <- melt(cor(X)) cor2$X1 <- factor(cor2$X1, levels = c("x1", "x3", "x2")) cor2$X2 <- factor(cor2$X2, levels = c("x1", "x3", "x2")) p1 <- plotCors(cor1) p2 <- plotCors(cor2) # 布局两个图,中间留空放置箭头 p <- p1 + plot_spacer(width = 0.2) + p2 + plot_layout(widths = c(4,1,4)) # 绘制箭头 print(p) grid.segments(x0 = 0.42, y0 = 0.5, x1 = 0.58, y1 = 0.5, arrow = arrow(type = "open", length = unit(0.1, "inches")), gp = gpar(lwd = 1.5)) grid.segments(x0 = 0.42, y0 = 0.167, x1 = 0.58, y1 = 0.167, arrow = arrow(type = "open", length = unit(0.1, "inches")), gp = gpar(lwd = 1.5))
说明
- 两个方案都能自动生成你需要的箭头,箭头位置可以通过调整
grid.segments的x/y坐标进行微调 - 方案一的视口定位更灵活,适合复杂布局;方案二的patchwork代码更简洁,上手更快
内容的提问来源于stack exchange,提问作者thesecond
相关产品推荐
相关产品推荐

