拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Matplotlib 瀑布图(Waterfall Chart)讲解

Matplotlib 瀑布图(Waterfall Chart)讲解

一、什么是瀑布图

瀑布图用来展示初始值,经过多轮增减之后得到最终值,可以直观看到每一项对总量的贡献。

特点:

  • 柱子从前一项的终点开始向上 / 向下延伸
  • 正数向上,负数向下
  • 一般用不同颜色区分:增加、减少、总计

matplotlib 本身没有内置瀑布图函数,需要我们手动计算每个柱子的底部位置来绘制。

二、瀑布图(Waterfall Chart)应用场景

1.财务分析

  1. 利润拆解:营业收入 → 减营业成本 → 减各项费用 → 加其他收益 → 减所得税 →净利润一眼看清:哪一项侵蚀利润、哪一项带来收益。
  2. 现金流分析(刚才示例):期初现金,加减经营、投资、融资现金流,得到期末现金。
  3. 预算差异分析:目标预算为基数,各项超支 / 节约,最后得到实际总额。
  4. 净资产变动:期初所有者权益,加上净利润、分红、股本变动,得到期末净资产。

2.业务指标归因分析(数据分析 / 运营)

用来做指标拆解,定位增长或下滑原因

  • 营收拆解:上期营收 → 新增用户收入 + 老用户复购收入 - 用户流失损失 → 本期营收
  • 用户量变化:期初用户数 + 新增用户 - 流失用户 = 期末用户
  • GMV 拆解:基准 GMV + 活动增量 - 退款金额 = 最终 GMV

3.项目成本与投资测算

  • 项目总投资测算:基础造价 + 设备采购 + 人工成本 - 补贴 / 优惠 = 项目总投入
  • 投资收益测算:初始投入 + 每年收入 - 运营成本 = 净收益

4.供应链、库存管理

库存数量变动:期初库存 + 入库数量 - 出库数量 - 损耗 = 期末库存。

5. 工程 / 制造业:工程量、能耗分析

  • 能耗:基准能耗 + 新增设备耗能 - 节能改造节省能耗 = 最终能耗。

三、不适合使用瀑布图的场景

  1. 只想看各部分占整体百分比→ 用饼图,不要瀑布图。
  2. 多组数据对比(5 个部门同时做瀑布对比会很乱),少量组别可以,多了不推荐。
  3. 分类没有先后加减逻辑,只是独立分类,不要强行用瀑布图。

对比:瀑布图 vs 其他图表

  • 柱状图:直接对比独立类别大小,没有 “连续累加” 含义
  • 饼图:静态构成占比,不能表达增减变化过程
  • 瀑布图:专门表达从初始值,逐项加减,得到最终结果

四、完整代码 + 逐行讲解

python

import matplotlib.pyplot as plt import numpy as np # ---------------------- 1. 准备数据 ---------------------- # 标签:各项名称 labels = ["期初", "营收增加", "成本减少", "费用支出", "税收", "期末"] # 数值:期初是初始基数,后面是每一步变化量,最后一项为0(用来画总计) values = [100, 40, 10, -25, -15, 0] # 计算每个柱子的底部基线 base base = np.zeros(len(values)) for i in range(1, len(values)-1): base[i] = base[i-1] + values[i-1] # 最后一个柱子(期末总计),基线=前面所有累加和 base[-1] = base[-2] + values[-2] values[-1] = base[-1] # 总计柱子高度等于最终值 # ---------------------- 2. 设置颜色 ---------------------- colors = [] for i, v in enumerate(values): if i == 0: colors.append("#1f77b4") # 期初:蓝色 elif i == len(values)-1: colors.append("#ff7f0e") # 期末总计:橙色 elif v > 0: colors.append("#2ca02c") # 增加:绿色 else: colors.append("#d62728") # 减少:红色 # ---------------------- 3. 绘图 ---------------------- plt.figure(figsize=(10,6)) bars = plt.bar(labels, values, bottom=base, color=colors, edgecolor="black") # 在柱子上方添加数值标签 for bar in bars: height = bar.get_height() y_pos = bar.get_y() + height plt.text(bar.get_x() + bar.get_width()/2, y_pos, f"{height:.0f}", ha="center", va="bottom", fontsize=11) # ---------------------- 4. 美化图表 ---------------------- plt.title("瀑布图示例:现金流变化", fontsize=14) plt.ylabel("金额", fontsize=12) plt.grid(axis="y", alpha=0.3) plt.tight_layout() plt.show()

五、核心原理讲解

plt.bar(x, height, bottom=base)

  • height:柱子高度(变化量)
  • bottom:柱子底部的 y 坐标,瀑布图的精髓就是不断更新 bottom 基线!

举个简单逻辑:

  1. 第 0 项(期初):bottom=0,柱子从 0 到 100
  2. 第 1 项(营收 + 40):bottom=100,柱子从 100 向上加到 140
  3. 第 2 项(成本 + 10):bottom=140,柱子从 140 向上加到 150
  4. 第 3 项(费用 - 25):bottom=150,柱子向下到 125
  5. 第 4 项(税收 - 15):bottom=125,柱子向下到 110
  6. 最后一项期末:bottom=0,高度 = 110,直接画一根从 0 到 110 的总计柱

六、运行结果说明

  • 蓝色:期初基数
  • 绿色:正向增加
  • 红色:负向扣减
  • 橙色:期末汇总,直观对比期初和最终结果

七、常见坑

  1. 忘记计算bottom基线:所有柱子都从 y=0 开始,变成普通柱状图,不是瀑布图
  2. 总计项处理错误:总计柱子不能沿用前面的 bottom,要从 0 开始画
  3. 负数标签位置:va="bottom"在负数时会跑到柱子下面,可做 if 判断微调文字位置
返回列表