如何将geom_rect扩展至geom_tile的d1与d6边缘?
问题:让geom_rect绘制的红色矩形延伸至热图上下边缘
使用geom_tile绘制热图时,希望用红色矩形突出特定日期(2018/3/5)的整个深度区域,但当前绘制的矩形无法延伸至d6和d1的边缘,效果如下:
原代码:
df <- data.frame( sensor_date = rep(seq(from = as.Date("2018/3/4"), to = as.Date("2018/3/6"), "days"), each = 6), depth_class = as.factor(rep(c("d1", "d2", "d3", "d4", "d5", "d6"), 3)), freq = rnorm(18, 10, 4) ) df_rect <- data.frame( sensor_date = as.Date(c(rep("2018/3/5", 6)), format = "%Y/%m/%d"), depth_class = c("d0") ) ggplot(data = df) + geom_tile(aes(x = sensor_date, y = depth_class, fill = freq)) + geom_rect( data = df_rect, linewidth = 1, colour = "red", fill = NA, alpha = 0.2, aes( xmin = min(sensor_date - .5), xmax = max(sensor_date + .5), ymin = min("d6"), ymax = max("d1") ) )
当前效果:
解决方案
问题核心是对因子型y轴的数值映射理解:ggplot会把depth_class这类因子变量转换为连续数值(比如d1对应1、d2对应2…d6对应6),每个geom_tile的y轴实际范围是[数值-0.5, 数值+0.5]。要让矩形延伸至边缘,需要把矩形的y轴范围扩展到所有深度因子对应的数值范围之外各加减0.5。
修改后的代码:
set.seed(123) # 设置随机种子保证结果可复现 df <- data.frame( sensor_date = rep(seq(from = as.Date("2018/3/4"), to = as.Date("2018/3/6"), "days"), each = 6), depth_class = as.factor(rep(c("d1", "d2", "d3", "d4", "d5", "d6"), 3)), freq = rnorm(18, 10, 4) ) # 简化矩形数据,仅保留目标日期 df_rect <- data.frame( sensor_date = as.Date("2018/3/5", format = "%Y/%m/%d") ) ggplot(data = df) + geom_tile(aes(x = sensor_date, y = depth_class, fill = freq)) + geom_rect( data = df_rect, linewidth = 1, colour = "red", fill = NA, alpha = 0.2, aes( xmin = sensor_date - 0.5, xmax = sensor_date + 0.5, # 将因子转换为数值,扩展范围至边缘 ymin = min(as.numeric(df$depth_class)) - 0.5, ymax = max(as.numeric(df$depth_class)) + 0.5 ) )
关键改动说明:
- 简化
df_rect:仅需一行目标日期数据,无需重复多次 - 调整y轴范围:通过
as.numeric()将因子转换为底层连续数值,再分别减/加0.5,让矩形覆盖从d6底部到d1顶部的完整边缘区域 - 简化x轴范围:单日期场景下,直接用
sensor_date ± 0.5即可覆盖该日期的整个热图宽度
内容的提问来源于stack exchange,提问作者Dasr
相关产品推荐
相关产品推荐

