Waterfall Chart

Cost Reduction Initiative Impact

Dark-themed waterfall chart showing the impact of various cost reduction initiatives on total operating costs.

Output
Cost Reduction Initiative Impact
Python
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Patch

# Cost reduction initiatives (in millions)
categories = ['Baseline\nCosts', 'Automation', 'Outsourcing', 'Renegotiated\nContracts', 
              'Workforce\nOptimization', 'Energy\nEfficiency', 'New\nInvestments', 'Target\nCosts']
values = [0, -25, -18, -12, -35, -8, 15, 0]

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

for i, (cat, val) in enumerate(zip(categories, values)):
    if 'Baseline' in cat:
        bottoms.append(0)
        heights.append(initial)
        colors.append('#F5276C')
    elif 'Target' in cat:
        bottoms.append(0)
        heights.append(running_total)
        colors.append('#6CF527')
    elif val < 0:
        bottoms.append(running_total + val)
        heights.append(abs(val))
        colors.append('#27F5B0')
        running_total += val
    else:
        bottoms.append(running_total)
        heights.append(val)
        colors.append('#F5B027')
        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 'Baseline' in categories[i] or 'Target' 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"-${abs(val)}M" if val < 0 else f"+${val}M"
        ax.text(bar.get_x() + bar.get_width()/2, y_pos, label, 
                ha='center', va='center', fontsize=10, fontweight='bold', color='white' if height > 10 else '#0a0a0f')

# Connect bars
for i in range(len(x) - 1):
    if i == 0:
        y = initial
    else:
        y = bottoms[i]
    ax.plot([x[i] + 0.35, x[i+1] - 0.35], [y, y], 
            color='#475569', linestyle='--', linewidth=1.5, alpha=0.7)

# 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('Annual Costs ($ Millions)', fontsize=12, color='#e2e8f0', fontweight='500')
ax.set_title('Cost Reduction Initiative Impact Analysis', 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')

# Savings annotation
savings = initial - running_total
pct = (savings / initial) * 100
ax.annotate(f'Total Savings: ${savings}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='Baseline Costs'),
    Patch(facecolor='#27F5B0', label='Cost Savings'),
    Patch(facecolor='#F5B027', label='New Investments'),
    Patch(facecolor='#6CF527', label='Target Costs')
]
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

Did this help you?

Support PyLucid to keep it free & growing

Support