Upstream Steps
This Notebook
Metacell calculation by SEACells (following this tutorial)
import os
import sys
import numpy as np
import pandas as pd
import scanpy as sc
import pickle
#Plotting
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
#utils
#import ipynbname
from datetime import datetime
# SeaCell
import SEACells
#import custom functions
sys.path.append('../')
import functions as fn
# Some plotting aesthetics
%matplotlib inline
sns.set_style('ticks')
matplotlib.rcParams['figure.figsize'] = [3.5, 3.5]
matplotlib.rcParams['figure.dpi'] = 100
print("Scanpy version: ", sc.__version__)
print("Pandas version: ", pd.__version__)
print("SEACell version: ", SEACells.__version__)
Scanpy version: 1.10.2 Pandas version: 2.2.2 SEACell version: 0.3.3
sc.settings.verbosity = 3
sc.settings.set_figure_params(dpi=80)
input_file = '../../../../DataDir/ExternalData/SingleCellData/Wang_ITrimester_adata.h5ad'
output_file = '../../../../DataDir/ExternalData/SingleCellData/Wang_ITrimester_adataMetacells.h5ad'
print(datetime.now())
2026-03-11 12:28:25.280218
adata = sc.read(input_file)
adata
AnnData object with n_obs × n_vars = 23137 × 20266
obs: 'Auth_Sample_ID', 'Auth_Estimated_postconceptional_age_in_days', 'Auth_Group', 'Auth_Region', 'Auth_nCount_RNA', 'Auth_nFeature_RNA', 'Auth_ATAC_fragments_in_peaks', 'Auth_Scrublet_doublet_score', 'Auth_S.Score', 'Auth_G2M.Score', 'Auth_Class', 'Auth_Subclass', 'Auth_Type_updated', 'Auth_Cluster', 'Auth_cell_type_ontology_term_id', 'Auth_development_stage_ontology_term_id', 'Auth_donor_id', 'Auth_cell_type', 'Auth_sex', 'Auth_tissue', 'Auth_self_reported_ethnicity', 'Auth_development_stage', 'dataset_id', 'sample_id', 'age', 'stage', 'cell_label', 'brain_region', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'total_counts_mito', 'log1p_total_counts_mito', 'pct_counts_mito', 'total_counts_ribo', 'log1p_total_counts_ribo', 'pct_counts_ribo', 'log1p_gene_UMI_ratio', 'n_genes', 'n_counts', 'Leiden_02', 'Leiden_04', 'Leiden_06', 'Leiden_Sel'
var: 'gene_name', 'feature_is_filtered', 'feature_name', 'feature_length', 'feature_type', 'EnsembleCode', 'mito', 'ribo', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'n_cells', 'highly_variable', 'means', 'dispersions', 'dispersions_norm', 'highly_variable_nbatches', 'highly_variable_intersection'
uns: 'Auth_Group_colors', 'Leiden_02', 'Leiden_02_colors', 'Leiden_04', 'Leiden_04_colors', 'Leiden_06', 'Leiden_06_colors', 'Leiden_Sel_colors', 'age_colors', 'brain_region_colors', 'cell_label_colors', 'diffmap_evals', 'draw_graph', 'harmony', 'hvg', 'log1p', 'pca', 'sample_id_colors', 'umap'
obsm: 'X_draw_graph_fa_harmony', 'X_pca', 'X_pca_harmony', 'X_umap_harmony', 'X_umap_nocorr'
varm: 'PCs'
layers: 'counts', 'lognorm'
obsp: 'harmony_connectivities', 'harmony_distances', 'pca_connectivities', 'pca_distances'
adata.obsm
AxisArrays with keys: X_draw_graph_fa_harmony, X_pca, X_pca_harmony, X_umap_harmony, X_umap_nocorr
adata.X
<Compressed Sparse Row sparse matrix of dtype 'float32' with 56309487 stored elements and shape (23137, 20266)>
print(adata.X[40:45, 40:45])
<Compressed Sparse Row sparse matrix of dtype 'float32' with 1 stored elements and shape (5, 5)> Coords Values (0, 4) 1.2090129852294922
adata.layers['counts']
<Compressed Sparse Row sparse matrix of dtype 'uint16' with 56309487 stored elements and shape (23137, 20266)>
print(adata.layers['counts'][40:45, 40:45])
<Compressed Sparse Row sparse matrix of dtype 'uint16' with 1 stored elements and shape (5, 5)> Coords Values (0, 4) 1
sc.pl.scatter(adata, basis='umap_nocorr', color=['sample_id', 'brain_region', 'cell_label'], frameon=False)
sc.pl.scatter(adata, basis='pca_harmony', color=['sample_id', 'brain_region', 'cell_label'], frameon=False)
sc.pl.scatter(adata, basis='umap_harmony', color=['sample_id', 'brain_region', 'cell_label'], frameon=False)
adata.obs.head(3)
| Auth_Sample_ID | Auth_Estimated_postconceptional_age_in_days | Auth_Group | Auth_Region | Auth_nCount_RNA | Auth_nFeature_RNA | Auth_ATAC_fragments_in_peaks | Auth_Scrublet_doublet_score | Auth_S.Score | Auth_G2M.Score | ... | total_counts_ribo | log1p_total_counts_ribo | pct_counts_ribo | log1p_gene_UMI_ratio | n_genes | n_counts | Leiden_02 | Leiden_04 | Leiden_06 | Leiden_Sel | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| HDBR-14584-CTX_AAACAGCCATAAGCAA-1 | HDBR-14584-CTX | 60 | First_trimester | General | 3095 | 1510 | 1173 | 0.022056 | -0.163720 | -0.239870 | ... | 131 | 4.882802 | 4.232633 | 0.397355 | 1510 | 3095 | 2 | 1 | 1 | 1 |
| HDBR-14584-CTX_AAACAGCCATCCCTCA-1 | HDBR-14584-CTX | 60 | First_trimester | General | 3508 | 1901 | 2148 | 0.047426 | -0.124941 | -0.279074 | ... | 189 | 5.247024 | 5.396916 | 0.433250 | 1899 | 3502 | 6 | 8 | 5 | 8 |
| HDBR-14584-CTX_AAACAGCCATTAGGTT-1 | HDBR-14584-CTX | 60 | First_trimester | General | 4783 | 2187 | 3382 | 0.094412 | -0.099038 | -0.237593 | ... | 235 | 5.463832 | 4.913234 | 0.376547 | 2187 | 4783 | 5 | 3 | 8 | 3 |
3 rows × 45 columns
Normalization, log-transformation, HVG and dimensionality reduction have been already performed.
We follow the workflow described in the SEACells tutorial
Parameters to be defined:
We then employ the SEACells.core.SEACells function to initialize the model.
## Core parameters
n_SEACells = round(adata.n_obs/75)
print(n_SEACells)
build_kernel_on = 'X_pca_harmony' # key in ad.obsm to use for computing metacells
# This would be replaced by 'X_svd' for ATAC data
## Additional parameters
n_waypoint_eigs = 10 # Number of eigenvalues to consider when initializing metacells
308
#help(SEACells.core.SEACells)
model = SEACells.core.SEACells(adata,
build_kernel_on=build_kernel_on,
n_SEACells=n_SEACells,
n_waypoint_eigs=n_waypoint_eigs,
convergence_epsilon = 1e-5,
use_gpu=True)
Welcome to SEACells GPU!
construct_kernel_matrix function constructs the kernel matrix from data matrix using PCA/SVD and nearest neighbors. Key parameters are:
model.construct_kernel_matrix(n_neighbors=20)
M = model.kernel_matrix
Computing kNN graph using scanpy NN ...
computing neighbors
finished: added to `.uns['neighbors']`
`.obsp['distances']`, distances for each pair of neighbors
`.obsp['connectivities']`, weighted adjacency matrix (0:00:27)
Computing radius for adaptive bandwidth kernel...
0%| | 0/23137 [00:00<?, ?it/s]
Making graph symmetric... Parameter graph_construction = union being used to build KNN graph... Computing RBF kernel...
0%| | 0/23137 [00:00<?, ?it/s]
Building similarity LIL matrix...
0%| | 0/23137 [00:00<?, ?it/s]
Constructing CSR matrix...
# Initialize archetypes
model.initialize_archetypes()
Building kernel on X_pca_harmony
Computing diffusion components from X_pca_harmony for waypoint initialization ...
computing neighbors
finished: added to `.uns['neighbors']`
`.obsp['distances']`, distances for each pair of neighbors
`.obsp['connectivities']`, weighted adjacency matrix (0:00:05)
Done.
Sampling waypoints ...
Done.
Selecting 296 cells from waypoint initialization.
Initializing residual matrix using greedy column selection
Initializing f and g...
100%|██████████| 22/22 [00:00<00:00, 24.63it/s]
Selecting 12 cells from greedy initialization.
adata
AnnData object with n_obs × n_vars = 23137 × 20266
obs: 'Auth_Sample_ID', 'Auth_Estimated_postconceptional_age_in_days', 'Auth_Group', 'Auth_Region', 'Auth_nCount_RNA', 'Auth_nFeature_RNA', 'Auth_ATAC_fragments_in_peaks', 'Auth_Scrublet_doublet_score', 'Auth_S.Score', 'Auth_G2M.Score', 'Auth_Class', 'Auth_Subclass', 'Auth_Type_updated', 'Auth_Cluster', 'Auth_cell_type_ontology_term_id', 'Auth_development_stage_ontology_term_id', 'Auth_donor_id', 'Auth_cell_type', 'Auth_sex', 'Auth_tissue', 'Auth_self_reported_ethnicity', 'Auth_development_stage', 'dataset_id', 'sample_id', 'age', 'stage', 'cell_label', 'brain_region', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'total_counts_mito', 'log1p_total_counts_mito', 'pct_counts_mito', 'total_counts_ribo', 'log1p_total_counts_ribo', 'pct_counts_ribo', 'log1p_gene_UMI_ratio', 'n_genes', 'n_counts', 'Leiden_02', 'Leiden_04', 'Leiden_06', 'Leiden_Sel'
var: 'gene_name', 'feature_is_filtered', 'feature_name', 'feature_length', 'feature_type', 'EnsembleCode', 'mito', 'ribo', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'n_cells', 'highly_variable', 'means', 'dispersions', 'dispersions_norm', 'highly_variable_nbatches', 'highly_variable_intersection'
uns: 'Auth_Group_colors', 'Leiden_02', 'Leiden_02_colors', 'Leiden_04', 'Leiden_04_colors', 'Leiden_06', 'Leiden_06_colors', 'Leiden_Sel_colors', 'age_colors', 'brain_region_colors', 'cell_label_colors', 'diffmap_evals', 'draw_graph', 'harmony', 'hvg', 'log1p', 'pca', 'sample_id_colors', 'umap', 'neighbors'
obsm: 'X_draw_graph_fa_harmony', 'X_pca', 'X_pca_harmony', 'X_umap_harmony', 'X_umap_nocorr'
varm: 'PCs'
layers: 'counts', 'lognorm'
obsp: 'harmony_connectivities', 'harmony_distances', 'pca_connectivities', 'pca_distances', 'distances', 'connectivities'
adata.obsm['X_umap'] = adata.obsm['X_umap_harmony'].copy()
# Plot the initilization to ensure they are spread across phenotypic space
SEACells.plot.plot_initialization(adata, model)
We apply the model.fit function.
model.fit(min_iter=10, max_iter=50)
model
Randomly initialized A matrix. Setting convergence threshold at 0.00315 Starting iteration 1. Completed iteration 1. Starting iteration 10. Completed iteration 10. Starting iteration 20. Completed iteration 20. Converged after 29 iterations.
<SEACells.gpu.SEACellsGPU at 0x155431e79900>
# Plot model convergence
model.plot_convergence()
#model.A_
plt.figure(figsize=(4,3))
sns.distplot((model.A_.T > 0.1).sum(axis=1), kde=False)
plt.title(f'Non-trivial (> 0.1) assignments per cell')
plt.xlabel('# Non-trivial SEACell Assignments')
plt.ylabel('# Cells')
plt.show()
plt.figure(figsize=(4,3))
b = np.partition(model.A_.T, -5)
sns.heatmap(np.sort(b[:,-5:])[:, ::-1], cmap='viridis', vmin=0)
plt.title('Strength of top 5 strongest assignments')
plt.xlabel('$n^{th}$ strongest assignment')
plt.show()
/tmp/ipykernel_136029/2880491417.py:4: UserWarning: `distplot` is a deprecated function and will be removed in seaborn v0.14.0. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms). For a guide to updating your code to use the new functions, please see https://gist.github.com/mwaskom/de44147ed2974457ad6372750bbe5751 sns.distplot((model.A_.T > 0.1).sum(axis=1), kde=False)
labels,weights = model.get_soft_assignments()
#labels.head()
We will use hard assignment of each cell to a single metacell to define our metacells for downstream steps. Hard assingment can be retreived in two ways:
adata.obs[['SEACell']].head()
# Alternatively:
# model.get_hard_assignments().head()
| SEACell | |
|---|---|
| index | |
| HDBR-14584-CTX_AAACAGCCATAAGCAA-1 | SEACell-214 |
| HDBR-14584-CTX_AAACAGCCATCCCTCA-1 | SEACell-284 |
| HDBR-14584-CTX_AAACAGCCATTAGGTT-1 | SEACell-279 |
| HDBR-14584-CTX_AAACATGCAAAGGTAC-1 | SEACell-35 |
| HDBR-14584-CTX_AAACATGCAATAATCC-1 | SEACell-37 |
# By default, ad.raw is used for summarization. Other layers present in the anndata can be specified using the parameter summarize_layer parameter
SEA_adata = SEACells.core.summarize_by_SEACell(adata, SEACells_label='SEACell', summarize_layer='counts', celltype_label='cell_label')
SEA_adata
100%|██████████| 308/308 [00:05<00:00, 55.79it/s] /env/lib/python3.10/site-packages/anndata/_core/anndata.py:430: FutureWarning: The dtype argument is deprecated and will be removed in late 2024. warnings.warn(
AnnData object with n_obs × n_vars = 308 × 20266
obs: 'cell_label', 'cell_label_purity'
layers: 'raw'
SEA_adata.obs.head()
| cell_label | cell_label_purity | |
|---|---|---|
| SEACell-214 | ExN | 0.755906 |
| SEACell-284 | RadialGlia | 0.934884 |
| SEACell-279 | ExN | 1.000000 |
| SEACell-35 | RadialGlia | 0.972678 |
| SEACell-37 | OPC | 1.000000 |
print(SEA_adata.X[40:43, 40:43])
<Compressed Sparse Row sparse matrix of dtype 'float64' with 6 stored elements and shape (3, 3)> Coords Values (0, 1) 3.0 (0, 2) 4.0 (1, 1) 1.0 (1, 2) 2.0 (2, 1) 4.0 (2, 2) 5.0
adata.obs['brain_region']
index
HDBR-14584-CTX_AAACAGCCATAAGCAA-1 Neocortex
HDBR-14584-CTX_AAACAGCCATCCCTCA-1 Neocortex
HDBR-14584-CTX_AAACAGCCATTAGGTT-1 Neocortex
HDBR-14584-CTX_AAACATGCAAAGGTAC-1 Neocortex
HDBR-14584-CTX_AAACATGCAATAATCC-1 Neocortex
...
HDBR-15020-FB_TTTGTGAAGTAACCAC-1 Forebrain
HDBR-15020-FB_TTTGTGGCAATACTGT-1 Forebrain
HDBR-15020-FB_TTTGTGGCATAAGGAC-1 Forebrain
HDBR-15020-FB_TTTGTGTTCTCAATTC-1 Forebrain
HDBR-15020-FB_TTTGTTGGTGGATTCA-1 Forebrain
Name: brain_region, Length: 23137, dtype: category
Categories (3, object): ['Forebrain', 'Neocortex', 'Telencephalon']
top_sampleid = adata.obs['sample_id'].groupby(adata.obs['SEACell']).value_counts().groupby(level=0, group_keys=False).head(1)
SEA_adata.obs['agg_sample_id'] = top_sampleid[SEA_adata.obs_names].index.get_level_values(1)
top_brain_region = adata.obs['brain_region'].groupby(adata.obs['SEACell']).value_counts().groupby(level=0, group_keys=False).head(1)
SEA_adata.obs['Aggregated_brain_region'] = top_brain_region[SEA_adata.obs_names].index.get_level_values(1)
SEA_adata.obs["Auth_Group"] = 'First_trimester'
SEA_adata.obs.head()
| cell_label | cell_label_purity | agg_sample_id | Aggregated_brain_region | Auth_Group | |
|---|---|---|---|---|---|
| SEACell-214 | ExN | 0.755906 | HDBR-14831-CTX | Neocortex | First_trimester |
| SEACell-284 | RadialGlia | 0.934884 | HDBR-14831-CTX | Neocortex | First_trimester |
| SEACell-279 | ExN | 1.000000 | HDBR-14831-CTX | Neocortex | First_trimester |
| SEACell-35 | RadialGlia | 0.972678 | HDBR-14831-CTX | Neocortex | First_trimester |
| SEACell-37 | OPC | 1.000000 | HDBR-14831-CTX | Neocortex | First_trimester |
plot_2D(): visualize metacell assignments on UMAP or any 2-dimensional embedding froma adata.obsm. Plots can also be coloured by metacell assignment. The visualization allows to assess the representativeness of the calculated metacells: ability to represent the global structure of the original dataset. Better representation corresponds to a more uniform coverage of the dataset.
plot_SEACell_sizes(): distribution of number of cells assigned to each metacell. Given to the non-uniform distribution of cell type density, metacells are expected to vary in size: larger metacells are retrieved from denser regions, and smaller metacells from sparser ones. However outlier values may require further inspection.
SEACells.plot.plot_2D(adata, key='X_umap', colour_metacells=False)
/env/lib/python3.10/site-packages/SEACells/plot.py:63: FutureWarning: The default of observed=False is deprecated and will be changed to True in a future version of pandas. Pass observed=False to retain current behavior or observed=True to adopt the future default and silence this warning.
mcs = umap.groupby("SEACell").mean().reset_index()
/env/lib/python3.10/site-packages/seaborn/relational.py:438: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored
points = ax.scatter(x=x, y=y, **kws)
/env/lib/python3.10/site-packages/seaborn/relational.py:438: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored
points = ax.scatter(x=x, y=y, **kws)
SEACells.plot.plot_2D(adata, key='X_umap', colour_metacells=True)
/env/lib/python3.10/site-packages/SEACells/plot.py:63: FutureWarning: The default of observed=False is deprecated and will be changed to True in a future version of pandas. Pass observed=False to retain current behavior or observed=True to adopt the future default and silence this warning.
mcs = umap.groupby("SEACell").mean().reset_index()
/env/lib/python3.10/site-packages/seaborn/relational.py:438: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored
points = ax.scatter(x=x, y=y, **kws)
/env/lib/python3.10/site-packages/seaborn/relational.py:438: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored
points = ax.scatter(x=x, y=y, **kws)
SEACells.plot.plot_SEACell_sizes(adata, bins=10, figsize=(10, 5))
/env/lib/python3.10/site-packages/SEACells/plot.py:130: UserWarning:
`distplot` is a deprecated function and will be removed in seaborn v0.14.0.
Please adapt your code to use either `displot` (a figure-level function with
similar flexibility) or `histplot` (an axes-level function for histograms).
For a guide to updating your code to use the new functions, please see
https://gist.github.com/mwaskom/de44147ed2974457ad6372750bbe5751
sns.distplot(label_df.groupby("SEACell").count().iloc[:, 0], bins=bins)
| size | |
|---|---|
| SEACell | |
| SEACell-0 | 33 |
| SEACell-1 | 136 |
| SEACell-10 | 22 |
| SEACell-100 | 24 |
| SEACell-101 | 72 |
| ... | ... |
| SEACell-95 | 73 |
| SEACell-96 | 91 |
| SEACell-97 | 36 |
| SEACell-98 | 49 |
| SEACell-99 | 45 |
308 rows × 1 columns
Purity: compute_celltype_purity(ad, col_name) computes the purity of different celltype labels within a SEACell metacell.
Compactness: per-SEAcell variance in diffusion components (typically 'X_pca' for RNA). Lower values of compactness suggest more compact/lower variance metacells.
Separation: distance between a SEACell and its nth_nbr. If cluster is provided as a string, e.g. 'celltype', nearest neighbors are restricted to have the same celltype value. Higher values of separation suggest better distinction between metacells.
SEACell_purity = SEACells.evaluate.compute_celltype_purity(adata, 'cell_label')
plt.figure(figsize=(6,4))
sns.boxplot(data=SEACell_purity, y='cell_label_purity')
plt.title('cell_label Purity')
sns.despine()
plt.show()
plt.close()
SEACell_purity.head()
| cell_label | cell_label_purity | |
|---|---|---|
| SEACell | ||
| SEACell-0 | RadialGlia | 0.545455 |
| SEACell-1 | ExN | 1.000000 |
| SEACell-10 | Vascular | 0.409091 |
| SEACell-100 | CajalRetzius | 0.958333 |
| SEACell-101 | ExN | 0.916667 |
compactness = SEACells.evaluate.compactness(adata, 'X_pca_harmony')
plt.figure(figsize=(6,4))
sns.boxplot(data=compactness, y='compactness')
plt.title('Compactness')
sns.despine()
plt.show()
plt.close()
compactness.head()
computing neighbors
finished: added to `.uns['neighbors']`
`.obsp['distances']`, distances for each pair of neighbors
`.obsp['connectivities']`, weighted adjacency matrix (0:00:06)
| compactness | |
|---|---|
| SEACell | |
| SEACell-0 | 0.012929 |
| SEACell-1 | 0.000886 |
| SEACell-10 | 0.040295 |
| SEACell-100 | 0.003464 |
| SEACell-101 | 0.003697 |
separation = SEACells.evaluate.separation(adata, 'X_pca_harmony')
plt.figure(figsize=(6,4))
sns.boxplot(data=separation, y='separation')
plt.title('Separation')
sns.despine()
plt.show()
plt.close()
separation.head()
computing neighbors
finished: added to `.uns['neighbors']`
`.obsp['distances']`, distances for each pair of neighbors
`.obsp['connectivities']`, weighted adjacency matrix (0:00:06)
| separation | |
|---|---|
| SEACell | |
| SEACell-0 | 0.206783 |
| SEACell-1 | 0.017085 |
| SEACell-10 | 0.513386 |
| SEACell-100 | 0.105930 |
| SEACell-101 | 0.049692 |
SEA_adata.layers['counts'] = SEA_adata.X.copy()
sc.pp.normalize_total(SEA_adata)
sc.pp.log1p(SEA_adata)
SEA_adata.layers['lognorm'] = SEA_adata.X.copy()
sc.pp.highly_variable_genes(SEA_adata, inplace=True, batch_key="agg_sample_id")
sc.tl.pca(SEA_adata, use_highly_variable=True)
sc.pp.neighbors(SEA_adata, use_rep='X_pca')
sc.tl.umap(SEA_adata)
normalizing counts per cell
finished (0:00:00)
extracting highly variable genes
finished (0:00:00)
--> added
'highly_variable', boolean vector (adata.var)
'means', float vector (adata.var)
'dispersions', float vector (adata.var)
'dispersions_norm', float vector (adata.var)
computing PCA
with n_comps=50
/env/lib/python3.10/site-packages/scanpy/preprocessing/_pca.py:385: FutureWarning: Argument `use_highly_variable` is deprecated, consider using the mask argument. Use_highly_variable=True can be called through mask_var="highly_variable". Use_highly_variable=False can be called through mask_var=None warn(msg, FutureWarning)
finished (0:00:00)
computing neighbors
finished: added to `.uns['neighbors']`
`.obsp['distances']`, distances for each pair of neighbors
`.obsp['connectivities']`, weighted adjacency matrix (0:00:00)
computing UMAP
finished: added
'X_umap', UMAP coordinates (adata.obsm) (0:00:01)
sc.pl.umap(SEA_adata, color=['cell_label'], s=75)
SEA_adata
AnnData object with n_obs × n_vars = 308 × 20266
obs: 'cell_label', 'cell_label_purity', 'agg_sample_id', 'Aggregated_brain_region', 'Auth_Group'
var: 'highly_variable', 'means', 'dispersions', 'dispersions_norm', 'highly_variable_nbatches', 'highly_variable_intersection'
uns: 'log1p', 'hvg', 'pca', 'neighbors', 'umap', 'cell_label_colors'
obsm: 'X_pca', 'X_umap'
varm: 'PCs'
layers: 'raw', 'counts', 'lognorm'
obsp: 'distances', 'connectivities'
sc.pl.umap(SEA_adata, color=['agg_sample_id'], s=75)
sc.pl.umap(SEA_adata, color=['Aggregated_brain_region'], s=75)
sc.pl.umap(SEA_adata, color=['cell_label_purity'], s=75)
SEA_adata.obs.columns
Index(['cell_label', 'cell_label_purity', 'agg_sample_id',
'Aggregated_brain_region', 'Auth_Group'],
dtype='object')
SEA_adata
AnnData object with n_obs × n_vars = 308 × 20266
obs: 'cell_label', 'cell_label_purity', 'agg_sample_id', 'Aggregated_brain_region', 'Auth_Group'
var: 'highly_variable', 'means', 'dispersions', 'dispersions_norm', 'highly_variable_nbatches', 'highly_variable_intersection'
uns: 'log1p', 'hvg', 'pca', 'neighbors', 'umap', 'cell_label_colors', 'agg_sample_id_colors', 'Aggregated_brain_region_colors'
obsm: 'X_pca', 'X_umap'
varm: 'PCs'
layers: 'raw', 'counts', 'lognorm'
obsp: 'distances', 'connectivities'
SEA_adata.X
<Compressed Sparse Row sparse matrix of dtype 'float64' with 4429212 stored elements and shape (308, 20266)>
SEA_adata.write(output_file)
%%bash
# save also html and python versions for git
jupyter nbconvert SEACellsWang_FirstTrimester.ipynb --to="python" --output="SEACellsWang_FirstTrimester"
jupyter nbconvert SEACellsWang_FirstTrimester.ipynb --to="html" --output="SEACellsWang_FirstTrimester"
[NbConvertApp] Converting notebook SEACellsWang_FirstTrimester.ipynb to python [NbConvertApp] Writing 13102 bytes to SEACellsWang_FirstTrimester.py [NbConvertApp] Converting notebook SEACellsWang_FirstTrimester.ipynb to html [NbConvertApp] WARNING | Alternative text is missing on 11 image(s). [NbConvertApp] Writing 6399677 bytes to SEACellsWang_FirstTrimester.html
print(datetime.now())
2026-03-11 12:40:04.839718