Upload code/plots.py
Browse files- code/plots.py +70 -0
code/plots.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
|
| 5 |
+
import matplotlib
|
| 6 |
+
|
| 7 |
+
matplotlib.use("Agg")
|
| 8 |
+
|
| 9 |
+
import matplotlib.pyplot as plt
|
| 10 |
+
import numpy as np
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def plot_reconstruction_batch(
|
| 14 |
+
path: str | Path,
|
| 15 |
+
target_loglam,
|
| 16 |
+
target_flux,
|
| 17 |
+
pred_flux,
|
| 18 |
+
loss_mask,
|
| 19 |
+
valid_patch,
|
| 20 |
+
z_true,
|
| 21 |
+
z_pred,
|
| 22 |
+
max_items: int = 4,
|
| 23 |
+
) -> None:
|
| 24 |
+
path = Path(path)
|
| 25 |
+
path.parent.mkdir(parents=True, exist_ok=True)
|
| 26 |
+
bsz = min(max_items, len(target_flux))
|
| 27 |
+
fig, axes = plt.subplots(bsz, 1, figsize=(13, 3.2 * bsz), squeeze=False)
|
| 28 |
+
for i in range(bsz):
|
| 29 |
+
ax = axes[i, 0]
|
| 30 |
+
wave = np.exp(target_loglam[i])
|
| 31 |
+
valid = valid_patch[i].astype(bool)
|
| 32 |
+
masked = loss_mask[i].astype(bool)
|
| 33 |
+
ax.plot(wave[valid], target_flux[i][valid], color="black", linewidth=1.0, label="target")
|
| 34 |
+
ax.plot(wave[valid], pred_flux[i][valid], color="#d62728", linewidth=1.0, alpha=0.9, label="recon")
|
| 35 |
+
if masked.any():
|
| 36 |
+
ax.scatter(wave[masked], target_flux[i][masked], s=8, color="#1f77b4", alpha=0.55, label="masked target")
|
| 37 |
+
ax.set_ylabel("norm flux")
|
| 38 |
+
ax.set_title(f"z true={z_true[i]:.5f} z pred={z_pred[i]:.5f}")
|
| 39 |
+
ax.grid(alpha=0.2)
|
| 40 |
+
if i == 0:
|
| 41 |
+
ax.legend(loc="best", fontsize=8)
|
| 42 |
+
axes[-1, 0].set_xlabel("wavelength Angstrom")
|
| 43 |
+
fig.tight_layout()
|
| 44 |
+
fig.savefig(path, dpi=150)
|
| 45 |
+
plt.close(fig)
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def plot_redshift_scatter(path: str | Path, y_true: np.ndarray, y_pred: np.ndarray) -> None:
|
| 49 |
+
path = Path(path)
|
| 50 |
+
path.parent.mkdir(parents=True, exist_ok=True)
|
| 51 |
+
z_true = np.expm1(y_true)
|
| 52 |
+
z_pred = np.expm1(y_pred)
|
| 53 |
+
fig, axes = plt.subplots(1, 2, figsize=(11, 4.2))
|
| 54 |
+
axes[0].scatter(z_true, z_pred, s=6, alpha=0.35)
|
| 55 |
+
lim = [float(np.nanmin(z_true)), float(np.nanmax(z_true))]
|
| 56 |
+
axes[0].plot(lim, lim, color="black", linewidth=1)
|
| 57 |
+
axes[0].set_xlabel("z true")
|
| 58 |
+
axes[0].set_ylabel("z pred")
|
| 59 |
+
axes[0].grid(alpha=0.2)
|
| 60 |
+
dz = (z_pred - z_true) / (1 + z_true)
|
| 61 |
+
axes[1].scatter(z_true, dz, s=6, alpha=0.35)
|
| 62 |
+
axes[1].axhline(0, color="black", linewidth=1)
|
| 63 |
+
axes[1].axhline(0.01, color="#d62728", linewidth=1, linestyle="--")
|
| 64 |
+
axes[1].axhline(-0.01, color="#d62728", linewidth=1, linestyle="--")
|
| 65 |
+
axes[1].set_xlabel("z true")
|
| 66 |
+
axes[1].set_ylabel("delta z / (1 + z)")
|
| 67 |
+
axes[1].grid(alpha=0.2)
|
| 68 |
+
fig.tight_layout()
|
| 69 |
+
fig.savefig(path, dpi=150)
|
| 70 |
+
plt.close(fig)
|