R ggplot2绘制堆叠柱状图时如何将线条延伸至绘图区边缘
问题原因
之前两种调整方式不生效,核心是geom_line仅会基于传入数据中实际存在的x坐标点位绘制线段,即使手动扩展x轴范围,只要参考线数据源没有对应绘图区左右边缘的点位,线段就不会自动拉长到边界。
实现方案
方案1(固定产能阈值场景,最优解,全自动适配)
你的示例数据中Capacity是固定产能值,不需要随周变化绘制折线,直接将geom_line替换为geom_hline即可。geom_hline绘制的水平线默认会贯穿整个绘图区域的左右边缘,后续新增周数据时会自动适配x轴范围,完全不需要手动指定日期边界。
完整可运行代码:
library(tidyverse) library(lubridate) my_df <- tibble( Week = c(ymd("2022-06-06"),ymd("2022-06-06"),ymd("2022-06-06"),ymd("2022-06-06")+7,ymd("2022-06-06")+7, ymd("2022-06-06")+7), Scenario = c("Conservative","Likely","Aggressive","Conservative","Likely","Aggressive"), Hours = c(100,50,35,150,65,25), Capacity = c(110,110,110,110,110,110) ) ggplot(my_df, aes(fill=factor(Scenario, levels = c("Conservative","Likely","Aggressive")), y=Hours, x=Week, label = Hours)) + geom_bar(position="stack", stat="identity") + # 绘制贯穿全图的产能参考线,去重避免重复绘制相同线条 geom_hline(yintercept = unique(my_df$Capacity), linewidth = 0.5) + theme(legend.title= element_blank())
如果需要调整线条样式,直接在geom_hline内传入linetype、color等参数即可,用法和geom_line完全一致。
方案2(产能随周变动场景,全自动无需手动写日期)
如果你的Capacity值每周会发生变化,需要绘制折线而非水平直线,可以自动计算x轴扩展后的边界范围,给参考线数据集补全边缘点位,不需要每次手动修改日期参数:
library(tidyverse) library(lubridate) my_df <- tibble( Week = c(ymd("2022-06-06"),ymd("2022-06-06"),ymd("2022-06-06"),ymd("2022-06-06")+7,ymd("2022-06-06")+7, ymd("2022-06-06")+7), Scenario = c("Conservative","Likely","Aggressive","Conservative","Likely","Aggressive"), Hours = c(100,50,35,150,65,25), Capacity = c(110,110,110,120,120,120) # 示例为第二周产能变化的场景 ) # 自动计算x轴延伸后的左右边界,延伸比例和ggplot默认边距匹配 x_boundary <- extendrange(my_df$Week, f = 0.05) # 构造参考线数据集,补充左右边缘的点位 cap_line_df <- my_df %>% distinct(Week, Capacity) %>% add_row(Week = x_boundary[1], Capacity = first(.$Capacity)) %>% add_row(Week = x_boundary[2], Capacity = last(.$Capacity)) %>% arrange(Week) ggplot(my_df, aes(fill=factor(Scenario, levels = c("Conservative","Likely","Aggressive")), y=Hours, x=Week, label = Hours)) + geom_bar(position="stack", stat="identity") + # 传入补全后的参考线数据,关闭继承的填充映射避免报错 geom_line(data = cap_line_df, aes(x=Week, y=Capacity), inherit.aes = FALSE, linewidth = 0.5) + # x轴延伸比例和之前extendrange的f参数保持一致 scale_x_date(expand = expansion(mult = c(0.05, 0.05))) + theme(legend.title= element_blank())
每周更新数据时,代码会自动识别最新的日期范围计算边界,不需要手动调整x轴参数。
内容的提问来源于stack exchange,提问作者Stephen Poole
相关产品推荐
相关产品推荐

