You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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()
  )

原理说明

  1. 数据排序:通过group_by(name)和arrange(order)确保每个name组内的颜色顺序完全匹配order变量的定义
  2. 手动分配y轴位置:用row_number()/n()计算每个tile的y轴坐标,让同组内的tile均匀分布在0到1的区间内
  3. 固定tile高度:height=1让每个tile填满对应的y轴区间,实现和position="stack"一致的堆叠视觉效果,同时严格遵循数据排序顺序

内容的提问来源于stack exchange,提问作者Cheroff_Faces

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 11:54:52