Tutorial 1: Stereo-Seq: MOSTA E16.5 E2S5

Analyze MOSTA E16.5 E2S5 Spatial Transcriptomics data with SpacGPA.

Data source: https://db.cngb.org/stomics/mosta/

MOSTA E16.5 E2S5 is a mouse embryo sample at embryonic day 16.5 generated with Stereo-seq.

[1]:
# Import SpacGPA and other required packages.
import SpacGPA as sg
import scanpy as sc
import matplotlib.pyplot as plt
import os

[2]:
# Set the working directory to your local path.
workdir = '..'
os.chdir(workdir)

Part 1: Gene program analysis via SpacGPA

[3]:
# Load spatial transcriptomics data.
adata = sc.read_h5ad("data/Stereo-seq/MOSTA/E16.5_E2S5.MOSTA.h5ad")
adata.var_names_make_unique()
print(adata)

AnnData object with n_obs × n_vars = 132481 × 28555
    obs: 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'annotation', 'Regulon - A1cf', 'Regulon - Agap2', 'Regulon - Alx1', 'Regulon - Alx3', 'Regulon - Arid3a', 'Regulon - Arnt', 'Regulon - Arnt2', 'Regulon - Arx', 'Regulon - Atf1', 'Regulon - Atf2', 'Regulon - Atf3', 'Regulon - Atf4', 'Regulon - Atf5', 'Regulon - Atf6b', 'Regulon - Atf7', 'Regulon - Bach2', 'Regulon - Barhl1', 'Regulon - Barhl2', 'Regulon - Barx1', 'Regulon - Barx2', 'Regulon - Bcl6', 'Regulon - Bclaf1', 'Regulon - Bdp1', 'Regulon - Bhlha15', 'Regulon - Bhlhe22', 'Regulon - Bhlhe40', 'Regulon - Bmyc', 'Regulon - Brca1', 'Regulon - Brf1', 'Regulon - Brf2', 'Regulon - Carf', 'Regulon - Cdx1', 'Regulon - Cdx2', 'Regulon - Cebpa', 'Regulon - Cebpb', 'Regulon - Cebpd', 'Regulon - Cebpe', 'Regulon - Cebpg', 'Regulon - Cenpb', 'Regulon - Chd1', 'Regulon - Ckmt1', 'Regulon - Clock', 'Regulon - Creb1', 'Regulon - Creb3', 'Regulon - Creb3l1', 'Regulon - Creb3l2', 'Regulon - Crebl2', 'Regulon - Crem', 'Regulon - Ctcf', 'Regulon - Cux1', 'Regulon - Cux2', 'Regulon - Dbp', 'Regulon - Dbx1', 'Regulon - Dlx1', 'Regulon - Dlx2', 'Regulon - Dlx3', 'Regulon - Dlx5', 'Regulon - Dlx6', 'Regulon - Dmap1', 'Regulon - Dmbx1', 'Regulon - E2f1', 'Regulon - E2f2', 'Regulon - E2f3', 'Regulon - E2f4', 'Regulon - E2f5', 'Regulon - E2f6', 'Regulon - E2f7', 'Regulon - E2f8', 'Regulon - Ebf2', 'Regulon - Ebf4', 'Regulon - Egr1', 'Regulon - Egr3', 'Regulon - Elf1', 'Regulon - Elf3', 'Regulon - Elf4', 'Regulon - Elk1', 'Regulon - Elk3', 'Regulon - Elk4', 'Regulon - Emx1', 'Regulon - Emx2', 'Regulon - En2', 'Regulon - Eomes', 'Regulon - Ep300', 'Regulon - Erg', 'Regulon - Esrra', 'Regulon - Esrrg', 'Regulon - Ets1', 'Regulon - Ets2', 'Regulon - Etv3', 'Regulon - Etv4', 'Regulon - Ezh2', 'Regulon - Fli1', 'Regulon - Fos', 'Regulon - Fosl1', 'Regulon - Fosl2', 'Regulon - Foxa1', 'Regulon - Foxa3', 'Regulon - Foxc1', 'Regulon - Foxc2', 'Regulon - Foxd1', 'Regulon - Foxd3', 'Regulon - Foxe1', 'Regulon - Foxf1', 'Regulon - Foxf2', 'Regulon - Foxj2', 'Regulon - Foxj3', 'Regulon - Foxk2', 'Regulon - Foxm1', 'Regulon - Foxn3', 'Regulon - Foxo1', 'Regulon - Foxo3', 'Regulon - Foxo4', 'Regulon - Foxo6', 'Regulon - Foxp1', 'Regulon - Foxp2', 'Regulon - Foxp4', 'Regulon - Gabpa', 'Regulon - Gata1', 'Regulon - Gata2', 'Regulon - Gata3', 'Regulon - Gata4', 'Regulon - Gata5', 'Regulon - Gata6', 'Regulon - Gbx1', 'Regulon - Gfi1b', 'Regulon - Gli1', 'Regulon - Gm10093', 'Regulon - Gm14410', 'Regulon - Gm28308', 'Regulon - Gm29609', 'Regulon - Gm45871', 'Regulon - Gpank1', 'Regulon - Grhl1', 'Regulon - Grhl2', 'Regulon - Grhl3', 'Regulon - Gsx2', 'Regulon - Gtf2b', 'Regulon - Gtf2f1', 'Regulon - Gtf2ird1', 'Regulon - Gtf3c2', 'Regulon - Hcfc1', 'Regulon - Hdac1', 'Regulon - Hdac2', 'Regulon - Hdac3', 'Regulon - Hes1', 'Regulon - Hes5', 'Regulon - Hes6', 'Regulon - Hey2', 'Regulon - Hlf', 'Regulon - Hlx', 'Regulon - Hmga2', 'Regulon - Hmgb1', 'Regulon - Hmgb3', 'Regulon - Hmgn3', 'Regulon - Hmx1', 'Regulon - Hnf4a', 'Regulon - Hnf4g', 'Regulon - Hoxa10', 'Regulon - Hoxa11', 'Regulon - Hoxa3', 'Regulon - Hoxa4', 'Regulon - Hoxa5', 'Regulon - Hoxa7', 'Regulon - Hoxa9', 'Regulon - Hoxb13', 'Regulon - Hoxb3', 'Regulon - Hoxb4', 'Regulon - Hoxb5', 'Regulon - Hoxb6', 'Regulon - Hoxb7', 'Regulon - Hoxb8', 'Regulon - Hoxb9', 'Regulon - Hoxc10', 'Regulon - Hoxc11', 'Regulon - Hoxc12', 'Regulon - Hoxc13', 'Regulon - Hoxc4', 'Regulon - Hoxc5', 'Regulon - Hoxc6', 'Regulon - Hoxc8', 'Regulon - Hoxc9', 'Regulon - Hoxd10', 'Regulon - Hoxd11', 'Regulon - Hoxd12', 'Regulon - Hoxd3', 'Regulon - Hoxd9', 'Regulon - Ikzf1', 'Regulon - Irf1', 'Regulon - Irf3', 'Regulon - Irf8', 'Regulon - Irx1', 'Regulon - Isl1', 'Regulon - Isl2', 'Regulon - Isx', 'Regulon - Jun', 'Regulon - Junb', 'Regulon - Jund', 'Regulon - Kdm5a', 'Regulon - Kdm5b', 'Regulon - Klf1', 'Regulon - Klf10', 'Regulon - Klf11', 'Regulon - Klf13', 'Regulon - Klf15', 'Regulon - Klf2', 'Regulon - Klf3', 'Regulon - Klf4', 'Regulon - Klf5', 'Regulon - Klf6', 'Regulon - Klf7', 'Regulon - Klf8', 'Regulon - Kmt2a', 'Regulon - Lbx1', 'Regulon - Lef1', 'Regulon - Lhx1', 'Regulon - Lhx2', 'Regulon - Lhx4', 'Regulon - Lhx5', 'Regulon - Lhx6', 'Regulon - Lhx8', 'Regulon - Lhx9', 'Regulon - Lmo2', 'Regulon - Lmx1a', 'Regulon - Lmx1b', 'Regulon - Lyl1', 'Regulon - Maf', 'Regulon - Mafa', 'Regulon - Mafb', 'Regulon - Mafg', 'Regulon - Mafk', 'Regulon - Max', 'Regulon - Maz', 'Regulon - Mecom', 'Regulon - Mef2a', 'Regulon - Mef2c', 'Regulon - Mef2d', 'Regulon - Meis1', 'Regulon - Meis2', 'Regulon - Mga', 'Regulon - Mios', 'Regulon - Mitf', 'Regulon - Mkx', 'Regulon - Mnx1', 'Regulon - Msc', 'Regulon - Msi2', 'Regulon - Msx2', 'Regulon - Mxi1', 'Regulon - Myb', 'Regulon - Mybl1', 'Regulon - Mybl2', 'Regulon - Myc', 'Regulon - Mycn', 'Regulon - Myf5', 'Regulon - Myf6', 'Regulon - Myod1', 'Regulon - Myog', 'Regulon - Ncor2', 'Regulon - Nelfe', 'Regulon - Neurod1', 'Regulon - Neurod2', 'Regulon - Neurog3', 'Regulon - Nfatc1', 'Regulon - Nfatc2', 'Regulon - Nfatc3', 'Regulon - Nfatc4', 'Regulon - Nfe2', 'Regulon - Nfe2l2', 'Regulon - Nfic', 'Regulon - Nfil3', 'Regulon - Nfix', 'Regulon - Nfya', 'Regulon - Nfyb', 'Regulon - Nhlh1', 'Regulon - Nkx2-1', 'Regulon - Nkx2-3', 'Regulon - Nkx2-5', 'Regulon - Nkx6-1', 'Regulon - Nkx6-2', 'Regulon - Nkx6-3', 'Regulon - Npdc1', 'Regulon - Nr1h3', 'Regulon - Nr1h4', 'Regulon - Nr1h5', 'Regulon - Nr1i3', 'Regulon - Nr2c2', 'Regulon - Nr2f2', 'Regulon - Nr2f6', 'Regulon - Nr3c1', 'Regulon - Nr5a1', 'Regulon - Nr5a2', 'Regulon - Nrf1', 'Regulon - Nucb1', 'Regulon - Olig2', 'Regulon - Onecut1', 'Regulon - Onecut2', 'Regulon - Onecut3', 'Regulon - Otp', 'Regulon - Otx2', 'Regulon - Patz1', 'Regulon - Pax5', 'Regulon - Pax6', 'Regulon - Pax7', 'Regulon - Pax8', 'Regulon - Pbx1', 'Regulon - Phf8', 'Regulon - Phox2a', 'Regulon - Phox2b', 'Regulon - Pitx1', 'Regulon - Pitx2', 'Regulon - Pitx3', 'Regulon - Pknox2', 'Regulon - Plagl1', 'Regulon - Pole4', 'Regulon - Poli', 'Regulon - Pou1f1', 'Regulon - Pou2f1', 'Regulon - Pou2f3', 'Regulon - Pou3f1', 'Regulon - Pou3f2', 'Regulon - Pou3f3', 'Regulon - Pou3f4', 'Regulon - Pou4f1', 'Regulon - Pou4f2', 'Regulon - Pou4f3', 'Regulon - Pou6f1', 'Regulon - Ppard', 'Regulon - Pparg', 'Regulon - Prdm1', 'Regulon - Prdm16', 'Regulon - Prox1', 'Regulon - Prrx1', 'Regulon - Prrx2', 'Regulon - Prrxl1', 'Regulon - Psmd12', 'Regulon - Ptf1a', 'Regulon - Rad21', 'Regulon - Rara', 'Regulon - Rarb', 'Regulon - Rbbp5', 'Regulon - Rcor1', 'Regulon - Rela', 'Regulon - Rest', 'Regulon - Rfx7', 'Regulon - Rxra', 'Regulon - Rxrg', 'Regulon - Sap30', 'Regulon - Scrt1', 'Regulon - Sf1', 'Regulon - Shox2', 'Regulon - Sin3a', 'Regulon - Sirt6', 'Regulon - Six1', 'Regulon - Six3', 'Regulon - Six4', 'Regulon - Smad1', 'Regulon - Smad4', 'Regulon - Smarca4', 'Regulon - Smarcb1', 'Regulon - Smarcc2', 'Regulon - Snai3', 'Regulon - Snd1', 'Regulon - Sox10', 'Regulon - Sox11', 'Regulon - Sox12', 'Regulon - Sox17', 'Regulon - Sox18', 'Regulon - Sox2', 'Regulon - Sox21', 'Regulon - Sox4', 'Regulon - Sox7', 'Regulon - Sox9', 'Regulon - Sp1', 'Regulon - Sp2', 'Regulon - Sp3', 'Regulon - Sp6', 'Regulon - Sp7', 'Regulon - Sp9', 'Regulon - Spi1', 'Regulon - Srebf1', 'Regulon - Srebf2', 'Regulon - Srf', 'Regulon - Stat1', 'Regulon - Stat3', 'Regulon - Stat5b', 'Regulon - Stat6', 'Regulon - Supt20', 'Regulon - Taf1', 'Regulon - Taf7', 'Regulon - Tagln2', 'Regulon - Tal1', 'Regulon - Tbl1xr1', 'Regulon - Tbp', 'Regulon - Tbpl2', 'Regulon - Tbr1', 'Regulon - Tbx15', 'Regulon - Tbx20', 'Regulon - Tbx4', 'Regulon - Tcf12', 'Regulon - Tcf7l2', 'Regulon - Tead1', 'Regulon - Tead2', 'Regulon - Tead3', 'Regulon - Tead4', 'Regulon - Tfap2a', 'Regulon - Tfap2b', 'Regulon - Tfcp2l1', 'Regulon - Tfdp1', 'Regulon - Tfdp2', 'Regulon - Tfec', 'Regulon - Tff3', 'Regulon - Tgif2', 'Regulon - Thap1', 'Regulon - Thap11', 'Regulon - Thap12', 'Regulon - Thra', 'Regulon - Tlx2', 'Regulon - Tlx3', 'Regulon - Tmem33', 'Regulon - Trim28', 'Regulon - Trp63', 'Regulon - Trp73', 'Regulon - Trps1', 'Regulon - Twist1', 'Regulon - Ube2k', 'Regulon - Ubp1', 'Regulon - Ubtf', 'Regulon - Uncx', 'Regulon - Usf1', 'Regulon - Usf2', 'Regulon - Vax2', 'Regulon - Vsx2', 'Regulon - Wt1', 'Regulon - Xbp1', 'Regulon - Xrcc4', 'Regulon - Yy1', 'Regulon - Zbtb17', 'Regulon - Zbtb2', 'Regulon - Zbtb4', 'Regulon - Zbtb7b', 'Regulon - Zeb1', 'Regulon - Zfp110', 'Regulon - Zfp143', 'Regulon - Zfp148', 'Regulon - Zfp160', 'Regulon - Zfp189', 'Regulon - Zfp217', 'Regulon - Zfp219', 'Regulon - Zfp260', 'Regulon - Zfp263', 'Regulon - Zfp319', 'Regulon - Zfp385a', 'Regulon - Zfp536', 'Regulon - Zfp597', 'Regulon - Zfp607a', 'Regulon - Zfp697', 'Regulon - Zfp729a', 'Regulon - Zfp729b', 'Regulon - Zfp74', 'Regulon - Zfp740', 'Regulon - Zfp786', 'Regulon - Zfp821', 'Regulon - Zfp941', 'Regulon - Zfp950', 'Regulon - Zic1', 'Regulon - Zic2', 'Regulon - Zkscan3', 'Regulon - Zmiz1', 'Module_1', 'Module_2', 'Module_3', 'Module_4', 'Module_5', 'Module_6', 'Module_7', 'Module_8', 'Module_9', 'Module_10', 'Module_11', 'Module_12', 'Module_13', 'Module_14', 'Module_15', 'Module_16', 'Module_17', 'Module_18', 'Module_19', 'Module_20', 'Module_21', 'Module_22', 'Module_23', 'Module_24', 'Module_25', 'Module_26', 'Module_27', 'Module_28', 'Module_29', 'Module_30', 'Module_31', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_500_genes'
    var: 'n_cells', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'Regulon - A1cf', 'Regulon - Agap2', 'Regulon - Atf1', 'Regulon - Atf2', 'Regulon - Atf3', 'Regulon - Atf4', 'Regulon - Atf6b', 'Regulon - Bach2', 'Regulon - Barhl1', 'Regulon - Bcl6', 'Regulon - Bclaf1', 'Regulon - Bdp1', 'Regulon - Brca1', 'Regulon - Carf', 'Regulon - Cdx1', 'Regulon - Cdx2', 'Regulon - Cebpa', 'Regulon - Cebpb', 'Regulon - Cebpe', 'Regulon - Cebpg', 'Regulon - Cenpb', 'Regulon - Creb3l2', 'Regulon - Cux2', 'Regulon - Dbx1', 'Regulon - Dlx1', 'Regulon - Dlx2', 'Regulon - Dlx3', 'Regulon - Dlx5', 'Regulon - Dlx6', 'Regulon - Dmbx1', 'Regulon - E2f1', 'Regulon - E2f2', 'Regulon - E2f3', 'Regulon - E2f4', 'Regulon - E2f5', 'Regulon - E2f7', 'Regulon - E2f8', 'Regulon - Elk3', 'Regulon - Elk4', 'Regulon - Emx1', 'Regulon - Emx2', 'Regulon - En2', 'Regulon - Ep300', 'Regulon - Erg', 'Regulon - Esrra', 'Regulon - Esrrg', 'Regulon - Ets1', 'Regulon - Ets2', 'Regulon - Fli1', 'Regulon - Fos', 'Regulon - Fosl2', 'Regulon - Foxa1', 'Regulon - Foxa3', 'Regulon - Foxc1', 'Regulon - Foxf1', 'Regulon - Foxf2', 'Regulon - Foxm1', 'Regulon - Foxo1', 'Regulon - Foxo3', 'Regulon - Foxo6', 'Regulon - Foxp1', 'Regulon - Foxp4', 'Regulon - Gabpa', 'Regulon - Gata1', 'Regulon - Gata2', 'Regulon - Gata3', 'Regulon - Gata4', 'Regulon - Gata5', 'Regulon - Gata6', 'Regulon - Gli1', 'Regulon - Gm14410', 'Regulon - Gm29609', 'Regulon - Grhl1', 'Regulon - Grhl2', 'Regulon - Grhl3', 'Regulon - Gtf2b', 'Regulon - Gtf2f1', 'Regulon - Gtf2ird1', 'Regulon - Gtf3c2', 'Regulon - Hdac2', 'Regulon - Hdac3', 'Regulon - Hes1', 'Regulon - Hlx', 'Regulon - Hmga2', 'Regulon - Hmx1', 'Regulon - Hnf4a', 'Regulon - Hnf4g', 'Regulon - Hoxa10', 'Regulon - Hoxa3', 'Regulon - Hoxa4', 'Regulon - Hoxa5', 'Regulon - Hoxa7', 'Regulon - Hoxa9', 'Regulon - Hoxb3', 'Regulon - Hoxb5', 'Regulon - Hoxb6', 'Regulon - Hoxb7', 'Regulon - Hoxb9', 'Regulon - Hoxc10', 'Regulon - Hoxc13', 'Regulon - Hoxc6', 'Regulon - Hoxc9', 'Regulon - Hoxd10', 'Regulon - Hoxd11', 'Regulon - Hoxd12', 'Regulon - Hoxd9', 'Regulon - Ikzf1', 'Regulon - Irf1', 'Regulon - Irf3', 'Regulon - Irf8', 'Regulon - Irx1', 'Regulon - Isl1', 'Regulon - Isl2', 'Regulon - Isx', 'Regulon - Junb', 'Regulon - Jund', 'Regulon - Kdm5b', 'Regulon - Klf15', 'Regulon - Klf2', 'Regulon - Klf3', 'Regulon - Klf4', 'Regulon - Klf5', 'Regulon - Klf6', 'Regulon - Klf7', 'Regulon - Kmt2a', 'Regulon - Lef1', 'Regulon - Lhx2', 'Regulon - Lhx5', 'Regulon - Lhx9', 'Regulon - Lmx1a', 'Regulon - Lmx1b', 'Regulon - Maf', 'Regulon - Mafg', 'Regulon - Mafk', 'Regulon - Max', 'Regulon - Mecom', 'Regulon - Mef2a', 'Regulon - Mef2c', 'Regulon - Mef2d', 'Regulon - Meis2', 'Regulon - Mios', 'Regulon - Msc', 'Regulon - Msx2', 'Regulon - Myb', 'Regulon - Mybl2', 'Regulon - Myc', 'Regulon - Mycn', 'Regulon - Myf5', 'Regulon - Myf6', 'Regulon - Myod1', 'Regulon - Myog', 'Regulon - Ncor2', 'Regulon - Neurod1', 'Regulon - Nfatc1', 'Regulon - Nfatc3', 'Regulon - Nfatc4', 'Regulon - Nfe2', 'Regulon - Nfe2l2', 'Regulon - Nfic', 'Regulon - Nkx2-1', 'Regulon - Nkx6-1', 'Regulon - Nkx6-2', 'Regulon - Npdc1', 'Regulon - Nr1h3', 'Regulon - Nr1h4', 'Regulon - Nr5a1', 'Regulon - Nr5a2', 'Regulon - Nrf1', 'Regulon - Nucb1', 'Regulon - Onecut1', 'Regulon - Onecut2', 'Regulon - Onecut3', 'Regulon - Otx2', 'Regulon - Pax6', 'Regulon - Pbx1', 'Regulon - Phox2a', 'Regulon - Phox2b', 'Regulon - Pitx2', 'Regulon - Pitx3', 'Regulon - Pknox2', 'Regulon - Poli', 'Regulon - Pou3f3', 'Regulon - Pou3f4', 'Regulon - Pou4f3', 'Regulon - Pou6f1', 'Regulon - Prox1', 'Regulon - Ptf1a', 'Regulon - Rara', 'Regulon - Rarb', 'Regulon - Rela', 'Regulon - Rxra', 'Regulon - Rxrg', 'Regulon - Sap30', 'Regulon - Scrt1', 'Regulon - Sf1', 'Regulon - Shox2', 'Regulon - Six1', 'Regulon - Six3', 'Regulon - Six4', 'Regulon - Smad1', 'Regulon - Smad4', 'Regulon - Smarca4', 'Regulon - Smarcc2', 'Regulon - Snd1', 'Regulon - Sox10', 'Regulon - Sox11', 'Regulon - Sox12', 'Regulon - Sox17', 'Regulon - Sox2', 'Regulon - Sox21', 'Regulon - Sox4', 'Regulon - Sox7', 'Regulon - Sox9', 'Regulon - Sp1', 'Regulon - Sp7', 'Regulon - Spi1', 'Regulon - Srebf2', 'Regulon - Srf', 'Regulon - Stat3', 'Regulon - Stat5b', 'Regulon - Stat6', 'Regulon - Taf1', 'Regulon - Tagln2', 'Regulon - Tal1', 'Regulon - Tbp', 'Regulon - Tbr1', 'Regulon - Tbx20', 'Regulon - Tcf12', 'Regulon - Tcf7l2', 'Regulon - Tead1', 'Regulon - Tead2', 'Regulon - Tead3', 'Regulon - Tead4', 'Regulon - Tfap2a', 'Regulon - Tfcp2l1', 'Regulon - Tfdp1', 'Regulon - Tfdp2', 'Regulon - Tff3', 'Regulon - Thap11', 'Regulon - Thap12', 'Regulon - Trp63', 'Regulon - Twist1', 'Regulon - Ube2k', 'Regulon - Usf1', 'Regulon - Xbp1', 'Regulon - Xrcc4', 'Regulon - Yy1', 'Regulon - Zbtb2', 'Regulon - Zbtb4', 'Regulon - Zfp143', 'Regulon - Zfp189', 'Regulon - Zfp217', 'Regulon - Zfp260', 'Regulon - Zfp319', 'Regulon - Zfp385a', 'Regulon - Zfp536', 'Regulon - Zfp607a', 'Regulon - Zfp697', 'Regulon - Zfp729a', 'Regulon - Zfp729b', 'Regulon - Zfp740', 'Regulon - Zfp821', 'Regulon - Zic1', 'Module_1', 'Module_10', 'Module_11', 'Module_12', 'Module_13', 'Module_14', 'Module_15', 'Module_16', 'Module_17', 'Module_18', 'Module_19', 'Module_2', 'Module_20', 'Module_21', 'Module_22', 'Module_23', 'Module_24', 'Module_25', 'Module_26', 'Module_27', 'Module_28', 'Module_29', 'Module_3', 'Module_30', 'Module_31', 'Module_4', 'Module_5', 'Module_6', 'Module_7', 'Module_8', 'Module_9'
    uns: 'annotation_colors'
    obsm: 'spatial'
    varm: 'PCs'
    layers: 'count'
[4]:
# Preprocessing: use raw counts from layers['count'], then library-size normalize and log1p-transform.
adata.X = adata.layers['count']
sc.pp.normalize_total(adata, target_sum = 1e4)
sc.pp.log1p(adata)
sc.pp.filter_cells(adata, min_genes = 200)
sc.pp.filter_genes(adata, min_cells = 10)
print(adata.X.shape)

(130944, 25068)
[5]:
# Construct the co-expression network using SpacGPA (Gaussian graphical model).
ggm = sg.create_ggm(adata, project_name = "E16.5_E2S5")

Please Normalize The Expression Matrix Before Running!
Loading Data.

Running all calculations on GPU (if available).
Using single precision (float32) for all calculations.
Using chunk size of 5000 for efficient computation

Computing the number of cells co-expressing each gene pair...
Computing covariance matrix...
Computing Pearson correlation matrix...

Calculating partial correlations in 15711 iterations.
Number of genes randomly selected in each iteration: 2000
Iteration: 15711/15711, Avg loop time: 0.0387 s, Elapsed time: 10.55 min, Estimated time left: 0.00 min.
All iterations completed.

Performing FDR control...
Randomly redistribute the expression distribution of input genes...

Calculate correlation between genes after redistribution...

Computing the number of cells co-expressing each gene pair...
Computing covariance matrix...
Computing Pearson correlation matrix...

Calculating partial correlations in 15711 iterations.
Number of genes randomly selected in each iteration: 2000
Iteration: 15711/15711, Avg loop time: 0.0391 s, Elapsed time: 10.53 min, Estimated time left: 0.00 min.
All iterations completed.

Summarizing the FDR Statistics...
FDR control completed.
Current Pcor threshold: 0.020
Minimum Pcor threshold with FDR <= 0.05: 0.012
FDR at pcor=0.02: 1.65e-04

Task completed. Resources released.
[6]:
# Show statistically significant co-expression gene pairs.
print(ggm.SigEdges.head(5))

     GeneA    GeneB      Pcor  SamplingTime         r  Cell_num_A  Cell_num_B  \
0  Gm42418  Gm26561  0.161319           102  0.692325      130944      126654
1     Nnat   Marcks  0.021694            89  0.165198       93205       90285
2     Nrep     Nnat  0.022605           106  0.221623       86082       93205
3    Rpl18   Rpl13a  0.033076           118  0.159847      113324      126615
4    Rpl19   Rpl13a  0.023570           126  0.132455       93794      126615

   Cell_num_coexpressed     Project
0                126654  E16.5_E2S5
1                 68132  E16.5_E2S5
2                 65409  E16.5_E2S5
3                110812  E16.5_E2S5
4                 92034  E16.5_E2S5
[7]:
# Identify gene programs using the MCL-Hub algorithm (set inflation to 2).
ggm.find_modules(method = 'mcl-hub', inflation = 2)


Find modules using MCL-Hub...
Current Pcor: 0.02
Total significantly co-expressed gene pairs: 60459
Iteration: 38, Max change: 0.00000000
Converged at iteration 38.

2 modules were removed due to their linear or radial topology structure out of 76 modules.
[8]:
# Inspect the top 5 identified gene programs.
print(ggm.modules_summary.head(5))

  module_id  size  num_genes_degree_ge_2  \
0        M1   312                    255
1        M2   264                    241
2        M3   261                    210
3        M4   236                    188
4        M5   203                    157

                                           all_genes
0  Ttn, Neb, Myl1, Myh8, Gm28653, Tceal7, Tnnt3, ...
1  Dmkn, S100a14, Perp, Krt1, Sfn, Asprv1, Krt19,...
2  Apoa2, Gm45774, Afp, Apoa1, Mt2, Car2, Mt1, Rb...
3  Col3a1, Col1a2, Col1a1, Sparc, Lgals1, Postn, ...
4  Mapt, Ina, Tubb3, Nnat, Crmp1, Stmn2, Tuba1a, ...
[9]:
# Visualize the subnetwork of program M1 (top 30 genes by degree/connectivity for readability).
ggm.module_network_plot(module_id = 'M1', seed = 2)
# Fix layout randomness for reproducibility via set seed.
../_images/tutorials_Tutorial_1_Stereo-seq_MOSTA_E16_5_E2S5_11_0.png
[10]:
# Gene Ontology (GO) enrichment analysis with BH FDR control and p-value threshold 0.05.
ggm.go_enrichment_analysis(species = 'mouse', padjust_method = "BH", pvalue_cutoff = 0.05)


Reading GO term information for |mouse|...

Start GO enrichment analysis ...
Found 175 significant enriched GO terms in M74
GO enrichment analysis completed. Found 19447 significant enriched GO terms total.
[11]:
# Visualize top enriched GO terms for programs M1–M5.
ggm.module_go_enrichment_plot(shown_modules = ['M1', 'M2', 'M3', 'M4', 'M5'], go_per_module = 1)
../_images/tutorials_Tutorial_1_Stereo-seq_MOSTA_E16_5_E2S5_13_0.png
[12]:
# Mammalian Phenotype (MP) Ontology enrichment analysis with BH FDR control and p-value threshold 0.05.
ggm.mp_enrichment_analysis(species = 'mouse', padjust_method = "BH", pvalue_cutoff = 0.05)


Reading MP term information for |mouse|...

Start MP enrichment analysis ...
Found 280 significant enriched MP terms in M74
MP enrichment analysis completed. Found 12480 significant enriched MP terms total.
[13]:
# Visualize top enriched MP terms for programs M1–M5.
ggm.module_mp_enrichment_plot(shown_modules = ['M1', 'M2', 'M3', 'M4', 'M5'], mp_per_module = 1)
../_images/tutorials_Tutorial_1_Stereo-seq_MOSTA_E16_5_E2S5_15_0.png
[14]:
# Visualize the M1 network with nodes highlighted by a selected GO or MP term ID.
print(ggm.go_enrichment.iloc[0, :6])
ggm.module_network_plot(module_id = 'M1', highlight_anno = "GO:0030016", seed = 2)

module_id                      M1
module_size                   312
go_rank                         1
go_id                  GO:0030016
go_category    cellular_component
go_term                 myofibril
Name: 0, dtype: object
../_images/tutorials_Tutorial_1_Stereo-seq_MOSTA_E16_5_E2S5_16_1.png
[15]:
# The short name of Ontology term also works when highlighting (e.g., "muscle phenotype" for MP:0005369).
print(ggm.mp_enrichment.iloc[0, :5])
ggm.module_network_plot(module_id = 'M1', highlight_anno = "muscle phenotype", seed = 2)

module_id                    M1
module_size                 312
mp_rank                       1
mp_id                MP:0005369
mp_term        muscle phenotype
Name: 0, dtype: object
../_images/tutorials_Tutorial_1_Stereo-seq_MOSTA_E16_5_E2S5_17_1.png
[16]:
# Print a summary of the GGM analysis.
print(ggm)

View of ggm object: E16.5_E2S5
MetaInfo:
  Gene Number: 25068
  Sample Number: 130944
  Pcor Threshold: 0.02

Results:
  SigEdges: DataFrame with 60459 significant gene pairs
  modules: 74 modules with 4923 genes
  modules_summary: DataFrame with 74 rows
  FDR: Exists

[17]:
# Save the GGM object to HDF5 for later reuse.
sg.save_ggm(ggm, "data/MOSTA_E16.5_E2S5.ggm.h5")
# Then you can reload it via:
# ggm = sg.load_ggm("data/MOSTA_E16.5_E2S5.ggm.h5")

[18]:
# You can also save those results (e.g., modules, GO/MP enrichment) to CSV files.
ggm.modules.to_csv('data/MOSTA_E16.5_E2S5_modules.csv')
ggm.modules_summary.to_csv('data/MOSTA_E16.5_E2S5_modules_summary.csv')
ggm.go_enrichment.to_csv('data/MOSTA_E16.5_E2S5_go_enrichment.csv')
ggm.mp_enrichment.to_csv('data/MOSTA_E16.5_E2S5_mp_enrichment.csv')
# Which can lead to further downstream analyses with other tools.

Part 2: Spot annotation based on program expression

[ ]:
# Compute per-spot expression scores of each gene program.
sg.calculate_module_expression(adata, ggm)


Calculating module expression using top 30 genes...

Calculating gene weights based on degree...
Storing module information in adata.uns['module_info']...

Assigning colors to 74 modules...

Total 74 modules' average expression calculated and stored in adata.obs and adata.obsm
[20]:
# Visualize the spatial distribution of the top 20 program-expression scores.
plt.rcParams["figure.figsize"] = (7, 7)
program_list = ggm.modules_summary['module_id'] + '_exp'
sc.pl.spatial(adata, spot_size = 2, color = program_list[:20], cmap = 'RdYlBu_r', ncols = 4)

../_images/tutorials_Tutorial_1_Stereo-seq_MOSTA_E16_5_E2S5_23_0.png
[21]:
# Compute pairwise program similarity and plot the correlation heatmap with dendrograms.
sg.module_similarity_plot(adata, ggm_key = 'ggm', corr_method = 'pearson', heatmap_metric = 'correlation',
                          fig_height = 20, fig_width = 21, dendrogram_height = 0.1, dendrogram_space = 0.05, return_summary = False)

../_images/tutorials_Tutorial_1_Stereo-seq_MOSTA_E16_5_E2S5_24_0.png
[22]:
# Assign spot-level annotations via Gaussian Mixture Models (GMMs) based on program expression.
sg.calculate_gmm_annotations(adata, ggm_key = 'ggm')

# NOTE — OpenBLAS warning explanation & fix:
# If you see: "OpenBLAS warning: precompiled NUM_THREADS exceeded, adding auxiliary array for thread metadata",
# it means your OpenBLAS was compiled with a smaller thread cap than your machine exposes.
# This is harmless but noisy and may slightly impact performance.
# Workaround: limit BLAS threads at the VERY TOP of the pipeline, BEFORE importing any libraries:
#   import os
#   os.environ["OPENBLAS_NUM_THREADS"] = "32"   # choose a value ≤ the limit mentioned in the warning (e.g., 64)

M1 processed successfully, annotated cells: 13745
M2 processed successfully, annotated cells: 8810
M3 processed successfully, annotated cells: 11143
M4 processed successfully, annotated cells: 29069
M5 processed successfully, annotated cells: 26404
M6 processed successfully, annotated cells: 1833
M7 processed successfully, annotated cells: 4039
M8 processed successfully, annotated cells: 5620
M9 processed successfully, annotated cells: 7156
M10 processed successfully, annotated cells: 389
M11 processed successfully, annotated cells: 22200
M12 processed successfully, annotated cells: 3678
M13 processed successfully, annotated cells: 2236
M14 processed successfully, annotated cells: 6027
M15 processed successfully, annotated cells: 3465
M16 processed successfully, annotated cells: 681
M17 processed successfully, annotated cells: 100930
M18 processed successfully, annotated cells: 4764
M19 processed successfully, annotated cells: 2247
M20 processed successfully, annotated cells: 715
M21 processed successfully, annotated cells: 6175
M22 processed successfully, annotated cells: 4163
M23 processed successfully, annotated cells: 31540
M24 processed, failed: no_positive_cells
M25 processed successfully, annotated cells: 39774
M26 processed successfully, annotated cells: 321
M27 processed successfully, annotated cells: 572
M28 processed successfully, annotated cells: 387
M29 processed successfully, annotated cells: 4591
M30 processed successfully, annotated cells: 3345
M31 processed successfully, annotated cells: 11327
M32 processed, failed: no_positive_cells
M33 processed successfully, annotated cells: 5433
M34 processed successfully, annotated cells: 413
M35 processed successfully, annotated cells: 3980
M36 processed successfully, annotated cells: 5741
M37 processed successfully, annotated cells: 1921
M38 processed successfully, annotated cells: 27751
M39 processed successfully, annotated cells: 2887
M40 processed successfully, annotated cells: 673
M41 processed successfully, annotated cells: 3959
M42 processed successfully, annotated cells: 2574
M43 processed successfully, annotated cells: 1482
M44 processed successfully, annotated cells: 3785
M45 processed successfully, annotated cells: 10361
M46 processed successfully, annotated cells: 31543
M47 processed successfully, annotated cells: 3148
M48 processed successfully, annotated cells: 1765
M49 processed successfully, annotated cells: 11355
M50 processed successfully, annotated cells: 10740
M51 processed successfully, annotated cells: 2813
M52 processed successfully, annotated cells: 15519
M53 processed successfully, annotated cells: 1219
M54 processed successfully, annotated cells: 23032
M55 processed successfully, annotated cells: 1611
M56 processed successfully, annotated cells: 3761
M57 processed successfully, annotated cells: 70147
M58 processed successfully, annotated cells: 3873
M59 processed successfully, annotated cells: 2110
M60 processed, failed: no_positive_cells
M61 processed successfully, annotated cells: 940
M62 processed successfully, annotated cells: 1263
M63 processed successfully, annotated cells: 487
M64 processed successfully, annotated cells: 1697
M65 processed successfully, annotated cells: 4056
M66 processed successfully, annotated cells: 3781
M67 processed successfully, annotated cells: 27387
M68 processed successfully, annotated cells: 1735
M69 processed successfully, annotated cells: 2755
M70 processed successfully, annotated cells: 1647
M71 processed, failed: no_positive_cells
M72 processed, failed: no_positive_cells
M73 processed successfully, annotated cells: 7706
M74 processed successfully, annotated cells: 67
[23]:
# Optionally smooth the annotations using spatial k-NN (on the 'spatial' embedding).
sg.smooth_annotations(adata, ggm_key = 'ggm', embedding_key = 'spatial', k_neighbors = 24)

M1 processed. remain cells: 15630
M2 processed. remain cells: 10424
M3 processed. remain cells: 11557
M4 processed. remain cells: 34596
M5 processed. remain cells: 27570
M6 processed. remain cells: 1948
M7 processed. remain cells: 4309
M8 processed. remain cells: 5956
M9 processed. remain cells: 7937
M10 processed. remain cells: 367
M11 processed. remain cells: 24731
M12 processed. remain cells: 2898
M13 processed. remain cells: 2353
M14 processed. remain cells: 5628
M15 processed. remain cells: 3635
M16 processed. remain cells: 551
M17 processed. remain cells: 117300
M18 processed. remain cells: 5048
M19 processed. remain cells: 2496
M20 processed. remain cells: 691
M21 processed. remain cells: 5599
M22 processed. remain cells: 4517
M23 processed. remain cells: 39330
M24 processed. remain cells: 0
M25 processed. remain cells: 43532
M26 processed. remain cells: 289
M27 processed. remain cells: 468
M28 processed. remain cells: 366
M29 processed. remain cells: 4961
M30 processed. remain cells: 3186
M31 processed. remain cells: 10557
M32 processed. remain cells: 0
M33 processed. remain cells: 4478
M34 processed. remain cells: 318
M35 processed. remain cells: 4112
M36 processed. remain cells: 5703
M37 processed. remain cells: 1648
M38 processed. remain cells: 29962
M39 processed. remain cells: 2526
M40 processed. remain cells: 744
M41 processed. remain cells: 3988
M42 processed. remain cells: 2633
M43 processed. remain cells: 922
M44 processed. remain cells: 2693
M45 processed. remain cells: 12318
M46 processed. remain cells: 38055
M47 processed. remain cells: 3087
M48 processed. remain cells: 1740
M49 processed. remain cells: 10805
M50 processed. remain cells: 9909
M51 processed. remain cells: 2594
M52 processed. remain cells: 14936
M53 processed. remain cells: 622
M54 processed. remain cells: 25096
M55 processed. remain cells: 899
M56 processed. remain cells: 2794
M57 processed. remain cells: 88283
M58 processed. remain cells: 3381
M59 processed. remain cells: 1083
M60 processed. remain cells: 0
M61 processed. remain cells: 739
M62 processed. remain cells: 594
M63 processed. remain cells: 290
M64 processed. remain cells: 768
M65 processed. remain cells: 2886
M66 processed. remain cells: 3986
M67 processed. remain cells: 30896
M68 processed. remain cells: 1449
M69 processed. remain cells: 1796
M70 processed. remain cells: 939
M71 processed. remain cells: 0
M72 processed. remain cells: 0
M73 processed. remain cells: 7262
M74 processed. remain cells: 41

Annotation smoothing completed. Results stored in adata.obs.

[24]:
# Display smoothed annotations for the top 20 programs.
# If smoothing is skipped, use 'M1_anno' … 'M20_anno' instead.
plt.rcParams["figure.figsize"] = (7, 7)
program_list = ggm.modules_summary['module_id'] + '_anno_smooth'
sc.pl.spatial(adata, spot_size = 2, color = program_list[:20], legend_loc = None, ncols = 4)
# Where the blue nodes indicate the spots annotated by the program, and gray nodes are unassigned.

../_images/tutorials_Tutorial_1_Stereo-seq_MOSTA_E16_5_E2S5_27_0.png
[25]:
# Summarize program-expression across the existing annotation categories as a dot plot.
sg.module_dot_plot(adata, ggm_key = 'ggm', groupby = 'annotation', scale = True,
                   dendrogram_height = 0.1, dendrogram_space = 0.2, fig_width = 24, axis_fontsize = 10)

../_images/tutorials_Tutorial_1_Stereo-seq_MOSTA_E16_5_E2S5_28_0.png
[26]:
# Integrate multiple program-derived annotations into a single label set via sg.integrate_annotations.
sg.integrate_annotations(adata, ggm_key = 'ggm', neighbor_similarity_ratio = 0.6, result_anno = 'ggm_annotation')
# Here we integrate all programs as an example. You can specify a subset of programs via the 'modules_used' parameter.


Calculating 24 nearest neighbors for each cell based on spatial embedding...


125430 of total 130944 cells have multiple annotations. Among them,
    16450 cells are resolved by neighbors.
    108980 cells are resolved by expression score.

Integrated annotation stored in adata.obs['ggm_annotation'].

[27]:
# Visualize the integrated annotation and compare it to the existing annotation.
plt.rcParams["figure.figsize"] = (3, 6)
sc.pl.spatial(adata, spot_size = 2, color = ['ggm_annotation'], frameon = False, title = 'Integrated annotation')
plt.rcParams["figure.figsize"] = (3, 6)
sc.pl.spatial(adata, spot_size = 2, color = ['annotation'], frameon = False, title = 'Original annotation')

../_images/tutorials_Tutorial_1_Stereo-seq_MOSTA_E16_5_E2S5_30_0.png
../_images/tutorials_Tutorial_1_Stereo-seq_MOSTA_E16_5_E2S5_30_1.png
[28]:
# Save the annotated AnnData object.
adata.write("data/MOSTA_E16.5_E2S5_ggm_anno.h5ad")