如何在ggplot2的geom_tile中将每个瓦片划分为四个象限?
解决ggplot2 geom_tile瓦片拆分四季象限的问题
问题背景
我需要用ggplot2的geom_tile()创建季节性相关性图,将每个瓦片拆分为四个象限,分别对应四季的数值。已有单独季节的绘图代码和合并后的四季数据集,但无法根据Season因子列实现瓦片象限拆分,寻求解决方案。
解决方案
要实现每个瓦片拆分为四个季节象限,核心思路是将离散的物种变量转换为连续坐标,并为每个季节添加偏移量,让每个大瓦片内的四个小象限对应不同季节的数据。具体实现步骤如下:
1. 为季节定义坐标偏移量
给四个季节分配x/y方向的小偏移,确保每个大瓦片内的四个小方块位置不重叠:
- season1:x偏移+0.25,y偏移+0.25(左下象限)
- season2:x偏移+0.75,y偏移+0.25(右下象限)
- season3:x偏移+0.25,y偏移+0.75(左上象限)
- season4:x偏移+0.75,y偏移+0.75(右上象限)
2. 转换数据坐标
将离散的Var1/Var2转换为数值型,加上对应季节的偏移量,得到连续的x/y坐标,用于定位小瓦片。
3. 绘制带象限的热力图
使用转换后的连续坐标绘制小瓦片,同时保留原离散变量的轴标签,确保图表可读性。
完整代码实现
第一步:加载包与处理数据
library(dplyr) library(ggplot2) # 生成四季数据(复用原数据结构) dat.season1 <- data.frame(Var1 = c("species2", "species3", "species4", "species5", "species3", "species4", "species5", "species4", "species5", "species5"), Var2 = c("species1", "species1", "species1", "species1", "species2", "species2", "species2", "species3", "species3", "species4"), value = runif(10, -1, 1)) dat.season2 <- data.frame(Var1 = c("species2", "species3", "species4", "species5", "species3", "species4", "species5", "species4", "species5", "species5"), Var2 = c("species1", "species1", "species1", "species1", "species2", "species2", "species2", "species3", "species3", "species4"), value = runif(10, -1, 1)) dat.season3 <- data.frame(Var1 = c("species2", "species3", "species4", "species5", "species3", "species4", "species5", "species4", "species5", "species5"), Var2 = c("species1", "species1", "species1", "species1", "species2", "species2", "species2", "species3", "species3", "species4"), value = runif(10, -1, 1)) dat.season4 <- data.frame(Var1 = c("species2", "species3", "species4", "species5", "species3", "species4", "species5", "species4", "species5", "species5"), Var2 = c("species1", "species1", "species1", "species1", "species2", "species2", "species2", "species3", "species3", "species4"), value = runif(10, -1, 1)) # 合并四季数据并添加季节标识 all.dat <- dplyr::bind_rows(list(season1 = dat.season1, season2 = dat.season2, season3 = dat.season3, season4 = dat.season4), .id = "Season") # 添加坐标偏移量并转换为连续坐标 all.dat <- all.dat %>% mutate( x_offset = case_when( Season == "season1" ~ 0.25, Season == "season2" ~ 0.75, Season == "season3" ~ 0.25, Season == "season4" ~ 0.75 ), y_offset = case_when( Season == "season1" ~ 0.25, Season == "season2" ~ 0.25, Season == "season3" ~ 0.75, Season == "season4" ~ 0.75 ), # 将离散物种转为连续坐标,减1让起始位置从0开始 x = as.numeric(factor(Var2)) + x_offset - 1, y = as.numeric(factor(Var1)) + y_offset - 1, # 保留原因子水平用于轴标签 Var2_factor = factor(Var2), Var1_factor = factor(Var1) )
第二步:绘制带象限的热力图
# 复用原配色方案 my.colors = colorRampPalette(c("#00002d", '#001a6d', '#99cce2','#ffffff', "#FED18A",'#fda416', "#ff6600"), space = "rgb") colorLevels <-9 cols_to_use= my.colors(colorLevels) ggplot(all.dat, aes(x = x, y = y, fill = value)) + geom_tile(color = "gray60", size = 0.5) + # 小瓦片边框,增强区分度 # 设置x轴:匹配原离散变量的标签与位置 scale_x_continuous( breaks = seq_along(levels(all.dat$Var2_factor)) - 0.5, labels = levels(all.dat$Var2_factor), expand = c(0, 0), position = "top" ) + # 设置y轴:反转顺序,匹配原单季节图的布局 scale_y_continuous( breaks = seq_along(levels(all.dat$Var1_factor)) - 0.5, labels = rev(levels(all.dat$Var1_factor)), expand = c(0, 0), trans = "reverse" ) + scale_fill_gradientn( colors = cols_to_use, space = "Lab", guide = guide_colorbar(frame.colour = "gray60", frame.linewidth = 2) ) + labs(x = NULL, y = NULL) + theme_minimal() + theme( axis.text = element_text(size = 10), panel.grid = element_blank() # 移除网格线,保持图表整洁 )
内容的提问来源于stack exchange,提问作者C_goetsch
相关产品推荐
相关产品推荐

