R ggplot如何实现按排名升降规则着色的条件热图
ggplot 实现自定义排名变化热图方法
核心思路是先对原始数据做预处理,计算每个选手每一期相对上一期的排名变化状态,再将状态映射为对应填充色绘制热图,具体步骤如下:
- 首先给原始数据集增加时间周期标识列,将宽格式的选手排名数据转换为ggplot适配的长格式
- 按选手分组,逐行计算当前排名和上一期排名的差值,根据差值判定排名是上升、下降还是不变,注意排名数值越小代表名次越高,不要搞反判断逻辑
- 第一期(原始数据第1行)没有上一期数据可对比,可单独设置填充色
- 用
geom_tile()绘制热图单元格,手动指定不同变化状态对应的填充色,再在单元格上标注对应排名数值即可
完整可运行代码
library(tidyverse) # 读入原始排名数据 rank_df <- tibble( time = 1:5, `Player 1` = c(3, 3, 2, 4, 1), `Player 2` = c(1, 4, 3, 2, 4), `Player 3` = c(4, 2, 4, 1, 3), `Player 4` = c(2, 1, 1, 3, 2) ) # 数据预处理:计算排名变化状态 plot_df <- rank_df %>% pivot_longer( cols = starts_with("Player"), names_to = "player", values_to = "rank" ) %>% group_by(player) %>% mutate( last_rank = lag(rank), change_type = case_when( is.na(last_rank) ~ "首期无参照", rank < last_rank ~ "排名上升", rank == last_rank ~ "排名不变", rank > last_rank ~ "排名下降" ) ) %>% ungroup() # 自定义颜色映射规则 fill_colors <- c( "排名上升" = "forestgreen", "排名不变" = "gray70", "排名下降" = "firebrick3", "首期无参照" = "white" ) # 绘图 ggplot(plot_df, aes(x = player, y = factor(time, levels = rev(1:5)))) + geom_tile(aes(fill = change_type), color = "white", linewidth = 1) + geom_text(aes(label = rank), size = 5) + scale_fill_manual(values = fill_colors, name = "排名变化") + labs( x = "参赛选手", y = "统计周期", title = "选手排名逐期变化热图" ) + theme_minimal() + theme( panel.grid = element_blank(), axis.text = element_text(size = 11), legend.position = "bottom" )
可调整的细节
- 代码中对y轴做了顺序反转,让第1期显示在图表最上方,符合时间序列从上到下阅读的习惯,如果需要第1期在最下方,把
factor(time, levels = rev(1:5))改成factor(time)即可 - 首期单元格默认填充为白色,可自行修改
fill_colors中首期无参照对应的色值调整 - 绿、红、灰的色值可根据需求替换为自定义色号,单元格边框粗细、文字大小也可在对应图层参数中调整
- 逻辑校验:按照示例规则,选手1第2期排名和第1期一致,对应单元格为灰色;选手4第2期排名从2升到1,对应单元格为绿色,运行代码后结果和要求完全匹配
内容的提问来源于stack exchange,提问作者EV_Mustang
相关产品推荐
相关产品推荐

