A simple interest calculation is known to be P (1 + rt), where P is the principal amount, r is the interest rate, and t is the term,
from decimal import Decimal
import matplotlib.pyplot as plt
colors = [
(31, 119, 180), (174, 199, 232),(255,128,0), (255, 15, 14),
(44, 160, 44), (152, 223, 138),(214, 39, 40), (255,173, 61),
(148, 103, 189),(197, 176, 213),(140, 86, 75), (196, 156, 148),
(227, 119, 194),(247, 182, 210),(127, 127, 127),(199, 199, 199),
(188, 189, 34), (219, 219, 141),(23, 190, 207), (158, 218, 229)
]
#Scale the RGB values to the [0,1] range, which is the format matplotlib accepts
for i in range(len(colors)):
r,g,b = colors[i]
colors[i] = (r/255., g/255., b/255.)
def printHeaders(term, extra):
# Print headers
print("-----------------------------------------------------------------------------\n")
print("\nExtra-Payment: $" + str(extra) + " Term:" + str(int(term)) +" years")
print('Pmt no'.rjust(6), ' ', ' Beg. bal.'.ljust(13), ' ', 'Payment'.ljust(9), ' ',\
'Principal'.ljust(9), ' ', 'Interest'.ljust(9), ' ', 'End. bal.'.ljust(13)
)
print(''.rjust(9, '-'), ' ', ''.ljust(9, '-'), ' ', ''.rjust(9, '-'), ' ',\
''.ljust(13, '-'), ' '
)
def pmt(principal, rate, term):
#Monthly payment formula
ratePerTwelve = rate / (12*100.0) #the monthly interest rate
result = principal * ( ratePerTwelve / ( 1-(1+ratePerTwelve)**(-term) ) )
#Convert to decimal and round off to two decimal places.
result = Decimal(result)
result = round(result, 2)
return result
def amortization_table(principal, rate, term, extraPayment, printData=False):
#amortization_table(350000, 5, 360, extraPayment, True)
xarr = [] ###############
begarr = []##############
original_loan = principal
money_saved = 0
total_payment=0
payment = float(pmt(principal, rate, term))
begBal = principal
#Print data
num = 1
endBal = 1
if printData == True:
printHeaders(term/12, extraPayment)
#term<=360
while( num<term+1 ) and ( endBal>0 ):
interest = round( begBal * (rate/(12*100.0)), 2 ) # P * r
applied = extraPayment + round( payment-interest, 2 ) #extraPayment + pmt - P*r
# P - ( extraPayment + pmt - P*r ) = P(1+r) - ( pmt +extraPayment )
endBal = round( begBal - applied, 2 )
# (num-1)%12 for printing per year(per 12 months)
# endBal<applied+extraPayment # endingBalance< the rest after paying off interest + extraPayment
if (num-1)%12 == 0 or (endBal<applied+extraPayment): #??????????????endBal<payment+extraPayment
begarr.append(begBal)###############
xarr.append(num/12)#################
######################
if (printData == True) and ( endBal>0 ):
print('{0:3d}'.format(num).center(6), ' ',\
'{0:,.2f}'.format(begBal).rjust(13), ' ',\
'{0:,.2f}'.format(payment).rjust(9), ' ',\
'{0:,.2f}'.format(applied).rjust(9), ' ',\
'{0:,.2f}'.format(interest).rjust(9), ' ',\
'{0:,.2f}'.format(endBal).rjust(13)
)
total_payment += applied+extraPayment #??????????????payment+extraPayment
num+=1
begBal = endBal
if extraPayment >0:
money_saved = abs(original_loan - total_payment) #?????????????money_saved = payment*term-(total_payment)
print( '\nTotal Payment:','{0:,.2f}'.format(total_payment).rjust(13), \
' Money Saved:','{0:,.2f}'.format(money_saved).rjust(13)
)
#begarr.append(begBal) and xarr.append(num/12)
return xarr, begarr, '{0:,.2f}'.format(money_saved)
plt.figure(figsize=(18,14))
i=0
markers = ['o','s','D','^','v','*','p','s','D','o','s','D','^','v','*','p','s','D']
markersize=[8 , 8, 8,12, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,8,8,8,8,8,8]
for extra in range(100, 1700, 100):
xv, bv, saved = amortization_table(350000,5,360,extra, True)
if extra ==0:
plt.plot(xv,bv,color=colors[i],lw=2.2, label="Principal only", \
marker=markers[i], markersize=markersize[i])
else:
plt.plot(xv,bv,color=colors[i],lw=2.2, label="Principal plus\$" + str(extra) + str("/month, Save:\$")+saved,\
marker=markers[i], markersize=markersize[i])
i+=1
plt.grid(True)
plt.xlabel("Years", fontsize=18)
plt.ylabel("Mortgage Balance", fontsize=18)
plt.title("Mortgage Loan For $350,000 With Additional Payment Chart", fontsize=20)
plt.legend()
plt.show()
import matplotlib.pyplot as plt
# set the saving value from previous example
yvals1 = [101000,111000,121000,131000,138000,143000,148000,153000,158000]
yvals2 = [130000,142000,155000,160000,170000,180000,190000,194000,200000]
yvals3 = [125000,139000,157000,171000,183000,194000,205000,212000,220000]
xvals = [500,600,700, 800, 900,1000,1100,1200,1300]
#initialize bubbles that will be scaled
bubble1 = []
bubble2 = []
bubble3 = []
# scale it on something that can be displayed
# it should be scaled to 1000, but display will be too big
# so we choose to scale by 5% (divide these by 20 again to relate to real values)
for i in range(0,9):
bubble1.append(yvals1[i]/20)
bubble2.append(yvals2[i]/20)
bubble3.append(yvals3[i]/20)
# plot yvalues with scaled by bubble sizes
# If bubbles are not scaled, they don't fit well
fig, ax = plt.subplots(figsize=(10,12))
plt1 = ax.scatter(xvals,yvals1, c='#d82730', s=bubble1, alpha=0.5)
plt2 = ax.scatter(xvals,yvals2, c='#2077b4', s=bubble2, alpha=0.5)
plt3 = ax.scatter(xvals,yvals3, c='#ff8010', s=bubble3, alpha=0.5)
# Set the labels and title
ax.set_xlabel('Extra Dollar Amount', fontsize=16)
ax.set_ylabel('Savings', fontsize=16)
ax.set_title('Mortgage Savings (Paying Extra Every Month)',fontsize=20)
# Set x and y limits
ax.set_xlim(400,1450)
ax.set_ylim(90000,230000)
ax.grid(True)
ax.legend((plt1, plt2, plt3), ('$250,000 Loan', '$350,000 Loan', '$450,000 Loan'), scatterpoints=1, loc='upper left', markerscale=0.17, fontsize=10, ncol=1)
fig.tight_layout()
plt.show()