Aggiunge la generazione del grafico del voltammogramma

Traccia Potential normalized/V (colonna C) contro
Current/sqrt(scan rate)/scan rate (colonna E) e salva un PNG ad alta
risoluzione per ciascun *_ultimo_ciclo.csv, con etichette degli assi in
notazione scientifica (E - E_ref, i/v^3/2). Aggiunge requirements.txt
(matplotlib) e ignora i .png generati.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-13 23:08:44 +02:00
parent 8b476a0a30
commit b5c89c75cb
3 changed files with 94 additions and 0 deletions
+2
View File
@@ -6,3 +6,5 @@ venv/
*.txt
*.csv
*.png
!requirements.txt
+91
View File
@@ -0,0 +1,91 @@
"""Genera un grafico Potenziale normalizzato vs Current/sqrt(v)/v per ogni ciclo.
Legge la colonna C (Potential normalized/V) e la colonna E
(Current/sqrt(scan rate)/scan rate) dai file *_ultimo_ciclo.csv e salva,
per ciascuno, un PNG ad alta risoluzione con lo stesso nome del CSV.
"""
import csv
import sys
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
INPUT_SUFFIX = "_ultimo_ciclo"
X_COLUMN = "Potential normalized/V"
Y_COLUMN = "Current/sqrt(scan rate)/scan rate"
X_LABEL = "$E - E_{ref}$ (V)"
Y_LABEL = r"$i \, / \, v^{3/2}$ (A$\cdot$V$^{-3/2}\cdot$s$^{3/2}$)"
def read_columns(path: Path) -> tuple[list[float], list[float]]:
with path.open("r", encoding="utf-8", newline="") as f:
reader = csv.reader(f, delimiter=";")
header = next(reader)
try:
x_idx = header.index(X_COLUMN)
y_idx = header.index(Y_COLUMN)
except ValueError as e:
raise ValueError(
f"colonna mancante ({e}); esegui prima cv_normalize_potential.py e cv_current_over_sqrt_scanrate.py"
)
x_vals, y_vals = [], []
for row in reader:
x_vals.append(float(row[x_idx].replace(",", ".")))
y_vals.append(float(row[y_idx].replace(",", ".")))
return x_vals, y_vals
def plot_file(csv_path: Path, output_path: Path) -> None:
x_vals, y_vals = read_columns(csv_path)
fig, ax = plt.subplots(figsize=(8, 6), dpi=300)
ax.plot(x_vals, y_vals, color="#1f4e79", linewidth=1.6)
ax.set_title(csv_path.stem.replace(INPUT_SUFFIX, ""), fontsize=13, fontweight="bold", pad=12)
ax.set_xlabel(X_LABEL, fontsize=11)
ax.set_ylabel(Y_LABEL, fontsize=11)
ax.axhline(0, color="black", linewidth=0.8, alpha=0.5)
ax.axvline(0, color="black", linewidth=0.8, alpha=0.5)
ax.yaxis.set_major_formatter(mticker.ScalarFormatter(useMathText=True))
ax.ticklabel_format(axis="y", style="sci", scilimits=(0, 0))
ax.grid(True, linestyle="--", linewidth=0.5, alpha=0.6)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
fig.tight_layout()
fig.savefig(output_path, dpi=300)
plt.close(fig)
def main(argv: list[str]) -> None:
folder = Path(argv[1]) if len(argv) > 1 else Path(__file__).parent
csv_files = sorted(
p for p in folder.glob("*.csv") if p.stem.endswith(INPUT_SUFFIX)
)
if not csv_files:
print(f"Nessun file *{INPUT_SUFFIX}.csv trovato in {folder}")
return
for csv_file in csv_files:
output_path = csv_file.with_suffix(".png")
try:
plot_file(csv_file, output_path)
print(f"OK {csv_file.name} -> {output_path.name}")
except ValueError as e:
print(f"SKIP {csv_file.name}: {e}")
if __name__ == "__main__":
main(sys.argv)
+1
View File
@@ -0,0 +1 @@
matplotlib