时间序列geom_tile绘图添加coord_equal()后Y轴塌陷问题求助
解决ggplot geom_tile添加coord_equal()后Y轴塌陷的问题
这个问题我之前也碰到过!原因在于你的x轴是POSIXct类型的时间变量,它的底层单位是毫秒,而y轴是离散的分类变量。coord_equal()会强制x轴和y轴的单位长度完全相等,这就导致y轴上分类之间的间距被压缩到几乎看不见,看起来就“塌陷”了。
下面给你两种可行的解决方案,根据你的需求选择:
方法1:将时间轴转换为离散变量(简单直观)
把日期转成年月字符串,让x轴和y轴都变成离散轴,这样coord_equal()就能完美生成正方形tile:
首先处理数据,生成年月列:
library(dplyr) library(ggplot2) # 你的原始数据生成代码 ID <- rep(c('A','B','C'),each = 84) n <- rep(round(runif(84,1,4)), 3) datetime <- rep(seq(as.POSIXct("2014-01-01"), as.POSIXct("2020-12-01"), by="month"), 3) df <- tibble(ID,n, datetime) # 添加年月离散列 df <- df %>% mutate(month_year = format(datetime, "%Y-%m"))
然后绘图:
ggplot(df, aes(x = month_year, y = ID, fill = n)) + geom_tile(color = "white") + # 可选:添加白色边框,让正方形更清晰 scale_y_discrete(expand = c(0, 0)) + scale_x_discrete(expand = c(0, 0)) + # x轴取消扩展,避免tile之间有空隙 scale_fill_viridis() + coord_equal() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) # 旋转x轴标签,避免重叠
这种方法的好处是简单,不需要计算复杂的比例,适合不需要时间轴连续性的展示场景。
方法2:保留时间轴连续性,用coord_fixed()设置比例
如果需要保留x轴的时间连续性(比如后续要添加时间相关的图层),可以用coord_fixed()替代coord_equal(),手动设置x/y轴的比例,让每个tile的宽高相等:
ggplot(df, aes(x = datetime, y = ID, fill = n)) + geom_tile(width = months(1), height = 1) + # 设置每个tile的宽度为1个月,高度为1个分类单位 scale_y_discrete(expand = c(0, 0)) + scale_x_datetime(expand = c(0, 0), date_breaks = "1 year", date_labels = "%Y") + scale_fill_viridis() + # 计算x轴总时间长度(毫秒)与y轴分类数的比例,确保每个tile是正方形 coord_fixed(ratio = as.numeric(diff(range(df$datetime))) / length(unique(df$ID)))
这里的ratio参数是x轴总长度(以毫秒为单位)除以y轴的分类数量,这样就能保证每个月度tile的宽度和每个分类tile的高度完全相等,呈现出正方形效果。
内容的提问来源于stack exchange,提问作者Afiq Johari
相关产品推荐
相关产品推荐

