# Repository Context Generated on: 2025-05-30 ## Directory Tree (Whitelist Only) ``` . ├── scripts/ ├── lagged_oil_unrate_chart_styled.py ├── pyproject.toml ├── README.md ├── requirements.txt ``` ## Important Files ## python_charts/README.md ```markdown # Lagged Oil vs. Unemployment Charting This repository provides two Python scripts to fetch the latest US Unemployment Rate (UNRATE) and WTI crude oil price (DCOILWTICO) from FRED, apply a configurable lag or lead to the oil series, and generate polished dual‑axis charts. ## Files * **`lagged_oil_unrate_chart.py`** A lightweight script that: 1. Downloads monthly UNRATE and averages daily WTI to monthly. 2. Shifts the oil series by `N` months (default = 18). 3. Plots both series on a dual‑axis Matplotlib chart. * **`lagged_oil_unrate_chart_styled.py`** A more polished version that adds: * Title, subtitle, footnote with date range and source. * Clean dual‑axis styling with percentage and dollar‑format ticks. * Customizable date range and extended x‑axis (e.g., 1973–2028). * CLI flags for offset, start/end dates, and axis extension. * **`requirements.txt`** Lists all Python dependencies for both scripts. ## Prerequisites * Python 3.7 or later * Internet connection (to fetch data from FRED) ## Setup Clone or download this repository: ```bash git clone https://your-repo-url.git cd your-repo-folder ``` ### Create a Virtual Environment & Install Dependencies #### On Linux / macOS ```bash # 1. Create a venv python3 -m venv venv # 2. Activate it source venv/bin/activate # 3. Upgrade pip and install requirements pip install --upgrade pip pip install -r requirements.txt ``` #### On Windows (PowerShell) ```powershell # 1. Create a venv python -m venv venv # 2. Activate it venv\Scripts\Activate.ps1 # 3. Upgrade pip and install requirements python -m pip install --upgrade pip pip install -r requirements.txt ``` > **Note:** If you get execution policy errors on Windows, you may need to run: > > ```powershell > Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser > ``` ## Usage Once the virtual environment is active and dependencies are installed, run either script from the project root. ### 1. Basic Lag Script ```bash # Default: oil lags unemployment by 18 months (~1.5 years) python lagged_oil_unrate_chart.py # Other offsets (in months) python lagged_oil_unrate_chart.py --offset 6 # 6‑month lag python lagged_oil_unrate_chart.py --offset -12 # 12‑month lead ``` ### 2. Styled & Configurable Chart ```bash python lagged_oil_unrate_chart_styled.py \ --offset 18 \ --start 1973-01-01 \ --end 2025-05-31 \ --extend-years 3 ``` | Flag | Description | | ------------------ | -------------------------------------------------------------- | | `--offset N` | Lag (positive) or lead (negative) in months (default = 18) | | `--start DATE` | Series start date (`YYYY-MM-DD`, default = `1973-01-01`) | | `--end DATE` | Series end date (`YYYY-MM-DD`, default = today) | | `--extend-years M` | How many years beyond `end` to extend the x‑axis (default = 3) | ## Customization * **Normalization**: Insert a normalization step (e.g., percent change from a base date). * **Export**: Modify the script to save figures with `plt.savefig('chart.png', dpi=300)`. * **Statistics**: Add `ta.correl()` or use Pandas to compute rolling correlations. ## Troubleshooting * **"ModuleNotFoundError"**: Ensure your venv is activated, then reinstall dependencies. * **SSL/DataReader errors**: Upgrade `pandas_datareader` or switch to an alternate data source. ## License This project is released under the MIT License. ``` ## python_charts/requirements.txt ``` pandas>=1.5.0 pandas_datareader>=0.10.0 # good matplotlib>=3.5.0 lxml>=4.6.0 python-dateutil>=2.8.1 ``` ## scripts/pyproject.toml ``` # pyproject.toml [project] name = "lagged-oil-unrate" version = "0.1.0" description = "Plot UNRATE vs WTI oil price with adjustable lag" authors = ["Your Name "] dependencies = [ "pandas>=1.3.0", "pandas_datareader>=0.10.0", "matplotlib>=3.4.0", "python-dateutil>=2.8.0", "lxml>=4.6.0" ] ``` ## scripts/lagged_oil_unrate_chart_styled.py ```python #!/usr/bin/env python3 """ lagged_oil_unrate_chart_styled.py --------------------------------- Fetch and plot UNRATE vs. WTI oil price with a configurable lag, date range, and polished dual-axis styling. Usage: python lagged_oil_unrate_chart_styled.py \ --offset 18 \ --start 1973-01-01 \ --end 2025-05-31 \ --extend-years 3 Dependencies: pip install pandas pandas_datareader matplotlib python-dateutil """ import argparse from datetime import datetime from dateutil.relativedelta import relativedelta import matplotlib.dates as mdates import matplotlib.pyplot as plt import pandas as pd import pandas_datareader.data as web def fetch_series(start, end): # FRED series unrate = web.DataReader("UNRATE", "fred", start, end) oil = web.DataReader("DCOILWTICO", "fred", start, end) # Resample WTI to month-end average oil_monthly = oil.resample("M").mean() # Ensure UNRATE is at month-end timestamps, too unrate.index = unrate.index.to_period("M").to_timestamp("M") return unrate, oil_monthly def plot_lagged( unrate: pd.DataFrame, oil: pd.DataFrame, offset_months: int, start_date: datetime, end_date: datetime, extend_years: int ): # Shift oil by offset: positive = lag; negative = lead oil_shifted = oil.shift(offset_months) # Build figure fig, ax1 = plt.subplots(figsize=(14, 7)) plt.title("Unemployment Rate and US Oil Price", fontsize=20, weight="bold") plt.suptitle( "Civilian Unemployment Rate and WTI Crude Oil Price", fontsize=14, y=0.93 ) # Plot UNRATE on left axis ax1.plot(unrate.index, unrate["UNRATE"], label="UNRATE (LHS)", linewidth=2.5, color="#1f77b4") ax1.set_ylabel("Unemployment rate (%)", fontsize=12) ax1.set_ylim(0, unrate["UNRATE"].max() * 1.1) ax1.yaxis.set_major_formatter("{x:.0f}%") ax1.grid(axis="y", linestyle="--", alpha=0.4) # Plot shifted oil on right axis ax2 = ax1.twinx() ax2.plot(oil_shifted.index, oil_shifted["DCOILWTICO"], label="USOIL (RHS)", linewidth=2, linestyle="-", alpha=0.8, color="#FF9900") ax2.set_ylabel("Oil price (USD)", fontsize=12) ax2.set_ylim(0, oil_shifted["DCOILWTICO"].max() * 1.1) ax2.yaxis.set_major_formatter("${x:,.0f}") # X-axis formatting ax1.set_xlim(start_date, end_date + relativedelta(years=extend_years)) ax1.xaxis.set_major_locator(mdates.YearLocator(base=5)) ax1.xaxis.set_minor_locator(mdates.YearLocator(1)) ax1.xaxis.set_major_formatter(mdates.DateFormatter("%Y")) plt.setp(ax1.get_xticklabels(), rotation=0, fontsize=11) # Combine legends lines, labels = ax1.get_legend_handles_labels() l2, l2l = ax2.get_legend_handles_labels() ax1.legend(lines + l2, labels + l2l, loc="upper left", frameon=False, fontsize=12) # Footnotes foot = ( f"Dates: {start_date.strftime('%Y')} through {unrate.index[-1].strftime('%d %b %Y')}.\n" "Source: FRED, pandas_datareader." ) plt.annotate( foot, (0,0), (0, -40), xycoords="axes fraction", textcoords="offset points", va="top", fontsize=10, color="gray" ) fig.tight_layout(rect=[0, 0.03, 1, 0.95]) plt.show() if __name__ == "__main__": p = argparse.ArgumentParser() p.add_argument("-o", "--offset", type=int, default=18, help="lag in months (positive=lag, negative=lead)") p.add_argument("--start", type=str, default="1973-01-01", help="series start date (YYYY-MM-DD)") p.add_argument("--end", type=str, default=datetime.today().strftime("%Y-%m-%d"), help="series end date (YYYY-MM-DD)") p.add_argument("--extend-years", type=int, default=3, help="how many years beyond end_date to show on the x-axis") args = p.parse_args() start_dt = datetime.fromisoformat(args.start) end_dt = datetime.fromisoformat(args.end) unrate, oil = fetch_series(start_dt, end_dt) plot_lagged(unrate, oil, args.offset, start_dt, end_dt, args.extend_years) ```