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

ggplot绘制两数据框图形时如何保持相同类别配色一致

配色不一致的核心原因

你的代码存在3个直接导致配色错位的问题:

  • 折线图将Topic映射到了color(线条颜色)美学,但你仅配置了scale_fill_manual(填充色标度)的配色,没有给线条颜色指定色板,折线默认调用ggplot自带配色,完全没用到你提前定义的my_cols_one。
  • 每个子图设置标度limits时,使用的是当年数据子集的unique(.x$Topic),不同年份子集的Topic出现顺序不固定,会直接导致颜色和Topic的映射关系错位。
  • 代码存在多处笔误:排序df_two时错误引用了df_one的时间列、df_two聚合前未生成created_at字段、折线图y轴映射了不存在的avg_sentiment列、日期转换未指定匹配的格式(你的日期是日/月/年格式,默认转换会解析错误),这些问题也会间接导致绘图异常。
修正步骤

1. 固定全局Topic-颜色映射

不要使用子集的Topic列表做映射,提前固定全量Topic的顺序,保证所有图的颜色匹配规则完全统一:

library(randomcoloR)
library(tidyverse)
library(lubridate)
library(gridExtra)

# 取两个数据框的所有Topic值,固定顺序
all_topics <- unique(c(df_one$Topic, df_two$Topic))
# 生成对应数量的配色,按固定Topic顺序命名
my_cols <- distinctColorPalette(length(all_topics))
names(my_cols) <- all_topics

2. 修正df_one的预处理和面积图绘制代码

补全笔误,固定fill标度的limits为全量Topic列表:

# df_one预处理:指定日期格式,避免解析错误
df_one$Timestamp <- as.Date(df_one$Timestamp, format = "%d/%m/%Y")
df_one <- df_one[order(df_one$Timestamp),]

list_one <- df_one %>%
  mutate(year = year(Timestamp)) %>%
  split(.$year) %>%
  map(~ggplot(.x, aes(x=Timestamp, y=Value_A, fill=Topic)) + 
        scale_x_date(date_breaks = '1 month', date_labels = "%b-%y")+
        geom_area(alpha=0.6 , linewidth=1, colour="black", position = position_fill())+
        theme(legend.position="bottom", legend.box = "horizontal")+
        ggtitle("Reliable")+
        guides(fill = guide_legend(nrow = 2, label.position = "bottom")) +
        # 固定limits为全量Topic,保证映射一致
        scale_fill_manual(NULL, values = my_cols, limits = all_topics)
  )

3. 修正df_two的预处理和折线图绘制代码

补上scale_color_manual调用同一套色板,修正所有笔误,固定color标度的limits:

# df_two预处理:修正日期解析、排序、聚合逻辑的笔误
df_two$Timestamp <- as.Date(df_two$Timestamp, format = "%d/%m/%Y")
df_two <- df_two[order(df_two$Timestamp),]

df_two <- df_two %>% 
  mutate(created_at = floor_date(Timestamp, "15 days")) %>%
  group_by(created_at, Topic) %>% 
  summarise(Average_Value = mean(Value_B), .groups = "drop")

list_two <- df_two %>%
  mutate(year = year(created_at)) %>%
  split(.$year) %>%
  map(~ggplot(.x, aes(x=created_at, y=Average_Value, color=Topic)) + 
        scale_x_date(date_breaks = '1 month', date_labels = "%b-%y")+
        geom_line(linewidth=1)+
        theme(legend.position="bottom", legend.box = "horizontal", plot.background = element_blank())+
        # 对应color美学修改向导
        guides(color = guide_legend(nrow = 2, label.position = "bottom")) +
        # 给线条颜色指定同一套色板,固定limits为全量Topic
        scale_color_manual(NULL, values = my_cols, limits = all_topics)+
        labs(x = 'Date', y = 'Average Value', color="")
  )

4. 按年度配对拼接图形

直接拼接两个列表会出现3张面积图全部排完再排3张折线图的问题,需要按年交叉排列,实现同一年的面积图、折线图上下配对:

# 按年份交叉组合图形
year_list <- sort(intersect(names(list_one), names(list_two)))
plot_order <- unlist(lapply(year_list, function(y) c(list_one[[y]], list_two[[y]])), recursive = F)

do.call("grid.arrange", c(plot_order, ncol=2))

修正后所有图中相同Topic的颜色会完全统一,图形排布也符合分年度上下对照的需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:48:23