File size: 3,035 Bytes
141bacd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | """dingwall UMAP: (a) PANDA-predicted class, (b) en1 genotype."""
from pathlib import Path
import warnings
warnings.filterwarnings("ignore")
import numpy as np
import pandas as pd
import anndata as ad
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import umap
import os as _os
from pathlib import Path as _Path
PANDA_ROOT = _Path(_os.environ.get("PANDA_ROOT", str(_Path(__file__).resolve().parents[2])))
FIG = Path(str(PANDA_ROOT / "figures"))
FIG.mkdir(exist_ok=True)
CLASS_COLORS = {
"fibroblast-reticular": "#66c2a5",
"basal-IFE": "#fc8d62",
"endothelial": "#8da0cb",
"immune": "#e78ac3",
"fibroblast-papillary": "#a6d854",
"melanocyte": "#ffd92f",
"spinous": "#e5c494",
"granular": "#b3b3b3",
"HF-ORS": "#1b9e77",
"HF-DP": "#d95f02",
"HF-placode": "#7570b3",
"eccrine-duct": "#666666",
"eccrine-placode": "#000000",
}
def main():
p = ad.read_h5ad(str(PANDA_ROOT / "discovery/pan_skin/marker/50_aldrich_projections.h5ad"))
print(f"[umap] Dingwall projection shape {p.shape}", flush=True)
if "Z_projection" not in p.obsm:
print(f"[umap] no Z_projection in obsm; keys: {list(p.obsm.keys())}")
return
Z = np.asarray(p.obsm["Z_projection"])
print(f"[umap] Z shape {Z.shape}", flush=True)
print(f"[umap] fitting UMAP …", flush=True)
reducer = umap.UMAP(n_neighbors=30, min_dist=0.3, random_state=42,
metric="cosine", n_components=2)
emb = reducer.fit_transform(Z)
print(f"[umap] UMAP done, emb shape {emb.shape}", flush=True)
pred = p.obs["pred_bbse_label"] if "pred_bbse_label" in p.obs else p.obs.get("pred_label")
genotype = p.obs.get("genotype", pd.Series(index=p.obs.index, data="unknown"))
fig, axes = plt.subplots(1, 2, figsize=(14, 6))
ax = axes[0]
for cls in pred.unique():
m = pred == cls
ax.scatter(emb[m, 0], emb[m, 1], s=1.5, alpha=0.4,
c=CLASS_COLORS.get(cls, "#999999"), label=f"{cls} (n={int(m.sum())})")
ax.set_title("Dingwall (25,344 cells) — PANDA-predicted class (BBSE)")
ax.set_xlabel("UMAP 1"); ax.set_ylabel("UMAP 2")
ax.legend(bbox_to_anchor=(1.02, 1), loc="upper left", fontsize=7,
markerscale=6, frameon=False)
ax = axes[1]
gcolors = {"WT": "#2b83ba", "En1-cKO": "#d7191c", "unknown": "#999999"}
for g in ["WT", "En1-cKO"]:
m = genotype == g
ax.scatter(emb[m, 0], emb[m, 1], s=1.5, alpha=0.35,
c=gcolors[g], label=f"{g} (n={int(m.sum())})")
ax.set_title("Dingwall — En1 genotype")
ax.set_xlabel("UMAP 1"); ax.set_ylabel("UMAP 2")
ax.legend(bbox_to_anchor=(1.02, 1), loc="upper left", markerscale=6, frameon=False)
plt.tight_layout()
plt.savefig(FIG / "fig5_dingwall_umap.pdf", bbox_inches="tight")
plt.close()
print(f"[umap] wrote {FIG}/fig5_dingwall_umap.pdf")
if __name__ == "__main__":
main()
|