Waterfall Chart

Debt Reduction Waterfall

Waterfall showing debt paydown strategy across different tranches and refinancing activities.

Output
Debt Reduction Waterfall
Python
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Patch

# Debt changes (in millions)
categories = ['Beginning\nDebt', 'Term Loan\nPaydown', 'Revolver\nPaydown', 'Bond\nMaturity', 
              'Refinancing', 'New\nIssuance', 'Debt\nRepurchase', 'Ending\nDebt']
values = [0, -45, -25, -150, 0, 80, -35, 0]

# Calculate running total
initial = 520
running_total = initial
bottoms = []
heights = []
colors = []

for i, (cat, val) in enumerate(zip(categories, values)):
    if 'Beginning' in cat:
        bottoms.append(0)
        heights.append(initial)
        colors.append('#F5276C')
    elif 'Ending' in cat:
        bottoms.append(0)
        heights.append(running_total)
        colors.append('#6CF527' if running_total < initial else '#F5B027')
    elif 'Refinancing' in cat:
        bottoms.append(running_total - 40)
        heights.append(80)
        colors.append('#F5B027')
    elif val > 0:
        bottoms.append(running_total)
        heights.append(val)
        colors.append('#F54927')
        running_total += val
    else:
        bottoms.append(running_total + val)
        heights.append(abs(val))
        colors.append('#27F5B0')
        running_total += val

# Create figure
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)

# Add value labels
for i, (bar, val, bot, height) in enumerate(zip(bars, values, bottoms, heights)):
    y_pos = bot + height / 2
    if 'Beginning' 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')
    elif 'Ending' 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='#0a0a0f')
    elif 'Refinancing' in categories[i]:
        label = "Swap"
        ax.text(bar.get_x() + bar.get_width()/2, y_pos, label, 
                ha='center', va='center', fontsize=10, fontweight='bold', color='#0a0a0f')
    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')

# Styling
ax.set_xlim(-0.6, len(categories) - 0.4)
ax.set_ylim(0, initial * 1.1)
ax.set_xticks(x)
ax.set_xticklabels(categories, fontsize=9, color='#e2e8f0')
ax.set_ylabel('Debt Outstanding ($ Millions)', fontsize=12, color='#e2e8f0', fontweight='500')
ax.set_title('Annual Debt Reduction Progress', 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')

# Debt reduction annotation
reduction = initial - running_total
pct = (reduction / initial) * 100
ax.annotate(f'Net Debt Reduction: ${reduction}M ({pct:.1f}%)', 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 outside plot
legend_elements = [
    Patch(facecolor='#F5276C', label='Beginning Debt'),
    Patch(facecolor='#27F5B0', label='Paydowns'),
    Patch(facecolor='#F5B027', label='Refinancing'),
    Patch(facecolor='#F54927', label='New Debt'),
    Patch(facecolor='#6CF527', label='Ending Debt')
]
ax.legend(handles=legend_elements, loc='upper left', bbox_to_anchor=(0, -0.1), 
          ncol=5, fontsize=8, facecolor='#1e293b', edgecolor='#334155', labelcolor='white')

plt.tight_layout()
plt.subplots_adjust(bottom=0.15)
plt.show()
Library

Matplotlib

Category

Financial

Did this help you?

Support PyLucid to keep it free & growing

Support