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

R ggplot2 geom_area堆积面积图按颜色序列调整图例顺序

解决方案

针对两个需求分别提供可直接运行的实现方法:

1. 调整图例顺序匹配堆叠区域自上而下的颜色序列

geom_area搭配position = position_fill()时,默认堆叠规则为:分组因子的第一个水平放在最底层,最后一个水平放在最顶层,默认图例顺序和从底到顶的层顺序一致。要让图例顺序和2019年初始位置自上而下的颜色对应,操作步骤如下:

  • 先提取最早时间点的堆叠顺序,按频率降序排列得到自上而下的Topic序列
  • 在填充标度中指定breaks为提取到的顺序即可
    对应代码:
library(tidyverse)

# 提取最左侧(2019年初)时间点自上而下的主题顺序
top_to_bottom_order <- df %>%
  filter(Timestamp == min(Timestamp)) %>%
  arrange(desc(Frequency)) %>%
  pull(Topic)

# 调整后绘图代码
ggplot(df, aes(x=Timestamp, y=Frequency, fill=Topic)) + 
  scale_x_date(date_breaks = '1 month', date_labels = "%b-%y")+
  geom_area(alpha=0.6 , size=1, colour="black", position = position_fill())+
  # 指定图例顺序为自上而下的色块序列
  scale_fill_discrete(breaks = top_to_bottom_order, guide = guide_legend()) +
  theme(legend.position="bottom", legend.box = "horizontal")+
  ggtitle("Questionable")+
  xlab("Month")+
  guides(fill = guide_legend(nrow = 1))

运行后图例第一个条目就是2019年最顶部的色块,后续条目依次向下对应。如果需要匹配其他时间点的堆叠顺序,替换filter(Timestamp == min(Timestamp))中的时间筛选条件即可。

2. 将分年份的图例放置在对应年份下方

ggplot2原生不支持将单个连续图例拆分后定位到x轴的不同分段位置,最简便稳定的实现方案是按年份拆分绘制子图,将每个子图的图例放在自身底部后再拼合为整图:

library(patchwork)
library(lubridate)

# 新增年份字段
df <- df %>% mutate(Year = year(Timestamp))

# 定义单年份绘图函数
draw_year_plot <- function(input_year, show_y_axis = FALSE) {
  df_sub <- df %>% filter(Year == input_year)
  
  ggplot(df_sub, aes(x=Timestamp, y=Frequency, fill=Topic)) + 
    scale_x_date(date_breaks = '2 month', date_labels = "%b")+
    geom_area(alpha=0.6 , size=1, colour="black", position = position_fill())+
    # 保持全局统一的图例顺序,仅显示当年存在的主题
    scale_fill_discrete(breaks = top_to_bottom_order, drop = TRUE) +
    theme(
      legend.position="bottom",
      axis.title.y = if(show_y_axis) element_text() else element_blank(),
      axis.text.y = if(show_y_axis) element_text() else element_blank(),
      axis.ticks.y = if(show_y_axis) element_line() else element_blank(),
      plot.title = element_text(hjust = 0.5)
    )+
    ggtitle(paste0(input_year, "年"))+
    xlab("")+
    guides(fill = guide_legend(nrow = 1, title = NULL))
}

# 拼合三年的图,仅在第一个子图显示y轴
draw_year_plot(2019, show_y_axis = TRUE) + 
  draw_year_plot(2020) + 
  draw_year_plot(2021) +
  plot_layout(nrow = 1) &
  ylab("占比")

如果需要保留连续的x轴不拆断,也可以通过annotation_custom在对应年份的x轴位置下方手动添加图例grob,但代码复杂度高,适配调整成本大,一般优先选择子图拼合方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 02:30:15