Files
python_charts/repo-context.txt
T
thePR0M3TH3AN 96964c6981 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.
2025-05-30 15:48:34 -04:00

297 lines
8.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 <[email protected]>"]
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)
```