求助:为热图各列设置独立scale_fill_discrete的实现问题
实现每列独立填充比例尺的热图解决方案
我明白你想要的是共享y轴(车型名称)、每列对应独立填充色比例尺的热图,你用ggnewscale的思路完全找对方向了!最后那段代码的问题主要是x轴位置没对齐,导致各列的瓷砖重叠或者位置混乱,咱们来调整一下就能达到目标:
第一步:预处理数据,给每列分配固定的x位置
首先咱们给每个key(也就是vs、am这些变量)分配一个固定的x坐标,这样每个变量对应的列在x轴上的位置是确定的,不会乱掉:
library(tidyverse) library(ggnewscale) library(ggsci) # 数据预处理:转成因子、整理格式,添加x位置列 temp <- mtcars %>% rownames_to_column("rnames") %>% as_tibble() %>% mutate(across(-rnames, as_factor)) %>% # 把数值列转成因子,保证填充色是离散型 select(rnames, vs, am, gear, carb) %>% gather(key = "key", value = "value", -rnames) %>% mutate( key = fct_inorder(key), # 保留变量原来的顺序 x_pos = as.numeric(key) # 给每个key分配对应的x轴位置 )
第二步:构建带独立填充比例尺的热图
接下来咱们用ggnewscale的new_scale_fill()来分隔每个图层的填充比例尺,每个变量对应一个geom_tile图层,并且搭配你想要的ggsci配色:
ggplot(temp, aes(y = rnames)) + # 第一列:vs,用Simpsons配色 geom_tile(data = filter(temp, key == "vs"), aes(x = x_pos, fill = value)) + scale_fill_simpsons(name = "vs") + new_scale_fill() + # 开启新的填充比例尺上下文 # 第二列:am,用Rick&Morty配色 geom_tile(data = filter(temp, key == "am"), aes(x = x_pos, fill = value)) + scale_fill_rickandmorty(name = "am") + new_scale_fill() + # 第三列:gear,用Futurama配色 geom_tile(data = filter(temp, key == "gear"), aes(x = x_pos, fill = value)) + scale_fill_futurama(name = "gear") + new_scale_fill() + # 第四列:carb,用Tron配色 geom_tile(data = filter(temp, key == "carb"), aes(x = x_pos, fill = value)) + scale_fill_tron(name = "carb") + # 调整x轴刻度,显示变量名称 scale_x_continuous(breaks = unique(temp$x_pos), labels = unique(temp$key)) + labs(x = "变量", y = "车型") + theme_minimal() + # 整理图例:放在底部,垂直排列 theme(legend.position = "bottom", legend.box = "vertical")
(可选)用循环简化代码
如果变量多的话,重复写图层太麻烦,咱们可以用循环来自动添加每个图层和对应的比例尺:
# 先定义每个变量对应的填充比例尺 scale_mapping <- list( vs = scale_fill_simpsons(name = "vs"), am = scale_fill_rickandmorty(name = "am"), gear = scale_fill_futurama(name = "gear"), carb = scale_fill_tron(name = "carb") ) # 初始化绘图对象 p <- ggplot(temp, aes(y = rnames)) # 循环添加每个变量的图层和比例尺 for (var_name in names(scale_mapping)) { p <- p + geom_tile(data = filter(temp, key == var_name), aes(x = x_pos, fill = value)) + scale_mapping[[var_name]] + new_scale_fill() } # 最后调整轴标签和主题 p <- p + scale_x_continuous(breaks = unique(temp$x_pos), labels = unique(temp$key)) + labs(x = "变量", y = "车型") + theme_minimal() + theme(legend.position = "bottom", legend.box = "vertical") print(p)
这样调整后,你就能得到一个每列有独立离散填充比例尺、共享y轴和统一x轴布局的热图,完美解决你之前遇到的对齐和比例尺冲突问题!
内容的提问来源于stack exchange,提问作者Aureliano Guedes
相关产品推荐
相关产品推荐

