- 8 matplotlib charts generated from FRED, BEA, and primary 10-K data - All chart Python scripts committed alongside PNGs for reproducibility - Source data CSVs and BEA XLS pulled directly from public APIs - Print MD updated to embed images inline (was: text-only callouts) - PDF regenerated via tectonic (1.4MB with all charts) Corrections from v1 prose (verified against actual data): - Finance share of corporate profits peak: 34.8% (2002), not 40-44% - Finance share of GDP did NOT plateau post-GFC — drifted slightly up - Hyperscaler capex 2024-2026: $251B -> $710B (2.8x, not 3x) Data gaps flagged in chart captions: - Philippon 130-year unit-cost series replaced with BEA 1997-2025 - Carta middle-bucket percentages estimated from blog text - Mega-round pre-2018 shares interpolated from round counts Pentagon-Agent: Rio <244ba05f-3aa3-4079-8c59-6d68a77c76fe>
98 lines
3.6 KiB
Python
98 lines
3.6 KiB
Python
"""
|
||
Chart 2: Finance & insurance value added as % of US GDP, 1997-2025
|
||
|
||
Source: BEA Industry Economic Accounts, Table 1.10 (TVA110-A annual)
|
||
URL: https://apps.bea.gov/industry/Release/XLS/GDPxInd/ValueAdded.xlsx
|
||
Published April 9, 2026. Annual frequency. NAICS-based.
|
||
|
||
Key story: NO COMPRESSION. Finance and insurance share of GDP went from
|
||
6.7% (1997) to 7.9% (2025), oscillating between a 5.9% GFC trough (2008)
|
||
and an 8.0% peak (2020). Every prior tech wave was supposed to compress this.
|
||
It didn't.
|
||
|
||
Data gap: pre-1997 data uses SIC industry codes (not NAICS) and lives in
|
||
BEA historical archives. The Greenwood/Ialenti/Scharfstein 2025 Annual
|
||
Review paper and Philippon's 2015 AER paper provide the longer-run series
|
||
back to 1880. We don't reproduce their data here — we cite it in caption.
|
||
"""
|
||
|
||
from pathlib import Path
|
||
import csv
|
||
import matplotlib.pyplot as plt
|
||
import matplotlib.ticker as mtick
|
||
|
||
HERE = Path(__file__).parent
|
||
OUT = HERE / "chart_02_finance_share_gdp.png"
|
||
|
||
years, vals = [], []
|
||
with open(HERE / "data" / "bea_finance_share_gdp_1997_2025.csv") as f:
|
||
r = csv.DictReader(f)
|
||
for row in r:
|
||
years.append(int(row["year"]))
|
||
vals.append(float(row["finance_insurance_pct_gdp"]))
|
||
|
||
fig, ax = plt.subplots(figsize=(10, 5.5), dpi=200)
|
||
ax.plot(years, vals, color="#1f4e79", linewidth=2.0, marker="o", markersize=4)
|
||
ax.fill_between(years, vals, alpha=0.12, color="#1f4e79")
|
||
|
||
# Reference: Philippon "constant unit cost of intermediation" implies stable ~2% of GDP for the
|
||
# *unit cost* metric — different from value-added, but worth annotating as the related claim.
|
||
# The relevant horizontal here is the 1997 baseline of 6.7%.
|
||
ax.axhline(6.7, color="#888", linestyle="--", linewidth=0.8, alpha=0.6)
|
||
ax.text(1997.5, 6.55, "1997 baseline: 6.7%", fontsize=8, color="#666", va="top")
|
||
|
||
# Annotate key points
|
||
ax.annotate(
|
||
f"GFC trough\n2008: {vals[years.index(2008)]:.1f}%",
|
||
xy=(2008, vals[years.index(2008)]),
|
||
xytext=(2003.5, 5.4),
|
||
fontsize=8,
|
||
arrowprops=dict(arrowstyle="->", color="#666", lw=0.6),
|
||
)
|
||
|
||
peak_idx = vals.index(max(vals))
|
||
ax.annotate(
|
||
f"Peak\n{years[peak_idx]}: {vals[peak_idx]:.1f}%",
|
||
xy=(years[peak_idx], vals[peak_idx]),
|
||
xytext=(years[peak_idx] - 4, vals[peak_idx] + 0.5),
|
||
fontsize=8,
|
||
arrowprops=dict(arrowstyle="->", color="#666", lw=0.6),
|
||
)
|
||
|
||
ax.annotate(
|
||
f"2025: {vals[-1]:.1f}%",
|
||
xy=(years[-1], vals[-1]),
|
||
xytext=(years[-1] - 5, vals[-1] - 0.5),
|
||
fontsize=8,
|
||
arrowprops=dict(arrowstyle="->", color="#666", lw=0.6),
|
||
)
|
||
|
||
ax.set_title(
|
||
"Finance & insurance value added as % of US GDP, 1997–2025",
|
||
fontsize=13,
|
||
fontweight="bold",
|
||
pad=14,
|
||
)
|
||
ax.set_xlabel("Year", fontsize=10)
|
||
ax.set_ylabel("Finance & insurance value added / GDP", fontsize=10)
|
||
ax.yaxis.set_major_formatter(mtick.PercentFormatter(decimals=1))
|
||
ax.set_ylim(5.0, 9.0)
|
||
ax.set_xlim(1996, 2026)
|
||
ax.grid(alpha=0.25)
|
||
ax.spines["top"].set_visible(False)
|
||
ax.spines["right"].set_visible(False)
|
||
|
||
caption = (
|
||
"Source: BEA Industry Economic Accounts, Table 1.10 (Value Added as % of GDP), April 2026. NAICS-based.\n"
|
||
"Pre-1997 series exists in Philippon (AER 2015) and Greenwood/Ialenti/Scharfstein (Annual Review of\n"
|
||
"Financial Economics 2025); these show finance share rose from ~2.8% in 1950 to current levels."
|
||
)
|
||
fig.text(0.02, 0.005, caption, fontsize=7, color="#555")
|
||
|
||
plt.tight_layout(rect=[0, 0.045, 1, 1])
|
||
plt.savefig(OUT, dpi=200, bbox_inches="tight")
|
||
print(f"wrote {OUT}")
|
||
print(f"data span: {years[0]}–{years[-1]} ({len(years)} years)")
|
||
print(f"min: {min(vals)}% in {years[vals.index(min(vals))]}")
|
||
print(f"max: {max(vals)}% in {years[vals.index(max(vals))]}")
|
||
print(f"latest: {vals[-1]}% ({years[-1]})")
|