Waterfall Chart
Real Estate Investment Returns
Property investment waterfall showing rental income, expenses, and net returns.
Output
Python
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Patch
categories = ['Gross\nRental Income', 'Vacancy\nLoss', 'Property\nMgmt', 'Maintenance',
'Property\nTaxes', 'Insurance', 'Mortgage\nPayment', 'Net\nCash Flow']
values = [0, -12, -18, -15, -24, -8, -85, 0]
initial = 240
running_total = initial
bottoms, heights, colors = [], [], []
for i, (cat, val) in enumerate(zip(categories, values)):
if 'Gross' in cat:
bottoms.append(0)
heights.append(initial)
colors.append('#27D3F5')
elif 'Net' in cat:
bottoms.append(0)
heights.append(running_total)
colors.append('#6CF527' if running_total > 0 else '#F5276C')
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 'Gross' in categories[i] or 'Net' in categories[i]:
label = f"${height}K"
ax.text(bar.get_x() + bar.get_width()/2, y_pos, label, ha='center', va='center',
fontsize=11, fontweight='bold', color='#0a0a0f' if height > 100 else 'white')
else:
label = f"${abs(val)}K"
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]
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, initial * 1.1)
ax.set_xticks(x)
ax.set_xticklabels(categories, fontsize=9, color='#e2e8f0')
ax.set_ylabel('Annual Amount ($ Thousands)', fontsize=12, color='#e2e8f0', fontweight='500')
ax.set_title('Rental Property Cash Flow 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')
# Cap rate calculation (assuming $2M property value)
noi = running_total + 85 # Add back mortgage for NOI
cap_rate = (noi / 2000) * 100
cash_on_cash = (running_total / 400) * 100 # Assuming $400K down payment
ax.annotate(f'Cap Rate: {cap_rate:.1f}% | Cash-on-Cash: {cash_on_cash:.1f}%', 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_elements = [Patch(facecolor='#27D3F5', label='Gross Income'), Patch(facecolor='#F5276C', label='Expenses'),
Patch(facecolor='#6CF527', label='Net Cash Flow')]
ax.legend(handles=legend_elements, loc='upper left', bbox_to_anchor=(0, -0.1), ncol=3, 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
☕