Unemployment rate with NBER recession shading
Macroeconomics
Example from the compendium of canonical charts
Python Code
"""Macroeconomics — Unemployment rate with NBER recession shading."""
import pandas as pd
import plotly.graph_objects as go
UNRATE_URL = "https://fred.stlouisfed.org/graph/fredgraph.csv?id=UNRATE"
USREC_URL = "https://fred.stlouisfed.org/graph/fredgraph.csv?id=USREC"
def generate():
print("fetching UNRATE and USREC from FRED …")
unrate = fetch_csv(UNRATE_URL)
usrec = fetch_csv(USREC_URL)
unrate.columns = ["date", "unrate"]
usrec.columns = ["date", "rec"]
unrate["date"] = pd.to_datetime(unrate["date"], errors="coerce")
usrec["date"] = pd.to_datetime(usrec["date"], errors="coerce")
# Align on common date range
df = pd.merge(unrate, usrec, on="date", how="inner").sort_values("date")
df = df.dropna()
# Find contiguous recession blocks
in_rec = False
rec_start = None
rec_blocks = []
for _, row in df.iterrows():
if row["rec"] == 1 and not in_rec:
in_rec = True
rec_start = row["date"]
elif row["rec"] == 0 and in_rec:
in_rec = False
rec_blocks.append((rec_start, row["date"]))
if in_rec:
rec_blocks.append((rec_start, df["date"].iloc[-1]))
fig = go.Figure()
# Recession vrects (add first so they sit behind the line)
for start, end in rec_blocks:
fig.add_vrect(
x0=start, x1=end,
fillcolor="gray", opacity=0.18,
line_width=0,
)
# UNRATE line
fig.add_trace(go.Scatter(
x=df["date"],
y=df["unrate"],
mode="lines",
line=dict(color=VIOLET, width=1.8),
name="Unemployment Rate",
hovertemplate="%{x|%b %Y}: %{y:.1f}%<extra></extra>",
))
fig.update_layout(
xaxis=dict(title=""),
yaxis=dict(title="Unemployment Rate (%)", ticksuffix="%"),
legend=dict(orientation="h", y=-0.14),
margin=dict(t=50, b=70, l=70, r=40),
annotations=[dict(
x=0.01, y=0.97,
xref="paper", yref="paper",
text="Gray bands = NBER recessions",
showarrow=False,
font=dict(size=11, color="#60646c"),
align="left",
)],
)
return fig
if __name__ == "__main__":
generate()
Made with Plotly