In [1]:
import numpy as np
import os
import matplotlib.pyplot as plt
%matplotlib inline

In [2]:
def federal_taxes(gross, status="single", ira=None):
if gross > 113700:
fica = (113700*0.124)/2.

elif gross <= 113700:
fica = (gross*0.124)/2.

if status == "single":
if gross > 200000:
medicare = (gross*0.038)/2.

elif gross <= 200000:
medicare = (gross*0.029)/2.

elif status == "married":
if gross > 250000:
medicare = (gross*0.038)/2.

elif gross <= 250000:
medicare = (gross*0.029)/2.

if type(ira) != type(None):
if ira == "calc":
if status == "single":
if 0.1*gross <= 5500:
ira = 0.1*gross
else:
ira = 5500.

elif status == "married":
if 0.1*gross <= 11000:
ira = 0.1*gross
else:
ira = 11000.
gross = gross - ira

if status.lower() == "single":
std_deduct = 6200
exemption = 3950
gross = gross - std_deduct - exemption

if gross <= 9075:
return 0.1 * gross + fica + medicare

elif (gross > 9075) & (gross <= 36900):
return 907.5 + 0.15 * (gross - 9075) + fica + medicare

elif (gross > 36900) & (gross <= 89350):
return 5081.25 + 0.25 * (gross - 36900) + fica + medicare

elif (gross > 89350) & (gross <= 186350):
return 18193.75 + 0.28 * (gross - 89350) + fica + medicare

elif (gross > 186350) & (gross <= 405100):
return 45353.75 + 0.33 * (gross - 186350) + fica + medicare

elif (gross > 405100) & (gross <= 406750):
return 117541.25 + 0.35 * (gross - 405100) + fica + medicare

elif gross > 406750:
return 118118.75 + 0.369 * (gross - 406750) + fica + medicare

elif status.lower() == "married":
std_deduct = 12400
exemption = 7900
gross = gross - std_deduct - exemption

if gross <= 18150:
return 0.1 * gross + fica + medicare

elif (gross > 18150) & (gross <= 73800):
return 1815 + 0.15 * (gross - 18150) + fica + medicare

elif (gross > 73800) & (gross <= 148850):
return 10162.50 + 0.25 * (gross - 73800) + fica + medicare

elif (gross > 148850) & (gross <= 226850):
return 28925 + 0.28 * (gross - 148850) + fica + medicare

elif (gross > 226850) & (gross <= 405100):
return 50765 + 0.33 * (gross - 226850) + fica + medicare

elif (gross > 405100) & (gross <= 457600):
return 109587.50 + 0.35 * (gross - 405100) + fica + medicare

elif gross > 457600:
return 127962.50 + 0.369 * (gross - 457600) + fica + medicare


In [3]:
def nystate_taxes(gross, status="single", ira=None):
if type(ira) != type(None):
if ira == "calc":
if status == "single":
if 0.1*gross <= 5500:
ira = 0.1*gross
else:
ira = 5500.

elif status == "married":
if 0.1*gross <= 11000:
ira = 0.1*gross
else:
ira = 11000.
gross = gross - ira

if status.lower() == "single":
std_deduct = 7800
gross = gross - std_deduct

if gross < 8300:
return 0.04*gross

elif (gross >= 8300) & (gross < 11450):
return 0.04*8300 + 0.045*(gross - 8300)

elif (gross >= 11450) & (gross < 13550):
return 0.04*8300 + 0.045*(11450 - 8300) + 0.0525*(gross - 11450)

elif (gross >= 13550) & (gross < 20850):
return 0.04*8300 + 0.045*(11450 - 8300) + 0.0525*(13550 - 11450) + 0.059*(gross - 13550)

elif (gross >= 20850) & (gross < 78400):
return 0.04*8300 + 0.045*(11450 - 8300) + 0.0525*(13550 - 11450) + 0.059*(20850 - 13550) + 0.0645*(gross - 20850)

elif (gross >= 78400) & (gross < 209250):
return 0.04*8300 + 0.045*(11450 - 8300) + 0.0525*(13550 - 11450) + 0.059*(20850 - 13550) + 0.0645*(78400 - 20850) + 0.0665*(gross - 78400)

elif (gross >= 209250) & (gross < 1046350):
return 0.04*8300 + 0.045*(11450 - 8300) + 0.0525*(13550 - 11450) + 0.059*(20850 - 13550) + 0.0645*(78400 - 20850) + 0.0665*(209250 - 78400) + 0.0685*(gross - 209250)

elif gross >= 1046350:
return 0.04*8300 + 0.045*(11450 - 8300) + 0.0525*(13550 - 11450) + 0.059*(20850 - 13550) + 0.0645*(78400 - 20850) + 0.0665*(209250 - 78400) + 0.0685*(1046350 - 209250) + 0.0882*(gross - 1046350)

elif status.lower() == "married":
std_deduct = 15650
gross = gross - std_deduct

if gross < 16700:
return 0.04*gross

elif (gross >= 16700) & (gross < 22950):
return 0.04*16700 + 0.045*(gross - 16700)

elif (gross >= 22950) & (gross < 27150):
return 0.04*16700 + 0.045*(22950 - 16700) + 0.0525*(gross - 22950)

elif (gross >= 27150) & (gross < 41800):
return 0.04*16700 + 0.045*(22950 - 16700) + 0.0525*(27150 - 22950) + 0.059*(gross - 27150)

elif (gross >= 41800) & (gross < 156900):
return 0.04*16700 + 0.045*(22950 - 16700) + 0.0525*(27150 - 22950) + 0.059*(41800 - 27150) + 0.0645*(gross - 41800)

elif (gross >= 156900) & (gross < 313850):
return 0.04*16700 + 0.045*(22950 - 16700) + 0.0525*(27150 - 22950) + 0.059*(41800 - 27150) + 0.0645*(156900 - 41800) + 0.0665*(gross - 156900)

elif (gross >= 313850) & (gross < 2092800):
return 0.04*16700 + 0.045*(22950 - 16700) + 0.0525*(27150 - 22950) + 0.059*(41800 - 27150) + 0.0645*(156900 - 41800) + 0.0665*(313850 - 156900) + 0.0685*(gross - 313850)

elif gross >= 2092800:
return 0.04*16700 + 0.045*(22950 - 16700) + 0.0525*(27150 - 22950) + 0.059*(41800 - 27150) + 0.0645*(156900 - 41800) + 0.0665*(313850 - 156900) + 0.0685*(2092800 - 313850) + 0.0882*(gross - 2092800)


In [4]:
def nycity_taxes(gross, status="single", ira=None):
if type(ira) != type(None):
if ira == "calc":
if status == "single":
if 0.1*gross <= 5500:
ira = 0.1*gross
else:
ira = 5500.

elif status == "married":
if 0.1*gross <= 11000:
ira = 0.1*gross
else:
ira = 11000.
gross = gross - ira

if status.lower() == "single":

if gross <= 12000:
return 0.02907*gross

elif (gross > 12000) & (gross <= 25000):
return 349 + 0.03534*(gross - 12000)

elif (gross > 25000) & (gross <= 50000):
return 808 + 0.03591*(gross - 25000)

elif (gross > 50000) & (gross <= 500000):
return 1706 + 0.03648*(gross - 50000)

elif gross > 500000:
return 18122 + 0.03876*(gross - 500000)

elif status.lower() == "married":

if gross <= 21600:
return 0.02907*gross

elif (gross > 21600) & (gross <= 45000):
return 628 + 0.03534*(gross - 21600)

elif (gross > 45000) & (gross <= 90000):
return 1455 + 0.03591*(gross - 45000)

elif (gross > 90000) & (gross <= 500000):
return 3071 + 0.03648*(gross - 90000)

elif gross > 500000:
return 18028 + 0.03876*(gross - 500000)


In [5]:
minimum = 7.25 * 40 * 50 / 1E3

salaries = np.linspace(minimum, 200., 10000)
taxes_single = np.array([federal_taxes(s*1E3, status="single") for s in salaries])/1E3
taxes_single_ira = np.array([federal_taxes(s*1E3, status="single", ira="calc") for s in salaries])/1E3
taxes_single_nys = np.array([federal_taxes(s*1E3, status="single") + nystate_taxes(s*1E3, status="single") for s in salaries])/1E3
taxes_single_nyc = np.array([federal_taxes(s*1E3, status="single") + nystate_taxes(s*1E3, status="single") + nycity_taxes(s*1E3, status="single") for s in salaries])/1E3

taxes_married = np.array([federal_taxes(s*1E3, status="married") for s in salaries])/1E3
taxes_married_ira = np.array([federal_taxes(s*1E3, status="married", ira="calc") for s in salaries])/1E3
taxes_married_nys = np.array([federal_taxes(s*1E3, status="married") + nystate_taxes(s*1E3, status="married") for s in salaries])/1E3
taxes_married_nyc = np.array([federal_taxes(s*1E3, status="married") + nystate_taxes(s*1E3, status="married") + nycity_taxes(s*1E3, status="married") for s in salaries])/1E3

In [13]:
salary = 65000.
federal_taxes(salary, status="single")

Out[13]:
14541.25
In [6]:
fig = plt.figure(figsize=(12,4))
ax = plt.subplot(133)
ax.plot(salaries, taxes_single_nyc, color="b", linestyle=":", linewidth=2)
ax.plot(salaries, taxes_married_nyc, color="r", linestyle=":", linewidth=2)
ax.set_ylim(1,79)
ax.set_xticks(np.arange(20,220,20))
ax.set_xlim(15)
ax.minorticks_on()
ax.grid()

ax = plt.subplot(132)
ax.plot(salaries, taxes_single_nys, color="b", linestyle="--")
ax.plot(salaries, taxes_married_nys, color="r", linestyle="--")
ax.set_xlabel("Total Gross Salary (x $1000)") ax.set_ylim(1,79) ax.set_xticks(np.arange(20,220,20)) ax.set_xlim(15, 195) ax.minorticks_on() ax.grid() ax = plt.subplot(131) ax.plot(salaries, taxes_single, color="b", linewidth="2") ax.plot(salaries, taxes_married, color="r", linewidth="2") ax.text(0.03,0.9,"Taxes in WA state compared to NY",transform=ax.transAxes, fontsize=14) ax.set_ylabel("Total Taxes (x$1000)")
ax.set_ylim(1,79)
ax.set_xlim(salaries[0], salaries[-1])
ax.set_xticks(np.arange(20,220,20))
ax.set_xlim(15, 195)
ax.minorticks_on()
ax.grid()

# ax.legend(("Single in WA","Single in NY","Single in NYC","Married in WA","Married in NY","Married in NYC"), loc=4)
plt.savefig("taxes_WANY.jpg")
plt.show()

In [7]:
## Taxes as fraction of salary
fig = plt.figure(figsize=(12,4))
ax = plt.subplot(133)
ax.plot(salaries, taxes_single_nyc/salaries * 100, color="b", linestyle=":")
ax.plot(salaries, taxes_married_nyc/salaries * 100, color="r", linestyle=":")
ax.set_xticks(np.arange(20,220,20))
ax.set_xlim(15, salaries[-1])
ax.set_ylim(1,39)
ax.minorticks_on()
ax.grid()

ax = plt.subplot(132)
ax.plot(salaries, taxes_single_nys/salaries * 100, color="b", linestyle="--")
ax.plot(salaries, taxes_married_nys/salaries * 100, color="r", linestyle="--")
ax.set_xticks(np.arange(20,220,20))
ax.set_xlim(15, 195)
ax.set_ylim(1,39)
ax.set_xlabel("Total Gross Salary (x $1000)") ax.minorticks_on() ax.grid() ax = plt.subplot(131) ax.plot(salaries, taxes_single/salaries * 100, color="b", linewidth="2") ax.plot(salaries, taxes_married/salaries * 100, color="r", linewidth="2") ax.set_ylabel("Total Percent of Salary (%)") ax.set_xticks(np.arange(20,220,20)) ax.set_xlim(15, 195) ax.set_ylim(1,39) ax.minorticks_on() ax.grid() # ax.legend(("Single in WA","Single in NY","Single in NYC","Married in WA","Married in NY","Married in NYC"), loc=4) plt.savefig("taxes_WANY_prct.jpg") plt.show()  In [8]: diff = taxes_single - taxes_married diff_prct = (taxes_single/salaries * 100) - (taxes_married/salaries * 100)  In [9]: plt.figure(figsize=(12,6)) plt.subplot(121) plt.plot(salaries, diff) plt.subplot(122) plt.plot(salaries, diff_prct) plt.show()  In [10]: salaries[np.where(diff_prct == max(diff_prct))]  Out[10]: array([ 94.08745875]) In [11]: print federal_taxes(1081.80*24)  3904.4148  In [12]: 1081.80*24  Out[12]: 25963.199999999997 In [13]: federal_taxes(200000, status="single")  Out[13]: 56458.15 In [14]: print federal_taxes(50000), nystate_taxes(50000), nycity_taxes(50000), federal_taxes(50000) + nystate_taxes(50000) + nycity_taxes(50000)  9643.75 2391.775 1705.75 13741.275  ### The Financial Life of Mr. Johnny Averageface¶ Salary: \$50K

Annual Expenses

• Rent: \$15,600 (\$1,300 per month)
• Food: \$7,500 (\$150 per week)
• Credit Card Payment: \$3,750 (\$312.50 per month)
• Student Loan Payment: \$4,143 (\$345.24 per month)
• Funtimes: \$3,600 (\$300 per month)

Sources:

• http://www.nerdwallet.com/blog/credit-card-data/average-credit-card-debt-household/
• http://www.finaid.org/calculators/loanpayments.phtml
In [15]:
salary = 50.*1E3

rent = 1300*12
food = 150*50

taxes = federal_taxes(salary)
taxes_nys = federal_taxes(salary) + nystate_taxes(salary)
taxes_nyc = federal_taxes(salary) + nystate_taxes(salary) + nycity_taxes(salary)

expenses_1 = np.array([taxes, rent, food, 3750, 4143, 3600])/1.E3
expenses_2 = np.array([taxes_nys, rent, food, 3750, 4143, 3600])/1.E3
expenses_3 = np.array([taxes_nyc, rent, food, 3750, 4143, 3600])/1.E3

w = 0.75
inds = [1. + w/3]*len(expenses_1)

plt.bar(w/3, salary/1E3, width=w, color="g")

plt.bar(inds[0], expenses_1[-1], width=w, color="b")
plt.bar(inds[0]+1, expenses_2[-1], width=w, color="b")
plt.bar(inds[0]+2, expenses_3[-1], width=w, color="b")

colors = ["blue","orange","purple","gray","yellow","r"]

for ii in range(1,len(inds)):
yind = -(ii+1)
plt.bar(inds[ii], expenses_1[yind], bottom=sum(expenses_1[yind+1:]), width=w, color=colors[ii])
plt.bar(inds[ii]+1, expenses_2[yind], bottom=sum(expenses_2[yind+1:]), width=w, color=colors[ii])
plt.bar(inds[ii]+2, expenses_3[yind], bottom=sum(expenses_3[yind+1:]), width=w, color=colors[ii])

# plt.legend(["A", "B", "C", "D", "E", "F"])

ylines = np.arange(0,100+10,10)
for ii in range(10):
plt.plot([0,100],[ylines[ii],ylines[ii]],color='k',linestyle=":",alpha=0.5)

plt.xlim(0,4.3)
plt.ylim(0,salary/1E3 + 10)
plt.minorticks_on()
plt.ylabel("Total Amount (x \$1000)")

plt.xticks([w/3+0.35, inds[0]+0.35, inds[0]+1+0.35, inds[0]+2+0.35],["Gross\nIncome", "WA", "NY State", "NY City"])
plt.savefig("income_expenses_compare.png")
plt.show()

In [16]:
# print federal_taxes(80000, status="married") + nystate_taxes(80000, status="married") + nycity_taxes(80000, status="married")
print federal_taxes(50000, status="single") + nystate_taxes(50000, status="single") + nycity_taxes(50000, status="single")

13741.275

In [18]:
federal_taxes((1081*2 + 1600)*12)/12., 1081*2 + 1600

Out[18]:
197.8166666666667
In [19]:
1600-197.82

Out[19]:
1402.18
In [5]:
federal_taxes(30928.90 + (400.04*5 + 388.10), status="single")

Out[5]:
5570.0958
In [7]:
federal_taxes(30928.90, status="single", ira=1200)

Out[7]:
4849.14585
In [ ]: