In [1]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
Wealth Distribution¶
One way that we might understand equality is through understanding the distribution of wealth in a society. Perfect wealth distribution would mean that all participants have the same share of wealth as everyone else. We can represent this situation mathematically with a function \(L(x) = x\) that we will call the Lorenz Curve.
Concretely, if we were to look at every 20% of the population, we would see 20% of income.
Fifths of Households | Percent of Wealth |
---|---|
Lowest Fifth | 20 |
Lowest two - Fifths | 40 |
Lowest three - Fifths | 60 |
Lowest four - Fifths | 80 |
Lowest five - Fifths | 100 |
In [2]:
percent = [0, 0.2, 0.4, 0.6, 0.8, 1.0]
lorenz = [0, 0.2, 0.4, 0.6, 0.8, 1.0]
In [3]:
plt.plot(percent, lorenz, '-o')
plt.title("Perfect Wealth Distribution")
Out[3]:
<matplotlib.text.Text at 0x118c4c7f0>
It is unlikely that we have perfect distribution of wealth in a society however. For example, the following table describes the cumulative distribution of income in the United States for the year 1994.
Fifths of Households | Percent of Wealth |
---|---|
Lowest Fifth | 4.2 |
Lowest two - Fifths | 14.2 |
Lowest three - Fifths | 29.9 |
Lowest four - Fifths | 53.2 |
Lowest five - Fifths | 100.0 |
In [4]:
usa_94 = [0, 0.042, 0.142, 0.299, 0.532, 1.00]
In [5]:
plt.figure(figsize = (9, 5))
plt.plot(percent, lorenz, '-o', label = 'Lorenz Curve')
plt.plot(percent, usa_94, '-o', label = 'USA 1994')
plt.title("The Difference between Perfect and Actual Wealth Equality")
plt.legend(loc = 'best', frameon = False)
Out[5]:
<matplotlib.legend.Legend at 0x119289c50>
The area between these curves can be understood to represent the discrepency between perfect wealth distribution and levels of inequality. Further, if we examine the ratio between this area and that under the Lorenz Curve we get the Gini Index.
One big issue remains however. We don’t want to use rectangles to
approximate these regions but we don’t have equations for the actual
distribution of wealth. We introduce two curve fitting techniques using
numpy
to address this problem.
Quadratic Fit¶
The curve in the figure above representing the actual distribution of
wealth in the USA in 1994 can be approximated by a polynomial function.
NumPy has a function called polyfit
that will fit a polynomial to a
set of points. Here, we use polyfit
to fit a quadratic function to
the points.
In [6]:
fit = np.poly1d(np.polyfit(percent, usa_94, 2))
In [7]:
plt.figure(figsize = (9, 5))
plt.plot(percent, usa_94, '-o', label = 'Polyfit')
plt.plot(percent, fit(percent), '-o', label = 'Actual USA 1994')
plt.title("Quality of Quadratic Fit")
plt.legend(loc = 'best', frameon = False)
Out[7]:
<matplotlib.legend.Legend at 0x119619f98>
Getting the Fit¶
Below, we return to the complete picture where we plot our fitted function and the Lorenz Curve and shade the area that represents the difference in income distribution.
In [8]:
plt.figure(figsize = (9, 5))
plt.plot(percent, lorenz, '--o', label = 'Lorenz')
plt.plot(percent, fit(percent), '--o', label = 'Polyfit')
plt.fill_between(percent, lorenz, fit(percent), alpha = 0.3, color = 'burlywood')
plt.title("Visualizing the Gini Index")
plt.legend(loc = 'best', frameon = False)
Out[8]:
<matplotlib.legend.Legend at 0x1197d9c50>
Now, we want to compute the ratio between the area between the curves to that under the Lorenz Curve. We can do this easily in Sympy but declaring \(x\) a symbol and substituting it into our fit function then integrating this.
In [9]:
import sympy as sy
In [10]:
x = sy.Symbol('x')
fit(x)
Out[10]:
x*(1.18839285714286*x - 0.241678571428574) + 0.0209285714285723
In [11]:
A_btwn = sy.integrate((x - fit(x)), (x, 0, 1))
In [12]:
A_L = sy.integrate(x, (x, 0,1))
In [13]:
A_btwn/A_L
Out[13]:
0.407559523809523
Inequality through Time¶
Now that we understand how to compute the Gini Index, we want to explore what improving the gap in wealth distribution would mean.
In [14]:
x = np.linspace(0, 1, 100)
plt.figure(figsize = (10, 7))
plt.plot(x, x)
plt.plot(x, x**2, label = "Country A")
plt.plot(x, x**4, label = "Country B")
plt.plot(x, x**8, label = "Country C")
plt.plot(x, x**16, label = "Country D")
plt.ylabel("Income Percent")
plt.xlabel("Population Fraction")
plt.title("Different Wealth Distributions")
plt.legend(loc = "best", frameon = False)
Out[14]:
<matplotlib.legend.Legend at 0x11aa4e860>
Which of the above countries do you believe is the most equitable? Why?
Census Bureau Data and Pandas¶
There are many organizations that use the Gini Index to this day. The OECD, World Bank, and US Census all track Gini Indicies. We want to investigate the real data much as we have with our smaller examples. To do so, we will use the Pandas library.
The table below gives distribution data for the years 1970, 1980, 1990, and 2000.
x | 0.0 | 0.2 | 0.4 | 0.6 | 0.8 | 1.0 |
---|---|---|---|---|---|---|
1970 | 0.000 | 0.041 | 0.149 | 0.323 | 0.568 | 1.000 |
1980 | 0.000 | 0.042 | 0.144 | 0.312 | 0.559 | 1.000 |
1990 | 0.000 | 0.038 | 0.134 | 0.293 | 0.530 | 1.000 |
2000 | 0.000 | 0.036 | 0.125 | 0.273 | 0.503 | 1.000 |
Creating the DataFrame¶
We will begin by creating a table from this data by entering lists with these values and creating a DataFrame from these lists.
In [15]:
import pandas as pd
seventies = [0, 0.041, 0.149, 0.323, 0.568, 1.0]
eighties = [0, 0.042, 0.144, 0.312, 0.559, 1.0]
nineties = [0, 0.038, 0.134, 0.293, 0.53, 1.0]
twothou = [0, 0.036, 0.125, 0.273, 0.503, 1.0]
In [16]:
df = pd.DataFrame({'1970s': seventies, '1980s':eighties, '1990s': nineties,
'2000s': twothou, 'perfect': [0, 0.2, 0.4, 0.6, 0.8, 1.0]})
df.head()
Out[16]:
1970s | 1980s | 1990s | 2000s | perfect | |
---|---|---|---|---|---|
0 | 0.000 | 0.000 | 0.000 | 0.000 | 0.0 |
1 | 0.041 | 0.042 | 0.038 | 0.036 | 0.2 |
2 | 0.149 | 0.144 | 0.134 | 0.125 | 0.4 |
3 | 0.323 | 0.312 | 0.293 | 0.273 | 0.6 |
4 | 0.568 | 0.559 | 0.530 | 0.503 | 0.8 |
Plotting from the DataFrame¶
We can plot directly from the dataframe. The default plot generates
lines for each decades inequality distribution. There are many plot
types available however, and we can specify them with the kind
argument as demonstrated with the density plot that follows. What do
these visualizations tell you about equality in the USA based on this
data?
In [17]:
df.plot(figsize = (10, 8))
Out[17]:
<matplotlib.axes._subplots.AxesSubplot at 0x122d7a518>
In [18]:
df.plot(kind = 'kde')
Out[18]:
<matplotlib.axes._subplots.AxesSubplot at 0x11a9efc88>