如何在ggplot中叠加不同宽度柱状图:实现城乡收支分位数可视化
解决方案:实现双维度并列叠加柱状图
需求梳理
- 每个Decile分组下,**收入(income)与支出(expenditures)**柱状图并列展示
- 农村数据:背景宽柱状图,透明度(alpha)设为0.5
- 城市数据:前景窄柱状图,叠加在农村柱子上方
- 收入对应左侧Y轴,支出对应右侧Y轴
问题分析
原代码生成的图表存在以下问题:
- 收入与支出的柱状图在同一x位置重叠,无法实现并列展示
- 未区分农村/城市数据的柱子宽度与层级,没有形成背景与前景的叠加效果
- 双Y轴直接复制左侧刻度,若收入与支出数据范围不同,会导致其中一类数据显示失真
- fill和alpha的映射未与城乡数据精准绑定,无法实现农村柱半透明的效果
修改后代码
确保数据已加载,且包含Decile(分位数)、Divide(城乡:农村/城市)、Avg.q.hou.inc(收入)、Avg.q.hou.exp(支出)字段:
library(ggplot2) library(scales) library(viridis) # 加载数据(替换为你的数据文件路径) # data <- read.csv("数据文件路径") # 生成Viridis配色,对应10个Decile分组 color <- viridis(10) # 计算收入与支出的比例,用于双Y轴刻度转换(避免数据范围差异导致的显示失真) inc_range <- range(data$Avg.q.hou.inc, na.rm = TRUE) exp_range <- range(data$Avg.q.hou.exp, na.rm = TRUE) scale_factor <- exp_range[2] / inc_range[2] # 绘制图表 ggplot() + # 农村收入:背景宽柱,alpha=0.5 geom_col(data = subset(data, Divide == "农村"), aes(x = as.numeric(Decile) - 0.2, y = Avg.q.hou.inc, fill = Decile), width = 0.35, alpha = 0.5) + # 城市收入:前景窄柱,叠加在农村收入柱上方 geom_col(data = subset(data, Divide == "城市"), aes(x = as.numeric(Decile) - 0.2, y = Avg.q.hou.inc, fill = Decile), width = 0.2) + # 农村支出:背景宽柱,alpha=0.5(需按比例缩放适配左侧Y轴) geom_col(data = subset(data, Divide == "农村"), aes(x = as.numeric(Decile) + 0.2, y = Avg.q.hou.exp / scale_factor, fill = Decile), width = 0.35, alpha = 0.5) + # 城市支出:前景窄柱,叠加在农村支出柱上方 geom_col(data = subset(data, Divide == "城市"), aes(x = as.numeric(Decile) + 0.2, y = Avg.q.hou.exp / scale_factor, fill = Decile), width = 0.2) + # 配置Decile分组配色 scale_fill_manual(values = color) + # 双Y轴设置:左侧为收入,右侧为支出(通过scale_factor还原刻度) scale_y_continuous(name = "季度家庭平均收入", labels = comma, sec.axis = sec_axis(~ . * scale_factor, name = "季度家庭平均支出", labels = comma)) + # 将x轴转换为Decile标签 scale_x_continuous(breaks = 1:10, labels = paste0("Decile ", 1:10)) + # 主题优化 theme_minimal() + theme(legend.position = "bottom", axis.title.y.right = element_text(color = "#2c7fb8"), axis.title.y.left = element_text(color = "#d95f02"))
代码说明
- x轴偏移:将
Decile转为数值后,收入柱左移0.2、支出柱右移0.2,实现同一Decile下两类数据的并列效果 - 柱子宽度区分:农村柱宽设为0.35,城市柱宽设为0.2,形成背景与前景的层级差异
- 双Y轴刻度适配:通过计算收入与支出的最大比例,将支出数据缩放后适配左侧Y轴,右侧轴再反向还原刻度,保证数据显示准确
- 图层分层逻辑:先绘制农村背景柱,再叠加城市前景柱,确保层级关系正确
- 视觉优化:用Viridis色系区分10个Decile,调整轴标题颜色强化收入/支出的区分度
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

