如何绘制Jonathan A. Schwabish(JEP 2014)格式带时间变化线的堆叠柱状图
符合Schwabish(JEP 2014)规范的堆叠柱状图+趋势折线R实现
示例数据集
你提供的两个测试数据集如下:
df_input <- data.frame( Year= c(2010,2010,2010,2010,2020,2020,2020,2020), village= c("A","B","C","D","A","B","C","D"), share = c(40,30,20,10,30,30,25,15)) df_input_2 <- data.frame( Year= c(2010,2010,2010,2010,2015,2015,2015,2015,2020,2020,2020,2020), village= c("A","B","C","D","A","B","C","D"), share = c(40,30,20,10,30,30,25,15,20,10,30,40))
实现依赖
仅需安装加载ggplot2常用包即可,代码适配tidyverse最新版本。
核心规范适配点
完全遵循Jonathan A. Schwabish在JEP 2014中提出的可视化规范要求:
- 移除顶部、右侧多余边框,最小化非数据墨水占比
- 仅保留必要的浅色水平网格线,避免干扰主体数据展示
- 每个堆叠段直接标注数值,降低读者信息获取成本
- 配色选用色弱友好、黑白打印也可区分的色系
- 所有标签字体大小适配常规阅读场景,可读性强
完整实现代码
我们选用时间点更丰富的df_input_2作为绘制数据,代码如下:
library(ggplot2) df <- df_input_2 ggplot(df, aes(x = as.factor(Year), y = share, fill = village)) + # 堆叠柱状图,白色细边框分隔不同村的柱段 geom_col(position = "stack", color = "white", linewidth = 0.3) + # 堆叠趋势折线,对齐到柱段中心,和柱形位置完全匹配 geom_line(aes(color = village, group = village), position = position_stack(vjust = 0.5), linewidth = 1) + # 柱段内部标注数值 geom_text(aes(label = paste0(share, "%")), position = position_stack(vjust = 0.5), size = 3.5, color = "#1a1a1a") + # 极简主题调整 theme_minimal() + theme( panel.grid.minor = element_blank(), panel.grid.major.x = element_blank(), panel.grid.major.y = element_line(color = "#f0f0f0"), axis.line = element_line(color = "#333333"), axis.text = element_text(size = 10, color = "#333333"), axis.title = element_text(size = 11, color = "#333333"), legend.title = element_text(size = 11, color = "#333333"), legend.position = "bottom", plot.margin = margin(10, 10, 10, 10, unit = "pt") ) + labs( x = "年份", y = "占比(%)", fill = "村庄", color = "村庄" ) + scale_y_continuous(limits = c(0, 100), breaks = seq(0, 100, 20)) + scale_fill_brewer(palette = "Set2") + scale_color_brewer(palette = "Set2")
关键参数说明
position_stack(vjust = 0.5):保证折线和数值标签都对齐到对应堆叠柱段的中心,不会出现和柱形错位的问题- 配色选用
Set2调色板,不同村庄的色块、折线区分度足够,同时适配彩色显示和黑白打印场景 - 折线宽度调整为1,比柱段边框更粗,保证趋势走向清晰可辨
内容的提问来源于stack exchange,提问作者Fuser
相关产品推荐
相关产品推荐

