{
 "cells": [
  {
   "cell_type": "raw",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "---\n",
    "title: \"Multi-Week Plotting Helpers — Colab Notebook\"\n",
    "date: \"March 31, 2026\"\n",
    "visible-after: \"2026-09-18T20:00:00-06:00\"\n",
    "---\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook provides reusable code for plotting $J_{sc}$, PCE, and EQE data across multiple weeks. As you collect more data each week, these snippets make it easier to combine and visualize your results without manually adding lines for each new dataset.\n",
    "\n",
    "You can copy any of these cells into your weekly Data Collection notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Adding a Time Column to Your CSV Files\n",
    "\n",
    "The $J_{sc}$/PCE CSV files you create each week need a `Time (hr)` column so you can plot values over time. The code below reads a CSV, adds the time column, and writes a new file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Update these variables for each week\n",
    "date_str = \"YYYY_MM_DD\"\n",
    "cell_id = \"###\"\n",
    "\n",
    "# Read the CSV you created with Jsc and PCE values\n",
    "# Your CSV must have columns: \"Pixel Number\", \"Jsc (mA/cm^2)\", \"PCE\"\n",
    "df = pd.read_csv(f\"{date_str}_jsc_pce_cell{cell_id}.csv\")\n",
    "\n",
    "# Set the time in hours since stressing began (update each week)\n",
    "t = 168  # <-- update this\n",
    "df[\"Time (hr)\"] = t\n",
    "\n",
    "# Write the updated DataFrame to a new CSV\n",
    "out_name = f\"{date_str}_jsc_pce_with_time_cell{cell_id}.csv\"\n",
    "df.to_csv(out_name, index=False)\n",
    "print(f\"[ok] Wrote {out_name}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## $J_{sc}$ Subplots\n",
    "\n",
    "Plot $J_{sc}$ vs. time for each pixel in a 4x2 grid. Add more CSV files to the list as you collect data each week."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load and combine data from all weeks (update file names)\n",
    "week5data = pd.read_csv(\"YYYY_MM_DD_jsc_pce_with_time_cell###.csv\")  # baseline\n",
    "week6data = pd.read_csv(\"YYYY_MM_DD_jsc_pce_with_time_cell###.csv\")  # Data Collection 1\n",
    "# Add more weeks as needed:\n",
    "# week7data = pd.read_csv(\"YYYY_MM_DD_jsc_pce_with_time_cell###.csv\")\n",
    "\n",
    "combined_df = pd.concat([week5data, week6data])\n",
    "\n",
    "# Jsc subplots\n",
    "fig, axes = plt.subplots(4, 2, figsize=(12, 16))\n",
    "axes = axes.flatten()\n",
    "\n",
    "for idx, pixel in enumerate(combined_df[\"Pixel Number\"].unique()):\n",
    "    if idx >= len(axes):\n",
    "        break\n",
    "\n",
    "    subset = combined_df[combined_df[\"Pixel Number\"] == pixel]\n",
    "\n",
    "    ax = axes[idx]\n",
    "    ax.scatter(subset[\"Time (hr)\"], subset[\"Jsc (mA/cm^2)\"], color=\"g\")\n",
    "\n",
    "    ax.set_title(f\"Pixel {pixel}\")\n",
    "    ax.set_xlabel(\"Time (hr)\")\n",
    "    ax.set_ylabel(\"Jsc (mA/cm\\u00b2)\")\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PCE Subplots\n",
    "\n",
    "Plot PCE vs. time for each pixel, using the same combined data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# PCE subplots\n",
    "fig, axes = plt.subplots(4, 2, figsize=(12, 16))\n",
    "axes = axes.flatten()\n",
    "\n",
    "for idx, pixel in enumerate(combined_df[\"Pixel Number\"].unique()):\n",
    "    if idx >= len(axes):\n",
    "        break\n",
    "\n",
    "    subset = combined_df[combined_df[\"Pixel Number\"] == pixel]\n",
    "\n",
    "    ax = axes[idx]\n",
    "    ax.scatter(subset[\"Time (hr)\"], subset[\"PCE\"], color=\"b\")\n",
    "\n",
    "    ax.set_title(f\"Pixel {pixel}\")\n",
    "    ax.set_xlabel(\"Time (hr)\")\n",
    "    ax.set_ylabel(\"PCE\")\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## EQE Subplots\n",
    "\n",
    "Compare EQE spectra across multiple weeks. This version uses a list of files and labels, making it easy to add new weeks without duplicating plot code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# List your EQE CSV files and labels (update each week)\n",
    "eqe_files = [\n",
    "    \"YYYY_MM_DD_eqe_cell###.csv\",\n",
    "    \"YYYY_MM_DD_eqe_cell###.csv\",\n",
    "    # Add more files as needed\n",
    "]\n",
    "\n",
    "labels = [\n",
    "    \"Baseline\",\n",
    "    \"Data Collection 1\",\n",
    "    # Add matching labels\n",
    "]\n",
    "\n",
    "# Load data\n",
    "weeks = []\n",
    "for lbl, f in zip(labels, eqe_files):\n",
    "    try:\n",
    "        df = pd.read_csv(f).sort_values(\"Wavelength (nm)\").reset_index(drop=True)\n",
    "        keep = [\"Wavelength (nm)\"] + [f\"eqe_pix{i}\" for i in range(1, 9)]\n",
    "        df = df[[c for c in keep if c in df.columns]]\n",
    "        weeks.append((lbl, df))\n",
    "        print(f\"[ok] Loaded {f}\")\n",
    "    except FileNotFoundError:\n",
    "        print(f\"[skip] Not found: {f}\")\n",
    "    except Exception as ex:\n",
    "        print(f\"[skip] Error reading {f}: {ex}\")\n",
    "\n",
    "if not weeks:\n",
    "    raise SystemExit(\"No valid EQE files loaded.\")\n",
    "\n",
    "# EQE subplots\n",
    "fig, axes = plt.subplots(4, 2, figsize=(12, 16))\n",
    "axes = axes.flatten()\n",
    "\n",
    "for i in range(8):\n",
    "    ax = axes[i]\n",
    "    col = f\"eqe_pix{i+1}\"\n",
    "    plotted_any = False\n",
    "\n",
    "    for lbl, df in weeks:\n",
    "        if {\"Wavelength (nm)\", col}.issubset(df.columns):\n",
    "            ax.plot(df[\"Wavelength (nm)\"], df[col], label=lbl)\n",
    "            plotted_any = True\n",
    "\n",
    "    ax.set_title(f\"Pixel {i+1}\")\n",
    "    ax.set_xlabel(\"Wavelength (nm)\")\n",
    "    ax.set_ylabel(\"EQE\")\n",
    "    if plotted_any:\n",
    "        ax.legend(loc=\"best\")\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.11.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
