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
相关产品推荐
相关产品推荐

