import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
# supply curve equation
y = 0.5*0.5 + 1
y
1.25
# creating supply curve
df_housing_supply = pd.DataFrame(np.array([[0,1], [4, 3]]),
columns=['Quantity', 'Price'])
df_housing_supply
Quantity | Price | |
---|---|---|
0 | 0 | 1 |
1 | 4 | 3 |
# creating supply curve decrease
df_housing_supply_decrease = pd.DataFrame(np.array([[0,1.75], [3.75,3.625]]),
columns=['Quantity', 'Price'])
df_housing_supply_decrease
#3 = 3.75*0.5 +1.75
Quantity | Price | |
---|---|---|
0 | 0.00 | 1.750 |
1 | 3.75 | 3.625 |
# demand curve equation
y = -0.5*3.1 + 3
y
1.45
#creating demand curve
df_housing_demand = pd.DataFrame(np.array([[0,3], [3.6,1.2]]),
columns=['Quantity', 'Price'])
df_housing_demand
Quantity | Price | |
---|---|---|
0 | 0.0 | 3.0 |
1 | 3.6 | 1.2 |
# demand curve increase equation
y = -0.5*4 + 4
y
2.0
# creating demand curve increase
df_housing_demand_increase = pd.DataFrame(np.array([[0.4,3.8], [4, 2]]),
columns=['Quantity', 'Price'])
df_housing_demand_increase
Quantity | Price | |
---|---|---|
0 | 0.4 | 3.8 |
1 | 4.0 | 2.0 |
# data for plumb lines of first equilibrium
dotted_one = pd.DataFrame(np.array([[0,2], [2,2], [2,0]]),
columns=['xx', 'yy'])
dotted_one
xx | yy | |
---|---|---|
0 | 0 | 2 |
1 | 2 | 2 |
2 | 2 | 0 |
# data for plumb lines of second equilibrium
dotted_two = pd.DataFrame(np.array([[0,2.5], [3,2.5], [3,0]]),
columns=['xx', 'yy'])
dotted_two
xx | yy | |
---|---|---|
0 | 0.0 | 2.5 |
1 | 3.0 | 2.5 |
2 | 3.0 | 0.0 |
# set figure size and style
fig = plt.figure(figsize=(9,6))
sns.set_style('darkgrid')
# plot axes
plt.axvline(ymin=0.065, ymax=0.93, color='black')
plt.axhline(xmin=0.065, xmax=0.93, color='black')
# plot supply and demand curves
plt.plot('Quantity', 'Price', data=df_housing_supply, label='Supply',
color='tomato', zorder=1, lw=2)
plt.plot('Quantity', 'Price', data=df_housing_demand, label='Demand',
color='lightseagreen', zorder=1, lw=2)
plt.plot('Quantity', 'Price', data=df_housing_demand_increase,
label='Demand increase', color='lightseagreen', linestyle='dashed',
zorder=1, lw=2)
# plot equilibria and plumb lines
plt.scatter(x=2, y=2, zorder=2, color='grey', s=60, label='Old equilibrium')
plt.plot('xx', 'yy', data=dotted_one, linestyle='dotted', color='grey', label='', lw=3)
plt.scatter(x=3, y=2.5, zorder=2, color='royalblue', s=60, label='New equilibrium')
plt.plot('xx', 'yy', data=dotted_two, linestyle='dotted', color='royalblue', label='', lw=3)
# plot arrows
plt.arrow(0.75, 2.625, 0.18, 0.4, width=0.015, head_width=0.13, head_length=0.13, fc='k', ec='k')
plt.arrow(3.1, 1.45, 0.18, 0.4, width=0.015, head_width=0.13, head_length=0.13, fc='k', ec='k')
# label axes
plt.xlabel('Quantity', fontsize=16)
plt.ylabel('Price', fontsize=16)
# set axes limits
plt.xlim([-0.3, 4.3])
plt.ylim([-0.3, 4.3])
# title and legend
plt.title('St. Ives Housing Market', fontsize=20, pad=30)
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, prop={'size': 13})
plt.tight_layout()
fig.savefig('st-ives-housing-market.png', dpi=180);
# demand curve increase equation
#y = -0.5*x + 4
# supply curve decrease equation
#y = 0.5*x + 1.75
#5.75/2
(2.875 - 1.75)/0.5
2.25
# data for plumb lines of third equilibrium
dotted_three = pd.DataFrame(np.array([[0,2.875], [2.25,2.875], [2.25,0]]),
columns=['xx', 'yy'])
dotted_three
xx | yy | |
---|---|---|
0 | 0.00 | 2.875 |
1 | 2.25 | 2.875 |
2 | 2.25 | 0.000 |
# set figure size and style
fig = plt.figure(figsize=(12,8))
sns.set_style('darkgrid')
# ----- FIRST SUBPLOT ------
plt.subplot(1, 2, 1)
# plot axes
plt.axvline(ymin=0.065, ymax=0.93, color='black')
plt.axhline(xmin=0.065, xmax=0.93, color='black')
# plot supply and demand curves
plt.plot('Quantity', 'Price', data=df_housing_supply, label='Supply #1',
color='tomato', zorder=1, lw=2)
plt.plot('Quantity', 'Price', data=df_housing_demand, label='Demand #1',
color='lightseagreen', zorder=1, lw=2)
plt.plot('Quantity', 'Price', data=df_housing_demand_increase,
label='Demand #2 (increase)', color='lightseagreen', linestyle='dashed',
zorder=1, lw=2)
# plot equilibria and plumb lines
plt.scatter(x=2, y=2, zorder=2, color='grey', s=60, label='Old equilibrium')
plt.plot('xx', 'yy', data=dotted_one, linestyle='dotted', color='grey', label='', lw=3)
plt.scatter(x=3, y=2.5, zorder=2, color='royalblue', s=60, label='New equilibrium')
plt.plot('xx', 'yy', data=dotted_two, linestyle='dotted', color='royalblue', label='', lw=3)
# plot arrows
plt.arrow(0.75, 2.625, 0.18, 0.4, width=0.015, head_width=0.13, head_length=0.13, fc='k', ec='k')
plt.arrow(3.1, 1.45, 0.18, 0.4, width=0.015, head_width=0.13, head_length=0.13, fc='k', ec='k')
# label axes
plt.xlabel('Quantity', fontsize=16)
plt.ylabel('Price', fontsize=16)
# set axes limits
plt.xlim([-0.3, 4.3])
plt.ylim([-0.3, 4.3])
# title and legend
plt.title('Situation for Locals: Increase in Demand', fontsize=18, pad=20)
plt.legend(bbox_to_anchor=(0.5, -0.4), loc=8, prop={'size': 13}, ncol=2)
plt.tight_layout()
# ----- SECOND SUBPLOT -----
plt.subplot(1, 2, 2)
# plot axes
plt.axvline(ymin=0.065, ymax=0.93, color='black')
plt.axhline(xmin=0.065, xmax=0.93, color='black')
# plot supply and demand curves
plt.plot('Quantity', 'Price', data=df_housing_supply, label='Supply #1',
color='tomato', zorder=1, lw=2)
plt.plot('Quantity', 'Price', data=df_housing_supply_decrease,
label='Supply #2 (decrease)', color='tomato', zorder=1, linestyle='dashed', lw=2)
plt.plot('Quantity', 'Price', data=df_housing_demand_increase,
label='Demand #2', color='lightseagreen', linestyle='dashed',
zorder=1, lw=2)
# plot equilibria and plumb lines
plt.scatter(x=3, y=2.5, zorder=2, color='grey', s=60, label='Old equilibria')
plt.plot('xx', 'yy', data=dotted_two, linestyle='dotted', color='grey', label='', lw=3)
plt.scatter(x=2.25, y=2.875, zorder=2, color='royalblue', s=60, label='New equilibrium')
plt.plot('xx', 'yy', data=dotted_three, linestyle='dotted', color='royalblue', label='', lw=3)
# plot arrows
plt.arrow(0.5, 1.25, -0.15, 0.3, width=0.015, head_width=0.13, head_length=0.13, fc='k', ec='k')
plt.arrow(3.5, 2.75, -0.15, 0.3, width=0.015, head_width=0.13, head_length=0.13, fc='k', ec='k')
# axes labels
plt.xlabel('Quantity', fontsize=16)
plt.ylabel('Price', fontsize=16)
# axes limits
plt.xlim([-0.3, 4.3])
plt.ylim([-0.3, 4.3])
# title and legend
plt.title('Response by Locals: Decrease in Supply', fontsize=18, pad=20)
plt.legend(bbox_to_anchor=(0.5, -0.4), loc=8, prop={'size': 13}, ncol=2)
plt.tight_layout()
# ----- End of second subplot -----
# figure title
plt.subplots_adjust(top=0.84)
fig.suptitle('St. Ives Housing Market: Pre-Legislation', fontsize=20)
fig.savefig('st-ives-housing-market-pre-legislation.png', dpi=180);
# creating second demand curve increase
df_housing_demand_increase2 = pd.DataFrame(np.array([[0.5,4], [4,2.25]]),
columns=['Quantity', 'Price'])
df_housing_demand_increase2
Quantity | Price | |
---|---|---|
0 | 0.5 | 4.00 |
1 | 4.0 | 2.25 |
# demand curve increase2 equation
#y = -0.5*x + 4
# supply curve decrease equation
#y = 0.5*x + 1.75
(4.5+1.75)/2
3.125
# data for plumb lines of forth equilibrium
dotted_four = pd.DataFrame(np.array([[0,3], [2.5,3], [2.5,0]]),
columns=['xx', 'yy'])
dotted_four
xx | yy | |
---|---|---|
0 | 0.0 | 3.0 |
1 | 2.5 | 3.0 |
2 | 2.5 | 0.0 |
# set figure size and style
fig = plt.figure(figsize=(12,8))
sns.set_style('darkgrid')
# ----- FIRST SUBPLOT -----
plt.subplot(1, 2, 1)
# plot axes
plt.axvline(ymin=0.065, ymax=0.93, color='black')
plt.axhline(xmin=0.065, xmax=0.93, color='black')
# plot supply and demand curves
plt.plot('Quantity', 'Price', data=df_housing_supply, label='Supply #1',
color='tomato', zorder=1, lw=2)
plt.plot('Quantity', 'Price', data=df_housing_supply_decrease,
label='Supply #2 (decrease)', color='tomato', zorder=1, linestyle='dashed', lw=2)
plt.plot('Quantity', 'Price', data=df_housing_demand_increase,
label='Demand #2', color='lightseagreen', linestyle='dashed',
zorder=1, lw=2)
# plot equilibria and plumb lines
plt.scatter(x=3, y=2.5, zorder=2, color='grey', s=60, label='Old equilibria')
plt.plot('xx', 'yy', data=dotted_two, linestyle='dotted', color='grey', label='', lw=3)
plt.scatter(x=2.25, y=2.875, zorder=2, color='royalblue', s=60, label='New equilibrium')
plt.plot('xx', 'yy', data=dotted_three, linestyle='dotted', color='royalblue', label='', lw=3)
# plot arrows
plt.arrow(0.5, 1.25, -0.15, 0.3, width=0.015, head_width=0.13, head_length=0.13, fc='k', ec='k')
plt.arrow(3.5, 2.75, -0.15, 0.3, width=0.015, head_width=0.13, head_length=0.13, fc='k', ec='k')
# axes labels
plt.xlabel('Quantity', fontsize=16)
plt.ylabel('Price', fontsize=16)
# axes limits
plt.xlim([-0.3, 4.3])
plt.ylim([-0.3, 4.3])
# title and legend
plt.title('Situation for Non-residents: Decrease in Supply', fontsize=16, pad=20)
plt.legend(bbox_to_anchor=(0.5, -0.4), loc=8, prop={'size': 13}, ncol=2)
plt.tight_layout()
# ----- SECOND SUBPLOT -----
plt.subplot(1, 2, 2)
# plot axes
plt.axvline(ymin=0.065, ymax=0.93, color='black')
plt.axhline(xmin=0.065, xmax=0.93, color='black')
# plot supply and demand curves
plt.plot('Quantity', 'Price', data=df_housing_supply_decrease,
label='Supply #2', color='tomato', zorder=1, linestyle='dashed', lw=2)
plt.plot('Quantity', 'Price', data=df_housing_demand_increase,
label='Demand #2', color='lightseagreen', linestyle='dashed',
zorder=1, lw=2)
plt.plot('Quantity', 'Price', data=df_housing_demand_increase2,
label='Demand #3 (increase)', color='lightseagreen', zorder=1,
linestyle='dashdot', lw=2)
# plot equilibria and plumb lines
plt.scatter(x=3, y=2.5, zorder=2, color='grey', s=60)
plt.scatter(x=2.25, y=2.875, zorder=2, color='grey', s=60, label='Old equilibria')
plt.plot('xx', 'yy', data=dotted_three, linestyle='dotted', color='grey', label='', lw=3)
plt.scatter(x=2.5, y=3, zorder=2, color='royalblue', s=60, label='New equilibrium')
plt.plot('xx', 'yy', data=dotted_four, linestyle='dotted', color='royalblue', label='', lw=3)
# plot arrows
plt.arrow(0.5, 3.75, 0.03, 0.07, width=0.015, head_width=0.13, head_length=0.13, fc='k', ec='k')
plt.arrow(3.5, 2.25, 0.03, 0.07, width=0.015, head_width=0.13, head_length=0.13, fc='k', ec='k')
# axes labels
plt.xlabel('Quantity', fontsize=16)
plt.ylabel('Price', fontsize=16)
# axes limits
plt.xlim([-0.3, 4.3])
plt.ylim([-0.3, 4.3])
# title and legend
plt.title('Response by All: Increase in Demand', fontsize=18, pad=20)
plt.legend(bbox_to_anchor=(0.5, -0.4), loc=8, prop={'size': 13}, ncol=2)
plt.tight_layout()
# ----- End of second subplot -----
# figure title
plt.subplots_adjust(top=0.83)
fig.suptitle('St. Ives Housing Market: Post-Legislation', fontsize=20)
fig.savefig('st-ives-housing-market-post-legislation.png', dpi=180);
# real data on St. Ives, from Financial Times
# numbers rounded to nearest thousand British pound
# https://www.ft.com/content/6abb85e8-c349-11e9-ae6e-a26d1d0455f4
df_dots_2016 = pd.DataFrame(np.array([[310,0], [310,323], [0,323]]),
columns=['xx', 'yy'])
df_dots_2018 = pd.DataFrame(np.array([[270,0], [270,352], [0,352]]),
columns=['xx', 'yy'])
# set figure size and style
fig = plt.figure(figsize=(12,8))
sns.set_style('darkgrid')
# ----- FIRST SUBPLOT ------
plt.subplot(1, 2, 1)
# plot axes
plt.axvline(ymin=0.065, ymax=0.93, color='black')
plt.axhline(xmin=0.065, xmax=0.93, color='black')
# plot supply and demand curves
plt.plot('Quantity', 'Price', data=df_housing_supply, color='tomato',
zorder=1, lw=2, label='')
plt.plot('Quantity', 'Price', data=df_housing_demand_increase,
color='lightseagreen', linestyle='dashed', zorder=1, lw=2, label='')
plt.plot('Quantity', 'Price', data=df_housing_supply_decrease, color='tomato',
zorder=1, linestyle='dashed', lw=2, label='')
plt.plot('Quantity', 'Price', data=df_housing_demand_increase2,
color='lightseagreen', zorder=1, linestyle='dashdot', lw=2, label='')
# plot equilibria and plumb lines
plt.scatter(x=3, y=2.5, zorder=2, color='grey', s=60, label='Pre-legislation equilibrium')
plt.plot('xx', 'yy', data=dotted_two, linestyle='dotted', color='grey',
label='', lw=3)
plt.scatter(x=2.5, y=3, zorder=2, color='royalblue', s=60, label='Post-legislation equilibrium')
plt.plot('xx', 'yy', data=dotted_four, linestyle='dotted',
color='royalblue', label='', lw=3)
# axes labels
plt.xlabel('Quantity', fontsize=16)
plt.ylabel('Price', fontsize=16)
# axes limits
plt.xlim([-0.3, 4.3])
plt.ylim([-0.3, 4.3])
# title and legend
plt.title('Theory', fontsize=18, pad=20)
plt.legend(bbox_to_anchor=(0.5, -0.4), loc=8, prop={'size': 13})
plt.tight_layout()
# ----- SECOND SUBPLOT -----
plt.subplot(1, 2, 2)
# plot axes
plt.axvline(ymin=0.07, ymax=0.95, color='black')
plt.axhline(xmin=0.07, xmax=0.95, color='black')
# plot equilibria and plumb lines
plt.scatter(x=310, y=323, zorder=2, color='grey', s=60, label='2016 equilibrium, pre-legislation')
plt.plot('xx', 'yy', data=df_dots_2016, linestyle='dotted', color='grey', label='', lw=3)
plt.scatter(x=270, y=352, zorder=2, color='royalblue', s=60, label='2018 equilibrium, post-legislation')
plt.plot('xx', 'yy', data=df_dots_2018, linestyle='dotted', color='royalblue', label='', lw=3)
# axes labels
plt.xlabel('Quantity', fontsize=16)
plt.ylabel('Price in thousands of pounds', fontsize=16)
# axes limits
plt.xlim([-38, 500])
plt.ylim([-38, 500])
# title and legend
plt.title('Reality', fontsize=18, pad=20)
plt.legend(bbox_to_anchor=(0.5, -0.4), loc=8, prop={'size': 13})
plt.tight_layout()
# ----- End of second subplot -----
# figure title
plt.subplots_adjust(top=0.83)
fig.suptitle('St. Ives Housing Market: Before & After Legislation', fontsize=20)
fig.savefig('st-ives-housing-market-theoretical-and-real.png', dpi=180);