Waterfall Chart
Operating Cash Flow Waterfall
Cash flow from operations breakdown showing sources and uses of operating cash.
Output
Python
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Patch
categories = ['Net\nIncome', 'Depreciation', 'Amortization', 'Stock\nComp',
'Receivables', 'Inventory', 'Payables', 'Accruals', 'Operating\nCash Flow']
values = [0, 65, 28, 35, -42, -28, 38, 15, 0]
initial = 195
running_total = initial
bottoms, heights, colors = [], [], []
for i, (cat, val) in enumerate(zip(categories, values)):
if cat == 'Net\nIncome':
bottoms.append(0)
heights.append(initial)
colors.append('#276CF5')
elif 'Operating' in cat:
bottoms.append(0)
heights.append(running_total)
colors.append('#6CF527')
elif val > 0:
bottoms.append(running_total)
heights.append(val)
colors.append('#27F5B0')
running_total += val
else:
bottoms.append(running_total + val)
heights.append(abs(val))
colors.append('#F5276C')
running_total += val
fig, ax = plt.subplots(figsize=(14, 8), facecolor='#0a0a0f')
ax.set_facecolor('#0a0a0f')
x = np.arange(len(categories))
bars = ax.bar(x, heights, bottom=bottoms, color=colors, width=0.65, edgecolor='#1e293b', linewidth=1)
for i, (bar, val, bot, height) in enumerate(zip(bars, values, bottoms, heights)):
y_pos = bot + height / 2
if categories[i] == 'Net\nIncome' or 'Operating' in categories[i]:
label = f"${height}M"
ax.text(bar.get_x() + bar.get_width()/2, y_pos, label, ha='center', va='center',
fontsize=11, fontweight='bold', color='white')
else:
label = f"+${val}M" if val > 0 else f"-${abs(val)}M"
ax.text(bar.get_x() + bar.get_width()/2, y_pos, label, ha='center', va='center',
fontsize=10, fontweight='bold', color='white')
for i in range(len(x) - 1):
y = initial if i == 0 else bottoms[i] + heights[i]
ax.plot([x[i] + 0.35, x[i+1] - 0.35], [y, y], color='#475569', linestyle='--', linewidth=1.5, alpha=0.7)
ax.set_xlim(-0.6, len(categories) - 0.4)
ax.set_ylim(0, max(b + h for b, h in zip(bottoms, heights)) * 1.1)
ax.set_xticks(x)
ax.set_xticklabels(categories, fontsize=9, color='#e2e8f0')
ax.set_ylabel('Cash Flow ($ Millions)', fontsize=12, color='#e2e8f0', fontweight='500')
ax.set_title('Operating Cash Flow Build-up', fontsize=16, color='white', fontweight='bold', pad=20)
ax.tick_params(axis='y', colors='#e2e8f0', labelsize=10)
ax.yaxis.grid(True, linestyle='--', alpha=0.3, color='#334155')
ax.set_axisbelow(True)
for spine in ax.spines.values():
spine.set_color('#334155')
conversion = (running_total / initial) * 100
ax.annotate(f'Cash Conversion: {conversion:.0f}%', xy=(0.98, 0.95), xycoords='axes fraction',
fontsize=11, color='#6CF527', ha='right', fontweight='bold',
bbox=dict(boxstyle='round,pad=0.4', facecolor='#1e293b', edgecolor='#6CF527', alpha=0.9))
legend_elements = [Patch(facecolor='#276CF5', label='Net Income'), Patch(facecolor='#27F5B0', label='Add-backs'),
Patch(facecolor='#F5276C', label='Working Capital Use'), Patch(facecolor='#6CF527', label='Operating CF')]
ax.legend(handles=legend_elements, loc='upper left', bbox_to_anchor=(0, -0.1), ncol=4, fontsize=9,
facecolor='#1e293b', edgecolor='#334155', labelcolor='white')
plt.tight_layout()
plt.subplots_adjust(bottom=0.15)
plt.show()
Library
Matplotlib
Category
Financial
More Waterfall Chart examples
☕