如何为ggplot2中%b-%Y格式月份变量按月份统一设置调色板
解决滚动12个月柱状图同月份同配色的问题
问题描述
我有一个按%b-%Y格式的MonthYear字段分组统计的滚动12个月数据框,使用ggplot2结合plotly绘制了柱状图。由于滚动数据包含2023年1月和2024年1月,希望同月份(如Jan-2023与Jan-2024)使用同一配色,无需每月手动修改scale_fill_manual参数。此前尝试编写的月份-颜色映射代码导致所有柱子显示为灰色,现寻求解决方案。
核心原因
之前的代码中,填充变量用的是MonthYear(如"Jan-2023"),但颜色映射的键是月份缩写(如"Jan"),两者无法匹配,ggplot找不到对应颜色时会默认使用灰色。
解决方案
方案1:提前提取月份字段(推荐)
在生成overviewdt时新增一个纯月份字段,用这个字段做填充映射,适配动态滚动数据:
# 生成带纯月份字段的数据框 overviewdt <- aefis_filtered %>% mutate(MonthYear = format(ymd(gen_reportdate), "%b-%Y"), # 提取月份缩写(如"Jan") Month = format(ymd(gen_reportdate), "%b")) %>% group_by(MonthYear, Month) %>% summarise(Count = n_distinct(other_record_id)) %>% mutate(Total = cumsum(Count)) %>% as.data.frame() # 定义月份-颜色映射 month_colour_mapping <- c( "Jan" = vax_light_blue, "Feb" = vax_mid_blue, "Mar" = vax_dark_blue, "Apr" = vax_yellow, "May" = vax_orange, "Jun" = vax_dark_orange, "Jul" = vax_light_green, "Aug" = vax_green, "Sep" = vax_dark_green, "Oct" = vax_light_purple, "Nov" = vax_mid_purple, "Dec" = vax_dark_purple ) # 绘图:用Month字段做填充 overall <- ggplot(overviewdt, aes(x = MonthYear, y = Count, fill = Month, text = paste("Month - Year:", MonthYear, "\nCount:", Count))) + geom_bar(stat = "identity", width = 0.7) + scale_fill_manual(values = month_colour_mapping) + labs(x = "", y = "") + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black"), axis.text = element_text(color = "black"), legend.position = "none") ggplotly(overall, tooltip = 'text')
方案2:绘图时直接提取月份(快速调整)
如果不想修改原始数据处理流程,可在aes中直接从MonthYear提取前3位作为月份:
# 定义月份-颜色映射(同方案1) month_colour_mapping <- c( "Jan" = vax_light_blue, "Feb" = vax_mid_blue, "Mar" = vax_dark_blue, "Apr" = vax_yellow, "May" = vax_orange, "Jun" = vax_dark_orange, "Jul" = vax_light_green, "Aug" = vax_green, "Sep" = vax_dark_green, "Oct" = vax_light_purple, "Nov" = vax_mid_purple, "Dec" = vax_dark_purple ) # 绘图:直接从MonthYear提取月份做填充 overall <- ggplot(overviewdt, aes(x = MonthYear, y = Count, fill = substr(MonthYear, 1, 3), text = paste("Month - Year:", MonthYear, "\nCount:", Count))) + geom_bar(stat = "identity", width = 0.7) + scale_fill_manual(values = month_colour_mapping) + labs(x = "", y = "") + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black"), axis.text = element_text(color = "black"), legend.position = "none") ggplotly(overall, tooltip = 'text')
效果说明
两种方案都能实现同月份不同年份的柱子使用同一配色,且无需手动维护scale_fill_manual的颜色向量顺序,完美适配滚动12个月的动态数据。
内容的提问来源于stack exchange,提问作者Renee
相关产品推荐
相关产品推荐

