Exploring Economic Data Using FRED

In [1]:
import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 
import plotly.express as px 
import time

plt.style.use('fivethirtyeight') 
In [2]:
!pip install fredapi 
Requirement already satisfied: fredapi in c:\users\hunte\anaconda3\lib\site-packages (0.5.0)
Requirement already satisfied: pandas in c:\users\hunte\anaconda3\lib\site-packages (from fredapi) (1.4.2)
Requirement already satisfied: numpy>=1.18.5 in c:\users\hunte\anaconda3\lib\site-packages (from pandas->fredapi) (1.21.5)
Requirement already satisfied: pytz>=2020.1 in c:\users\hunte\anaconda3\lib\site-packages (from pandas->fredapi) (2021.3)
Requirement already satisfied: python-dateutil>=2.8.1 in c:\users\hunte\anaconda3\lib\site-packages (from pandas->fredapi) (2.8.2)
Requirement already satisfied: six>=1.5 in c:\users\hunte\anaconda3\lib\site-packages (from python-dateutil>=2.8.1->pandas->fredapi) (1.16.0)
In [3]:
# fetch api key

from tkinter import *
from tkinter import filedialog
from tkinter import Tk
import json

# We don't need the tkinter popup window
root = Tk()
root.withdraw()


filepath = filedialog.askopenfilename()
file = open(filepath, 'r')


credentials = json.load(file)
file.close()


fred_key = credentials['fred_api']
In [4]:
from fredapi import Fred
fred = Fred(api_key=fred_key)

Searching FRED for Economic Data¶

In [5]:
sp_search = fred.search('S&P', order_by='popularity')
In [6]:
sp_search.head()
Out[6]:
id realtime_start realtime_end title observation_start observation_end frequency frequency_short units units_short seasonal_adjustment seasonal_adjustment_short last_updated popularity notes
series id
BAMLH0A0HYM2 BAMLH0A0HYM2 2024-03-28 2024-03-28 ICE BofA US High Yield Index Option-Adjusted S... 1996-12-31 2024-03-27 Daily, Close D Percent % Not Seasonally Adjusted NSA 2024-03-28 08:51:11-05:00 92 The ICE BofA Option-Adjusted Spreads (OASs) ar...
CSUSHPINSA CSUSHPINSA 2024-03-28 2024-03-28 S&P CoreLogic Case-Shiller U.S. National Home ... 1987-01-01 2024-01-01 Monthly M Index Jan 2000=100 Index Jan 2000=100 Not Seasonally Adjusted NSA 2024-03-26 08:11:02-05:00 88 For more information regarding the index, plea...
SP500 SP500 2024-03-28 2024-03-28 S&P 500 2014-03-28 2024-03-27 Daily, Close D Index Index Not Seasonally Adjusted NSA 2024-03-27 19:11:00-05:00 83 The observations for the S&P 500 represent the...
MEHOINUSA672N MEHOINUSA672N 2024-03-28 2024-03-28 Real Median Household Income in the United States 1984-01-01 2022-01-01 Annual A 2022 CPI-U-RS Adjusted Dollars 2022 CPI-U-RS Adjusted $ Not Seasonally Adjusted NSA 2023-09-12 13:48:02-05:00 83 Household data are collected as of March. As ...
BAMLH0A0HYM2EY BAMLH0A0HYM2EY 2024-03-28 2024-03-28 ICE BofA US High Yield Index Effective Yield 1996-12-31 2024-03-27 Daily, Close D Percent % Not Seasonally Adjusted NSA 2024-03-28 08:51:15-05:00 82 This data represents the effective yield of th...
In [7]:
sp500 = fred.get_series(series_id='SP500')
sp500.plot(figsize=(10, 5), title='S&P 500', lw=2)
plt.show()

Joining Multiple Data Series¶

In [8]:
unemp_df = fred.search('unemployment rate state', filter=('frequency','Monthly'))
unemp_df = unemp_df.query('seasonal_adjustment == "Seasonally Adjusted" and units == "Percent"')
unemp_df = unemp_df.loc[unemp_df['title'].str.contains('Unemployment Rate')]
In [9]:
all_results = []

for myid in unemp_df.index:
    results = fred.get_series(myid)
    results = results.to_frame(name=myid)
    all_results.append(results)
    time.sleep(0.1) # Don't request too fast and get blocked
uemp_results = pd.concat(all_results, axis=1)
In [10]:
cols_to_drop = []
for i in uemp_results:
    if len(i) > 4:
        cols_to_drop.append(i)
uemp_results = uemp_results.drop(columns = cols_to_drop, axis=1)
In [11]:
uemp_results.shape
Out[11]:
(1127, 52)
In [12]:
uemp_states = uemp_results.copy()  #.drop('UNRATE', axis=1)
uemp_states = uemp_states.dropna()
id_to_state = unemp_df['title'].str.replace('Unemployment Rate in ','').to_dict()
uemp_states.columns = [id_to_state[c] for c in uemp_states.columns]
In [13]:
# Plot States Unemployment Rate
px.line(uemp_states)

Pulling December 2023 Data Per State¶

In [14]:
ax = uemp_states.loc[uemp_states.index == '2023-12-01'].T \
    .sort_values('2023-12-01') \
    .plot(kind='barh', figsize=(8, 12), width=0.7, edgecolor='black',
          title='Unemployment Rate by State, December 2023')
ax.legend().remove()
ax.set_xlabel('% Unemployed')
plt.show()

Pulling Participation Rate¶

In [15]:
part_df = fred.search('participation rate state', filter=('frequency','Monthly'))
part_df = part_df.query('seasonal_adjustment == "Seasonally Adjusted" and units == "Percent"')
In [16]:
part_id_to_state = part_df['title'].str.replace('Labor Force Participation Rate for ','').to_dict()

all_results = []

for myid in part_df.index:
    results = fred.get_series(myid)
    results = results.to_frame(name=myid)
    all_results.append(results)
    time.sleep(0.1) # Don't request too fast and get blocked
part_states = pd.concat(all_results, axis=1)
part_states.columns = [part_id_to_state[c] for c in part_states.columns]

Plotting Unemployment vs Participation for Each State¶

In [17]:
# Fix DC
uemp_states = uemp_states.rename(columns={'the District of Columbia':'District Of Columbia'})
In [18]:
# Put the uemp_states columns in alphabetical order
uemp_states = uemp_states.reindex(sorted(uemp_states.columns), axis=1)
In [19]:
fig, axs = plt.subplots(10, 5, figsize=(30, 30), sharex=True)
axs = axs.flatten()

i = 0
for state in uemp_states.columns:
    if state in ["District Of Columbia","Puerto Rico"]:
        continue
    ax2 = axs[i].twinx()
    uemp_states.query('index >= 2020 and index < 2022')[state] \
        .plot(ax=axs[i], label='Unemployment')
    part_states.query('index >= 2020 and index < 2022')[state] \
        .plot(ax=ax2, label='Participation', color='red')
    ax2.grid(False)
    axs[i].set_title(state)
    i += 1
plt.tight_layout()
plt.show()
In [20]:
fred.search('unemployment rate men')
Out[20]:
id realtime_start realtime_end title observation_start observation_end frequency frequency_short units units_short seasonal_adjustment seasonal_adjustment_short last_updated popularity notes
series id
LNS14000031 LNS14000031 2024-03-28 2024-03-28 Unemployment Rate - 20 Yrs. & over, Black or A... 1972-01-01 2024-02-01 Monthly M Percent % Seasonally Adjusted SA 2024-03-08 08:03:14-06:00 56 The series comes from the 'Current Population ...
LNU04000031 LNU04000031 2024-03-28 2024-03-28 Unemployment Rate - 20 Yrs. & over, Black or A... 1972-01-01 2024-02-01 Monthly M Percent % Not Seasonally Adjusted NSA 2024-03-08 08:02:27-06:00 5 The series comes from the 'Current Population ...
LNS14000001 LNS14000001 2024-03-28 2024-03-28 Unemployment Rate - Men 1948-01-01 2024-02-01 Monthly M Percent % Seasonally Adjusted SA 2024-03-08 08:03:21-06:00 41 The series comes from the 'Current Population ...
LNS13000001 LNS13000001 2024-03-28 2024-03-28 Unemployment Level - Men 1948-01-01 2024-02-01 Monthly M Thousands of Persons Thous. of Persons Seasonally Adjusted SA 2024-03-08 08:03:23-06:00 42 The series comes from the 'Current Population ...
LNU04000001 LNU04000001 2024-03-28 2024-03-28 Unemployment Rate - Men 1948-01-01 2024-02-01 Monthly M Percent % Not Seasonally Adjusted NSA 2024-03-08 08:02:23-06:00 5 The series comes from the 'Current Population ...
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
LRUN64MANZQ156S LRUN64MANZQ156S 2024-03-28 2024-03-28 Unemployment Rate: Aged 15-64: Males for New Z... 1986-01-01 2023-07-01 Quarterly Q Percent % Seasonally Adjusted SA 2023-11-17 11:46:38-06:00 0 OECD Descriptor ID: LRUN64MA OECD unit ID: PC ...
LRUN64MAFIA156N LRUN64MAFIA156N 2024-03-28 2024-03-28 Unemployment Rate: Aged 15-64: Males for Finland 1998-01-01 2022-01-01 Annual A Percent % Not Seasonally Adjusted NSA 2023-04-20 16:23:13-05:00 0 OECD Descriptor ID: LRUN64MA OECD unit ID: PC ...
LRUN64MAFIA156S LRUN64MAFIA156S 2024-03-28 2024-03-28 Unemployment Rate: Aged 15-64: Males for Finland 1998-01-01 2022-01-01 Annual A Percent % Seasonally Adjusted SA 2023-04-20 16:23:13-05:00 0 OECD Descriptor ID: LRUN64MA OECD unit ID: PC ...
LRUN64MAFIQ156N LRUN64MAFIQ156N 2024-03-28 2024-03-28 Unemployment Rate: Aged 15-64: Males for Finland 1998-01-01 2023-07-01 Quarterly Q Percent % Not Seasonally Adjusted NSA 2024-01-12 14:44:32-06:00 0 OECD Descriptor ID: LRUN64MA OECD unit ID: PC ...
LRUNTTMAFIA156N LRUNTTMAFIA156N 2024-03-28 2024-03-28 Unemployment Rate: Aged 15 and over: Males for... 1998-01-01 2022-01-01 Annual A Percent % Not Seasonally Adjusted NSA 2023-04-20 16:23:32-05:00 0 OECD Descriptor ID: LRUNTTMA OECD unit ID: PC ...

1000 rows × 15 columns

In [21]:
unemp_men = fred.get_series(series_id='LNS14000001')
unemp_men.plot(figsize=(10, 5), title='Unemployment Rate Men', lw=2)
plt.show()
In [22]:
fred.search('unemployment rate women')
Out[22]:
id realtime_start realtime_end title observation_start observation_end frequency frequency_short units units_short seasonal_adjustment seasonal_adjustment_short last_updated popularity notes
series id
LNS14000002 LNS14000002 2024-03-28 2024-03-28 Unemployment Rate - Women 1948-01-01 2024-02-01 Monthly M Percent % Seasonally Adjusted SA 2024-03-08 08:03:17-06:00 51 To obtain estimates of women worker employment...
LNU04000002 LNU04000002 2024-03-28 2024-03-28 Unemployment Rate - Women 1948-01-01 2024-02-01 Monthly M Percent % Not Seasonally Adjusted NSA 2024-03-08 08:02:28-06:00 4 To obtain estimates of women worker employment...
LNS13000002 LNS13000002 2024-03-28 2024-03-28 Unemployment Level - Women 1948-01-01 2024-02-01 Monthly M Thousands of Persons Thous. of Persons Seasonally Adjusted SA 2024-03-08 08:03:23-06:00 41 To obtain estimates of women worker employment...
LNS14000032 LNS14000032 2024-03-28 2024-03-28 Unemployment Rate - 20 Yrs. & over, Black or A... 1972-01-01 2024-02-01 Monthly M Percent % Seasonally Adjusted SA 2024-03-08 08:03:36-06:00 13 To obtain estimates of women worker employment...
LNU04000032 LNU04000032 2024-03-28 2024-03-28 Unemployment Rate - 20 Yrs. & over, Black or A... 1972-01-01 2024-02-01 Monthly M Percent % Not Seasonally Adjusted NSA 2024-03-08 08:02:22-06:00 7 To obtain estimates of women worker employment...
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
LRUN64FEJPA156N LRUN64FEJPA156N 2024-03-28 2024-03-28 Unemployment Rate: Aged 15-64: Females for Japan 1968-01-01 2022-01-01 Annual A Percent % Not Seasonally Adjusted NSA 2023-02-14 12:01:09-06:00 0 OECD Descriptor ID: LRUN64FE OECD unit ID: PC ...
LRUN64FEJPM156N LRUN64FEJPM156N 2024-03-28 2024-03-28 Unemployment Rate: Aged 15-64: Females for Japan 1968-01-01 2023-11-01 Monthly M Percent % Not Seasonally Adjusted NSA 2024-01-12 14:49:01-06:00 0 OECD Descriptor ID: LRUN64FE OECD unit ID: PC ...
LRUN64FEJPQ156N LRUN64FEJPQ156N 2024-03-28 2024-03-28 Unemployment Rate: Aged 15-64: Females for Japan 1968-01-01 2023-07-01 Quarterly Q Percent % Not Seasonally Adjusted NSA 2023-11-17 12:26:53-06:00 0 OECD Descriptor ID: LRUN64FE OECD unit ID: PC ...
LRUN64FEJPQ156S LRUN64FEJPQ156S 2024-03-28 2024-03-28 Unemployment Rate: Aged 15-64: Females for Japan 1970-01-01 2023-07-01 Quarterly Q Percent % Seasonally Adjusted SA 2023-11-17 12:26:53-06:00 0 OECD Descriptor ID: LRUN64FE OECD unit ID: PC ...
LRUN74FEUSA156N LRUN74FEUSA156N 2024-03-28 2024-03-28 Unemployment Rate: Aged 15-74: Females for Uni... 1981-01-01 2023-01-01 Annual A Percent % Not Seasonally Adjusted NSA 2024-01-12 14:51:41-06:00 0 OECD Descriptor ID: LRUN74FE OECD unit ID: PC ...

1000 rows × 15 columns

In [23]:
unemp_women = fred.get_series(series_id='LNS14000002')
unemp_women.plot(figsize=(10, 5), title='Unemployment Rate Women', lw=2)
plt.show()
In [24]:
unemp_men = fred.get_series(series_id='LNS14000001')
unemp_men.plot(figsize=(10, 5), lw=2,label="Men")
unemp_women = fred.get_series(series_id='LNS14000002')
unemp_women.plot(figsize=(10, 5), title='Unemployment Rate Men and Women', lw=1,label="Women")
plt.legend() 
plt.show()
In [ ]: