如何在ggplot堆叠tile图中按order变量指定颜色顺序?
按指定order变量排列ggplot堆叠tile图的颜色
我需要让ggplot的堆叠tile图严格按照数据框里的order变量顺序排列颜色,但因为使用了geom_tile(position="stack"),且每个name组内的y值完全相同,导致颜色顺序呈现随机排列。以下是我的数据和绘图代码:
数据
df <- data.frame( name = c("sv0_allmain", "sv0_allmain", "sv0_allmain", "sv0_allmain", "sv0_allmain", "sv0_allmain", "sv0_allmain", "sv0_allmain", "sv0_skala_posneg_2", "sv0_skala_posneg_2", "sv0_skala_posneg_3", "sv0_skala_posneg_3", "sv0_skala_posneg_3", "sv0_skala_posneg_4", "sv0_skala_posneg_4", "sv0_skala_posneg_4", "sv0_skala_posneg_4", "sv0_skala_posneg_5", "sv0_skala_posneg_5", "sv0_skala_posneg_5", "sv0_skala_posneg_5", "sv0_skala_posneg_5", "sv0_skala_posneg_6", "sv0_skala_posneg_6", "sv0_skala_posneg_6", "sv0_skala_posneg_6", "sv0_skala_posneg_6", "sv0_skala_posneg_6", "sv0_skala_posneg_7", "sv0_skala_posneg_7", "sv0_skala_posneg_7", "sv0_skala_posneg_7", "sv0_skala_posneg_7", "sv0_skala_posneg_7", "sv0_skala_posneg_7", "sv0_mono_rot", "sv0_mono_rot", "sv0_mono_eisblau", "sv0_mono_eisblau", "sv0_mono_dunkelblau", "sv0_mono_dunkelblau", "sv0_mono_svgold", "sv0_mono_svgold", "sv0_mono_mint", "sv0_mono_mint", "sv1_allmain", "sv1_allmain", "sv1_allmain", "sv1_allmain", "sv1_allmain"), color = c("#195365", "#6896A8", "#ADA58B", "#91BEA0", "#B5BFC5", "#E73F0C", "#9650EB", "#AFD700", "#91BEA0", "#6896A8", "#91BEA0", "#ADA58B", "#6896A8", "#91BEA0", "#A2CEB1", "#79A8BA", "#6896A8", "#91BEA0", "#A2CEB1", "#ADA58B", "#79A8BA", "#6896A8", "#91BEA0", "#A2CEB1", "#B3DFC2", "#8AB9CC", "#7AA9BA", "#6896A8", "#91BEA0", "#A2CEB1", "#B3DFC2", "#ADA58B", "#8AB9CC", "#7AA9BA", "#6896A8", "#E73f0C", "#F9D4C8", "#6896A8", "#DDE7EB", "#195365", "#CBD8DC", "#ADA58B", "#ECEBE5", "#91BEA0", "#E6F0E9", "#195365", "#AFD700", "#6896A8", "#91BEA0", "#B5BFC5"), total_colors = rep(215, 50), y_value = rep(0.004651163, 50), order = c("sv0_allmain_1", "sv0_allmain_2", "sv0_allmain_3", "sv0_allmain_4", "sv0_allmain_5", "sv0_allmain_6", "sv0_allmain_7", "sv0_allmain_8", "sv0_skala_posneg_2_1", "sv0_skala_posneg_2_2", "sv0_skala_posneg_3_1", "sv0_skala_posneg_3_2", "sv0_skala_posneg_3_3", "sv0_skala_posneg_4_1", "sv0_skala_posneg_4_2", "sv0_skala_posneg_4_3", "sv0_skala_posneg_4_4", "sv0_skala_posneg_5_1", "sv0_skala_posneg_5_2", "sv0_skala_posneg_5_3", "sv0_skala_posneg_5_4", "sv0_skala_posneg_5_5", "sv0_skala_posneg_6_1", "sv0_skala_posneg_6_2", "sv0_skala_posneg_6_3", "sv0_skala_posneg_6_4", "sv0_skala_posneg_6_5", "sv0_skala_posneg_6_6", "sv0_skala_posneg_7_1", "sv0_skala_posneg_7_2", "sv0_skala_posneg_7_3", "sv0_skala_posneg_7_4", "sv0_skala_posneg_7_5", "sv0_skala_posneg_7_6", "sv0_skala_posneg_7_7", "sv0_mono_rot_1", "sv0_mono_rot_2", "sv0_mono_eisblau_1", "sv0_mono_eisblau_2", "sv0_mono_dunkelblau_1", "sv0_mono_dunkelblau_2", "sv0_mono_svgold_1", "sv0_mono_svgold_2", "sv0_mono_mint_1", "sv0_mono_mint_2", "sv1_allmain_1", "sv1_allmain_2", "sv1_allmain_3", "sv1_allmain_4", "sv1_allmain_5") )
原始绘图代码
ggplot(df, aes(x = fct_rev(fct_inorder(name)), y = y_value)) + geom_tile(aes(fill = color), position = "stack") + coord_flip() + labs( title = "In svVis::give_theme_and_color_set() integrierte Farbpalletten und Themes\n", x = "", y = "" ) + theme_minimal() + scale_fill_identity() + give_theme_and_color_set("sv0_allmain")[["theme"]] + theme( axis.text.x = element_blank() )
解决方法
问题核心是position="stack"在y值完全相同时无法判断堆叠顺序,需要手动控制每个tile的位置并确保数据排序正确。
修改后的代码
library(dplyr) library(forcats) library(ggplot2) # 按name分组,再按order排序,计算每个组内的堆叠位置 df_sorted <- df %>% group_by(name) %>% arrange(order, .by_group = TRUE) %>% mutate(stack_y = row_number() / n()) %>% ungroup() # 绘制严格按order顺序排列的堆叠tile图 ggplot(df_sorted, aes(x = fct_rev(fct_inorder(name)), y = stack_y)) + geom_tile(aes(fill = color), height = 1) + # height设为1填满组内y轴范围 coord_flip() + labs( title = "svVis::give_theme_and_color_set() 内置配色方案与主题\n", x = "", y = "" ) + theme_minimal() + scale_fill_identity() + give_theme_and_color_set("sv0_allmain")[["theme"]] + theme( axis.text.x = element_blank(), axis.ticks.x = element_blank() )
原理说明
- 数据排序:通过
group_by(name)和arrange(order)确保每个name组内的颜色顺序完全匹配order变量的定义 - 手动分配y轴位置:用
row_number()/n()计算每个tile的y轴坐标,让同组内的tile均匀分布在0到1的区间内 - 固定tile高度:
height=1让每个tile填满对应的y轴区间,实现和position="stack"一致的堆叠视觉效果,同时严格遵循数据排序顺序
内容的提问来源于stack exchange,提问作者Cheroff_Faces
相关产品推荐
相关产品推荐

