Merge pull request #9 from PR0M3TH3AN/codex/name-charts-with-script-and-timestamp

Add timestamp-based output naming for charts
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2025-05-31 08:28:56 -04:00
commit de889caa3d
4 files changed
+51 -7

No files matched your search

+4
View File
@@ -95,6 +95,10 @@ To add new data and plot it later:
The plotting script validates that both series contain data for the The plotting script validates that both series contain data for the
requested period before rendering the chart. requested period before rendering the chart.
If no `--output` path is provided, each script automatically saves the figure to
`outputs/<script>_<timestamp>.png`, where `<script>` is the script's base name
and `<timestamp>` is the current date and time in `YYYYMMDD_HHMMSS` format.
| Option | Description | | Option | Description |
| ---------------- | ----------------------------------------------- | | ---------------- | ----------------------------------------------- |
| `--offset` | Lag in months (pos = oil leads; neg = oil lags) | | `--offset` | Lag in months (pos = oil leads; neg = oil lags) |
+15 -2
View File
@@ -22,6 +22,20 @@ from dateutil.relativedelta import relativedelta
import sqlite3 import sqlite3
def save_figure(fig: plt.Figure, output: str | None, script_path: str) -> Path:
"""Save ``fig`` to ``output`` or a timestamped path under ``outputs/``."""
out_path = (
Path(output)
if output is not None
else Path("outputs")
/ f"{Path(script_path).stem}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
)
out_path.parent.mkdir(parents=True, exist_ok=True)
fig.savefig(out_path)
print(f"Saved figure to {out_path}")
return out_path
def fetch_series( def fetch_series(
start: datetime, start: datetime,
end: datetime, end: datetime,
@@ -140,8 +154,7 @@ def main(argv: list[str] | None = None) -> plt.Figure:
btc, m2 = fetch_series(start_dt, end_dt, args.btc_series, args.m2_series, args.db) btc, m2 = fetch_series(start_dt, end_dt, args.btc_series, args.m2_series, args.db)
fig = plot_bitcoin_m2(btc, m2, args.offset_days, args.extend_years) fig = plot_bitcoin_m2(btc, m2, args.offset_days, args.extend_years)
if args.output: save_figure(fig, args.output, __file__)
fig.savefig(args.output)
if argv is None: if argv is None:
fig.show() fig.show()
return fig return fig
+15 -2
View File
@@ -20,6 +20,20 @@ import pandas as pd
import sqlite3 import sqlite3
def save_figure(fig: plt.Figure, output: str | None, script_path: str) -> Path:
"""Save ``fig`` to ``output`` or a timestamped path under ``outputs/``."""
out_path = (
Path(output)
if output is not None
else Path("outputs")
/ f"{Path(script_path).stem}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
)
out_path.parent.mkdir(parents=True, exist_ok=True)
fig.savefig(out_path)
print(f"Saved figure to {out_path}")
return out_path
def fetch_series_multi( def fetch_series_multi(
series: Iterable[str], series: Iterable[str],
start: datetime, start: datetime,
@@ -97,8 +111,7 @@ def main(argv: list[str] | None = None) -> plt.Figure:
data = fetch_series_multi(args.series, start_dt, end_dt, args.db) data = fetch_series_multi(args.series, start_dt, end_dt, args.db)
fig = plot_series(data) fig = plot_series(data)
if args.output: save_figure(fig, args.output, __file__)
fig.savefig(args.output)
if argv is None: if argv is None:
fig.show() fig.show()
return fig return fig
+17 -3
View File
@@ -23,6 +23,20 @@ from dateutil.relativedelta import relativedelta
import sqlite3 import sqlite3
def save_figure(fig: plt.Figure, output: str | None, script_path: str) -> Path:
"""Save ``fig`` to ``output`` or a timestamped path under ``outputs/``."""
out_path = (
Path(output)
if output is not None
else Path("outputs")
/ f"{Path(script_path).stem}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
)
out_path.parent.mkdir(parents=True, exist_ok=True)
fig.savefig(out_path)
print(f"Saved figure to {out_path}")
return out_path
# ────────────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────────────
# Data helpers # Data helpers
# ────────────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────────────
@@ -217,7 +231,7 @@ def plot_lagged(
# ────────────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────────────
# CLI # CLI
# ────────────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────────────
def main() -> None: def main() -> plt.Figure:
p = argparse.ArgumentParser() p = argparse.ArgumentParser()
p.add_argument( p.add_argument(
"-o", "-o",
@@ -264,9 +278,9 @@ def main() -> None:
unrate, oil = fetch_series(start_dt, end_dt, args.db) unrate, oil = fetch_series(start_dt, end_dt, args.db)
validate_series(unrate, oil) validate_series(unrate, oil)
fig = plot_lagged(unrate, oil, args.offset, start_dt, end_dt, args.extend_years) fig = plot_lagged(unrate, oil, args.offset, start_dt, end_dt, args.extend_years)
if args.output: save_figure(fig, args.output, __file__)
fig.savefig(args.output)
fig.show() fig.show()
return fig
if __name__ == "__main__": if __name__ == "__main__":