From 96964c6981aa4ce5e4e30ccecf9be34b0ad51cce Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Fri, 30 May 2025 15:48:34 -0400 Subject: [PATCH] Add repository context and update requirements for charting scripts - Create `repo-context.txt` to document the repository structure, important files, setup instructions, and usage examples for the lagged oil vs. unemployment charting scripts. - Modify `requirements.txt` to ensure all necessary dependencies are listed for the project. - Add `saved_config.yaml` for storing configuration settings. --- repo-context.txt | 296 ++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 +- saved_config.yaml | 6 + 3 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 repo-context.txt create mode 100644 saved_config.yaml diff --git a/repo-context.txt b/repo-context.txt new file mode 100644 index 0000000..200e6d0 --- /dev/null +++ b/repo-context.txt @@ -0,0 +1,296 @@ +# 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 +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) + +``` + diff --git a/requirements.txt b/requirements.txt index 503365e..3033efc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ pandas>=1.5.0 -pandas\_datareader>=0.10.0 +pandas_datareader>=0.10.0 # good matplotlib>=3.5.0 lxml>=4.6.0 python-dateutil>=2.8.1 diff --git a/saved_config.yaml b/saved_config.yaml new file mode 100644 index 0000000..834fd36 --- /dev/null +++ b/saved_config.yaml @@ -0,0 +1,6 @@ +excluded_files: +- saved_config.yaml +selected_directories: +- scripts/ +- outputs/ +- data/