New York City budget explanation including fiscal year 2027

1 view
Skip to first unread message

Ralph Yozzo

unread,
Mar 3, 2026, 5:46:39 AM (yesterday) Mar 3
to tax-payers-...@googlegroups.com
Python
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# Data for NYC Expense Budget Progression (Billions of Dollars)
data = {
    'Fiscal Year': ['FY 2024', 'FY 2025', 'FY 2026', 'FY 2027'],
    'Financial Plan': [106.69, 111.63, 115.07, 127.00],
    'Adopted Budget': [107.12, 112.40, 115.91, 0], # 0 or None for FY27
    'Modified Budget': [114.10, 115.00, 118.23, 0] # 0 or None for FY27
}

df = pd.DataFrame(data)

# Create the plot
fig, ax = plt.subplots(figsize=(12, 7))

# Set position of bars on x axis
barWidth = 0.25
r1 = np.arange(len(df))
r2 = [x + barWidth for x in r1]
r3 = [x + barWidth for x in r2]

# Make the plot
ax.bar(r1, df['Financial Plan'], color='#3498db', width=barWidth, edgecolor='white', label='Financial Plan (Prelim/Exec)')
# Plot Adopted and Modified only where values > 0
ax.bar(r2, df['Adopted Budget'], color='#2ecc71', width=barWidth, edgecolor='white', label='Adopted Budget')
ax.bar(r3, df['Modified Budget'], color='#e67e22', width=barWidth, edgecolor='white', label='Modified Budget')

# Add labels and title
ax.set_xlabel('Fiscal Year', fontweight='bold', fontsize=12)
ax.set_ylabel('Amount ($ Billions)', fontweight='bold', fontsize=12)
ax.set_title('NYC Expense Budget: Progression through FY 2027', fontsize=14, fontweight='bold')
ax.set_xticks([r + barWidth for r in range(len(df))])
ax.set_xticklabels(df['Fiscal Year'])

# Add text labels on bars
for i, val in enumerate(df['Financial Plan']):
    ax.text(r1[i], val + 1, f'${val:.1f}B', ha='center', va='bottom', fontsize=9, fontweight='bold')

for i, val in enumerate(df['Adopted Budget']):
    if val > 0:
        ax.text(r2[i], val + 1, f'${val:.1f}B', ha='center', va='bottom', fontsize=9, fontweight='bold')
    elif df['Fiscal Year'][i] == 'FY 2027':
        ax.text(r2[i], 5, 'TBD', ha='center', va='bottom', fontsize=9, color='gray', style='italic')

for i, val in enumerate(df['Modified Budget']):
    if val > 0:
        ax.text(r3[i], val + 1, f'${val:.1f}B', ha='center', va='bottom', fontsize=9, fontweight='bold')
    elif df['Fiscal Year'][i] == 'FY 2027':
        ax.text(r3[i], 5, 'TBD', ha='center', va='bottom', fontsize=9, color='gray', style='italic')

ax.legend(loc='upper left')
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.ylim(0, 145) # Give space for labels
plt.tight_layout()

# Save the plot
plt.savefig('nyc_budget_2027_progression.png')

# Save updated data to CSV
df_to_save = df.copy()
df_to_save.replace(0, "TBD", inplace=True)
df_to_save.to_csv('nyc_budget_totals_through_2027.csv', index=False)

print("Plot saved as nyc_budget_2027_progression.png")
print(df_to_save)

Code output
Plot saved as nyc_budget_2027_progression.png
  Fiscal Year  Financial Plan Adopted Budget Modified Budget
0     FY 2024          106.69         107.12           114.1
1     FY 2025          111.63          112.4           115.0
2     FY 2026          115.07         115.91          118.23
3     FY 2027          127.00            TBD             TBD

CSV icon
nyc_budget...rough_2027
CSV

The updated graph and chart now include Fiscal Year 2027, showing how the financial plan amount starts the cycle and sets the stage for the years to follow.

As of March 2026, the city has released the FY 2027 Preliminary Budget, which serves as the first "Financial Plan" entry for the upcoming cycle.

NYC Expense Budget Progression through FY 2027 ($ Billions)

Fiscal YearFinancial PlanAdopted BudgetModified Budget
FY 2024$\$106.7\text{B}$$\$107.1\text{B}$$\$114.1\text{B}$
FY 2025$\$111.6\text{B}$$\$112.4\text{B}$$\$115.0\text{B}$
FY 2026$\$115.1\text{B}$$\$115.9\text{B}$$\$118.2\text{B}$
FY 2027 (Proposed)$\$127.0\text{B}$TBD (June 2026)TBD (Nov 2026)

Analysis of the FY 2027 Interaction

  • A Historic "First Step": The FY 2027 Financial Plan amount of $\$127$ billion is significantly higher than previous years. This is largely due to the new administration's "transparent budgeting" approach, which seeks to include "chronic underbudgeting" items (like rental assistance and shelter costs) in the initial plan rather than waiting for mid-year modifications.

  • The Path to Adoption: This $\$127\text{B}$ figure is the "opening bid" for FY 2027. Between now and June 2026, it will "interact" with the City Council through public hearings. Historical trends suggest that the Adopted Budget will likely be slightly higher than this initial plan as the Council negotiates for additional service restorations.

  • Future Modifications: Following the trend of FY 2024–2026, the Modified Budget for FY 2027 (which won't be finalized until 2027) will likely adjust even higher as the city accounts for actual tax receipts and unanticipated state or federal aid.

This progression shows that while the Financial Plan provides the initial framework, the budget is a dynamic negotiation that typically grows as it moves from the plan to adoption and finally to modification.


Reply all
Reply to author
Forward
0 new messages