Waterfall Charts Explained

โฑ๏ธ 35 sec read ๐Ÿ“Š Visualization

A waterfall chart shows how a starting value becomes an ending value through a sequence of additions and subtractions โ€” each floating bar picks up where the last one ended. It's the standard chart for explaining a change: revenue to net income, last year's headcount to this year's, budget to actual.

How Does a Waterfall Chart Work?

The first and last bars are anchored to zero (the start and end totals); every bar in between floats, starting at the previous bar's running total and moving up for gains or down for losses. Color codes the direction โ€” typically green up, red down, gray for totals.

# Running totals for a simple P&L bridge:
# Revenue        +500   (starts at 0, ends at 500)
# COGS           -200   (starts at 500, ends at 300)
# Gross Profit    300   (anchored total)
# Opex           -180   (starts at 300, ends at 120)
# Tax             -30   (starts at 120, ends at 90)
# Net Income       90   (anchored total)

How Do You Build a Waterfall Chart (P&L Example)?

Plotly has a native waterfall trace; in matplotlib you fake it with bars whose bottoms are the running cumulative sum. The measure list marks which bars are floating deltas and which are anchored totals.

import plotly.graph_objects as go

fig = go.Figure(go.Waterfall(
    x=["Revenue", "COGS", "Gross Profit", "Opex", "Tax", "Net Income"],
    measure=["relative", "relative", "total",
             "relative", "relative", "total"],
    y=[500, -200, 0, -180, -30, 0],
))
fig.show()
# Bars step down from 500 to 90, totals anchored at zero

When Should You Use a Waterfall Instead of a Stacked Bar?

Use a waterfall when the story is a sequence of changes between two states, especially with a mix of positive and negative steps; use a stacked bar when the story is the composition of a single total. A stacked bar can't show subtractions at all โ€” negative segments break the stack โ€” while a waterfall handles them naturally.

Common Pitfalls

Pro Tip: Sanity-check every waterfall: start value plus all the deltas must equal the end bar exactly. If it doesn't, you have a hidden bucket โ€” add an explicit "Other" bar rather than letting the bridge silently not reconcile.

โ† Back to Visualization Tips