In [1]:
import pandas as pd
import numpy as np
import matplotlib as mpl
import mplstyle
import mplstyle.styles.simple
%matplotlib inline

In [2]:
mplstyle.set(mplstyle.styles.simple)
fonts = mpl.font_manager.findSystemFonts()
arial_narrow = mpl.font_manager.FontProperties(filter(lambda x: "Arial Narrow.ttf" in x, fonts)[0])

In [3]:
mplstyle.set({
    "figure.figsize": (12, 8)
})

Comparing Increases in Average Tuition+Fees vs. Minimum Wage


In [4]:
min_wage = pd.read_csv("../data/federal-minimum-wage.csv", parse_dates=["effective_date"], index_col="effective_date")

In [5]:
min_wage["highest"] = min_wage.max(axis=1)

Because we're talking about summer earnings, we use the minimum wage as it was the July 1 of each year.


In [6]:
monthly_min_wage = min_wage["highest"].resample("D").fillna(method="pad")
julys = [ i for i in monthly_min_wage.index if i.month == 7 and i.day == 1 ]
july_min_wage = monthly_min_wage.ix[julys].shift(-1, freq="AS")

In [7]:
avg_tuition = pd.read_csv("../data/average-tuition.csv", parse_dates=["year"], index_col="year")

In [8]:
# Limit timespan to years for which we have tuition data
start = "1970"
end = "2011"

Calculate and chart the number of hours require to pay for avg. tuition


In [9]:
hours_required = (avg_tuition["public_4yr_instate"].resample("AS").ix[start:end] * 1.0 / \
      july_min_wage.ix[start:end])

In [10]:
ax = hours_required.plot(drawstyle="default", color="red",
    markersize=0, lw=3, alpha=0.75)
ax.minorticks_off()
ax.set_ylim(0, ax.get_ylim()[1])
ax.set_yticklabels(map("{0:,.0f} hours".format, ax.get_yticks()), fontsize="large", color="#888888")
mpl.pyplot.setp(ax.get_xticklabels(), fontsize=14, fontweight="bold")
ax.set_xlabel("")
ax.set_title(u"""Minimum-Wage Hours Required To Pay In-State
Tuition and Fees at an Average 4-Year Public University
""", fontsize=20)
pass



In [11]:
hours_required.apply(round).head(5)


Out[11]:
year
1970-01-01    272
1971-01-01    268
1972-01-01    314
1973-01-01    321
1974-01-01    256
Freq: AS-JAN, dtype: float64

In [12]:
hours_required.apply(round).tail(5)


Out[12]:
year
2007-01-01    1154
2008-01-01    1079
2009-01-01    1022
2010-01-01     984
2011-01-01    1062
Freq: AS-JAN, dtype: float64

Chart the nominal-dollar values for tuition and minimum wage summer earnings over time


In [13]:
ax = (july_min_wage * 12 * 40).ix[start:end]\
    .plot(drawstyle='steps', lw=3, markersize=0, color="teal", alpha=0.75)
avg_tuition["public_4yr_instate"]\
    .resample("AS")\
    .dropna()\
    .ix[start:end]\
    .plot(drawstyle="default", color="red", markersize=0, lw=3, alpha=0.75)
ax.minorticks_off()
ax.set_yticklabels(map("${0:,.0f}".format, ax.get_yticks()), fontsize="large", color="#888888")
mpl.pyplot.setp(ax.get_xticklabels(), fontsize=14, fontweight="bold")
ax.set_xlabel("")
ax.set_title(u"""
Average Tuition and Fees — 4-Year U.S. Public Universities (Red)
vs.
Minimum-Wage Summer Earnings — 12 Weeks @ 40 Hours/Week (Blue)
""", fontsize=20)
pass


School-Specific Calculations

Here, we compare the cost-coverage of a summer's worth of minimum-wage work, in 1976–77 vs. 2014–15, at four prominent state universities.


In [14]:
schools = pd.read_csv("../data/specific-schools.csv")

In [15]:
schools["coverage_1976"] = schools["farm_min_wage_1976"] * 40 * 12 / schools["cost_1976"]
schools["coverage_2014"] = schools["state_min_wage_2014"] * 40 * 12 / schools["cost_2014"]

In [16]:
ax = schools[["coverage_1976", "coverage_2014"]]\
    .rename(columns=dict(coverage_1976=u"1976–77", coverage_2014=u"2014–15")).plot(kind="bar",
        width=0.8,
        color=[ "#0077ee", "#ee3322" ],
        edgecolor="white")
mpl.pyplot.axhline(1, zorder=0, lw=2, color="#ffee00")
ax.set_ylim((0, 1.6))
ax.set_yticks(np.arange(0, 1.6, 0.25))
ax.set_xticklabels(schools["university"].apply(lambda x: x.replace(", ", ",\n")),
    rotation=0,
    fontsize="x-large",
    fontweight="bold")
ax.set_xlim((-0.5, 2.5))
ax.set_yticklabels([ "{0:.0f}%".format(y*100) for y in ax.get_yticks() ],
    fontsize="x-large")
ax.xaxis.grid(False)
ax.legend(loc="upper right", fontsize=18)
ax.set_title(u"""
Summer Minimum Wage Earnings (40 Hours/Week for 12 Weeks)
as a Percentage of Tution and Mandatory Fees
""", fontsize=18, linespacing=1.25)
pass