Waterfall Chart
Effective Tax Rate Reconciliation
Tax waterfall bridging statutory rate to effective tax rate through adjustments.
Output
Python
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Patch
# Tax rate reconciliation (in percentage points)
categories = ['Statutory\nRate', 'State\nTaxes', 'Foreign\nRate Diff', 'R&D\nCredits',
'Stock Comp\nDeduction', 'GILTI\nInclusion', 'Valuation\nAllowance', 'Effective\nRate']
values = [0, 3.2, -2.8, -4.5, -2.1, 1.8, 0.9, 0]
# Calculate running total
initial = 21.0
running_total = initial
bottoms = []
heights = []
colors = []
for i, (cat, val) in enumerate(zip(categories, values)):
if 'Statutory' in cat:
bottoms.append(0)
heights.append(initial)
colors.append('#4927F5')
elif 'Effective' in cat:
bottoms.append(0)
heights.append(running_total)
colors.append('#6CF527' if running_total < initial else '#F5B027')
elif val > 0:
bottoms.append(running_total)
heights.append(val)
colors.append('#F5276C')
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 'Statutory' in categories[i]:
label = f"{height:.1f}%"
ax.text(bar.get_x() + bar.get_width()/2, y_pos, label,
ha='center', va='center', fontsize=11, fontweight='bold', color='white')
elif 'Effective' in categories[i]:
label = f"{height:.1f}%"
ax.text(bar.get_x() + bar.get_width()/2, y_pos, label,
ha='center', va='center', fontsize=11, fontweight='bold', color='#0a0a0f')
else:
label = f"+{val:.1f}%" if val > 0 else f"{val:.1f}%"
ax.text(bar.get_x() + bar.get_width()/2, y_pos, label,
ha='center', va='center', fontsize=10, fontweight='bold', color='white')
# Connect bars
for i in range(len(x) - 1):
if i == 0:
y = initial
else:
y = 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)
# Styling
ax.set_xlim(-0.6, len(categories) - 0.4)
ax.set_ylim(0, max(bottoms[i] + heights[i] for i in range(len(heights))) * 1.2)
ax.set_xticks(x)
ax.set_xticklabels(categories, fontsize=9, color='#e2e8f0')
ax.set_ylabel('Tax Rate (%)', fontsize=12, color='#e2e8f0', fontweight='500')
ax.set_title('Statutory to Effective Tax Rate Reconciliation', 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')
# Tax savings annotation
savings = initial - running_total
pretax_income = 850
tax_saved = pretax_income * (savings / 100)
ax.annotate(f'Tax Savings: ${tax_saved:.0f}M ({savings:.1f} pp reduction)', xy=(0.98, 0.95), xycoords='axes fraction',
fontsize=10, 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='#4927F5', label='Statutory Rate'),
Patch(facecolor='#F5276C', label='Rate Increases'),
Patch(facecolor='#27F5B0', label='Rate Reductions'),
Patch(facecolor='#6CF527', label='Effective Rate')
]
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
☕