打破堆积困局:优化堆积条形图的对比效果

在数据可视化中,堆积条形图 擅长展示 "整体与构成" 的关系,但当每个柱子内的分段超过4个时,读者很难同时追踪各段的长度、位置与颜色映射, 误读概率显著上升

更糟的是,若不同类别的总量差异很大,堆积结构会放大视觉错觉,导致"看起来差不多"的结论失真。

今天,本文将尝试探索一下改进堆积条形图的呈现方式,让复杂数据对比变得一目了然。

如果大家有更好的方式,也欢迎指教,交流。完整的代码会在文末提供共享的地址。

1. 堆积条形图的困境

堆积条形图就像一道精心摆盘的多层蛋糕,当层数不多时,我们能轻松分辨每层的高度差异。

但当蛋糕层数超过4层,要比较某一特定口味在多个蛋糕中的含量就变得异常困难。

下面我们用Python模拟一个常见的堆积条形图场景:调查某产品5个功能模块的用户满意度(5个维度),共收集了4个季度的数据。

python 复制代码
# 模拟数据:4个季度,5个满意度维度(强烈反对、反对、中立、同意、坚决同意)
quarters = ["第一季度", "第二季度", "第三季度", "第四季度"]
categories = ["强烈反对", "反对", "中立", "同意", "坚决同意"]
colors = ["#FF6B6B", "#FF9F6B", "#D6CBCB", "#6BCF7F", "#4D96FF"]

# 每个季度的满意度分布(百分比)
data = np.array(
    [
        [5, 10, 25, 40, 20],  # 第一季度
        [3, 8, 20, 45, 24],  # 第二季度
        [4, 12, 18, 43, 23],  # 第三季度
        [2, 6, 15, 50, 27],  # 第四季度
    ]
)

# 传统横向堆积条形图
fig, ax = plt.subplots(1, 2, figsize=(14, 4), gridspec_kw={"width_ratios": [1, 1]})

# 左图:传统横向堆积条形图
# ... 省略 ...

# 右图:横向堆叠条形图的改进版,添加分隔线
# ... 省略 ...

plt.tight_layout()
plt.show()

这个横向堆积条形图展示了每个季度用户满意度的完整分布,随便右边的图稍微做了一些改进,

但如果我们想回答以下问题就会遇到困难:

  • "坚决同意" 的比例在哪个季度最高?
  • "反对""强烈反对" 的比例如何随时间变化?

2. 拆解重构--多个子图

与其把所有食材炖在一锅里,不如将它们分盘摆放。

我们将堆积条形图拆解为5个小图,每个小图只关注一个满意度维度的季度变化。

python 复制代码
import matplotlib.gridspec as gridspec

fig = plt.figure(figsize=(12, 6))
gs = gridspec.GridSpec(2, 5, figure=fig, hspace=0.3, wspace=0.4)
# 拆解堆积条形图:为每个类别创建单独的横向子图
axes = []
for i in range(5):
    axes.append(fig.add_subplot(gs[0, i]))

# 为每个满意度维度创建一个横向条形图
for i, (category, color, ax) in enumerate(zip(categories, colors, axes)):
    # ... 省略 ...

ax = fig.add_subplot(gs[1, :]) # 第1行,所有列 (等同于 gs[1, 0:5])
# ... 省略 ...

plt.show()

拆解后的图表确实提升了单一维度的对比效果,但仍有一个明显问题:我们的视线需要在多个图表间来回跳跃,无法形成统一的视觉印象。

这就像阅读一本分散在多个页面的表格,需要不断翻页对照。

3. 双向对比--蝴蝶图

蝴蝶图(也称为人口金字塔图或双向条形图)是数据可视化的"瑞士军刀",特别适合展示对立或双向比较的数据。

它的设计哲学是:让对比在中心轴两侧自然展开,就像蝴蝶展开双翅。

python 复制代码
# 4. 创建画布
fig, ax = plt.subplots(2, 1,figsize=(10, 6))
y_pos = np.arange(len(quarters))
# 拆分数据列
strongly_disagree = data[:, 0]
disagree          = data[:, 1]
neutral           = data[:, 2]
agree             = data[:, 3]
strongly_agree    = data[:, 4]

# ==========================================
# 核心逻辑修改:以中立(Neutral)的中心为0点
# ==========================================
# 1. 绘制中立 (灰色):跨越 0 轴
# left 从 -width/2 开始,这样 0 就在正中间

# 2. 绘制左侧 (负面情绪):向左堆叠
# 反对 (Green):起始位置在 -neutral/2 的左边

# 强烈反对 (Purple):起始位置在 反对 的左边

# 3. 绘制右侧 (正面情绪):向右堆叠
# 同意 (Orange):起始位置在 neutral/2

# 强烈同意 (Red):起始位置在 同意 的右边

# 5. 美化图表
# 添加中间的基准线 (穿过中立条形)
# ... 省略 ...
plt.show()

蝴蝶图和一般的堆积条形图放在一起,可以明显看出两者在数据展示逻辑和视觉重心上有显著区别。

蝴蝶图 侧重于展示 "对立态度的对比",适合看正反两面的力量悬殊以及整体的情绪倾向,而且也便于比较同侧的数据。

4. 总结

总之,堆积条形图像一锅大杂烩,当食材(数据维度)过多时,我们很难品尝(分析)到每种食材的原味。

通过拆解和重构,我们获得了更清晰的视角。而蝴蝶图则像一位优雅的舞者,将对比数据以对称的方式展开,既保留了整体视野,又强化了局部对比。

优秀的数据可视化不在于展示所有信息,而在于以最少的认知成本传达最多的洞察。

下次当我们面对多维数据对比的挑战时,不妨试试横向蝴蝶图这把"瑞士军刀",它可能会给你带来意想不到的清晰与美感。

绘制文中图像的完整代码共享在:优化堆积条形图.ipynb (访问密码: 6872)

相关推荐
实战项目3 小时前
大数据分析XX未来五年的房价走势
数据挖掘·数据分析
叫我:松哥7 小时前
基于Flask框架开发的二手房数据分析与推荐管理平台,集成大数据分析、机器学习预测和智能推荐技术
大数据·python·深度学习·机器学习·数据分析·flask
YangYang9YangYan7 小时前
2026高职计算机专业学习数据分析指南
学习·数据挖掘·数据分析
lingling00920 小时前
2026 年 BI 发展新趋势:AI 功能如何让数据分析工具 “思考” 和 “对话”?
大数据·人工智能·数据分析
运营秋秋21 小时前
数据分析:超越阅读量,读懂数据背后的“用户语言”
数据挖掘·数据分析·运营
wang_yb1 天前
你真的会用 Python 的 print 吗?
python·databook
踏歌~1 天前
突击债市高频交易(固收)面试
数据分析
Turboex邮件分享1 天前
邮件系统的未来趋势:AI、机器学习与大数据分析的融合应用
人工智能·机器学习·数据分析
大闲在人1 天前
惠普利用运筹学改进打印机生产线的设计
数据分析·供应链管理·智能制造