Scube tutorial: Alignment of consecutive ST slices on mouse embryo Stereo-seq dataset

July 2023

Dataset: 13 ST slices of mouse embryos (here)

[1]:
import SPACEL
from SPACEL import Scube
import scanpy as sc
import warnings
import matplotlib.pyplot as plt
warnings.filterwarnings("ignore")

Spatial transcriptomic data import

The input data type of Scube is a list of anndata objects for each slice. The anndata objects of each slice must contain a column of spatial domain for alignment in .obs.

[2]:
adata = sc.read(f'../data/stereo_seq_mouse_embryo/mouse_embryo_all_slices.h5ad')
adata_list=[]
for i in range(13):
    adata_list.append(adata[adata.obs.slice==i+1])
    adata_list[i].obs.spatial_domain = adata_list[i].obs.spatial_domain.astype('category')

Pairwise alignment

Here, we perform pairwise alignment of slices. The cluster_key is a column of .obs which contain spatial domain information used for alignment. The n_neighbors affect how much neighbors are considered when calculate similarity of two slices. The knn_exclude_cutoff affect max distance of neighbors. By default, n_neighbors = 15 and knn_exclude_cutoff = n_neighbors means a spot/cell in source slices consider 15 neighbors in target slices, and neighbor will be exclude when the distance of neighbors larger than the median of neareast 30 neighbors distance in all spot/cell in target slice. p affect the exponent of overlap penalty, and a larger p means stronger partial alignment capability.

[3]:
Scube.align(adata_list,
      cluster_key='spatial_domain',
      n_neighbors = 15,
      n_threads=10,
      p=1,
      write_loc_path='Scube_outputs/aligned_coordinates.csv'
    )
adata = sc.concat(adata_list)
adata.write(f'../data/stereo_seq_mouse_embryo/mouse_embryo_all_slices.h5ad')
Start alignment...
Alignment slice 1 to 0
Alignment slice 2 to 1
Alignment slice 3 to 2
Alignment slice 4 to 3
Alignment slice 5 to 4
Alignment slice 6 to 5
Alignment slice 7 to 6
Alignment slice 8 to 7
Alignment slice 9 to 8
Alignment slice 10 to 9
Alignment slice 11 to 10
Alignment slice 12 to 11
Runtime: 1901.174468755722 s

After alignment, the new spots/cells location coordinates saved in .obsm['spatial_aligned'] of anndata object of each slices. When write_loc_path provied by users, the location coordinates of all spots/cells of all slices will be saved in write_loc_path.

Plot alignment results

Plot all aligned slices stacked in a single figure. Spots are colored based on the annotations.

[4]:
color_anno = ['#bd6f37', '#e3c8ab', '#994d20', '#823f22', '#3a4d9d', '#455ea9','#6989c8', '#683784', '#c1b846', '#80b7bf', '#7ba22f', '#915998', '#7bb3cd', '#933780', '#68468f', '#d5d1d6', '#97922c', '#67a98c','#81163c', '#ba4343', '#c76b6f', '#962247', '#751932', '#5c9a42', '#324557', '#182a14', '#7e2a7a', '#67832d', '#494184', '#769f34']
anno = ['Brain', 'Spinal cord', 'Sympathetic nerve', 'Dorsal root ganglion', 'Epidermis', 'Mucosal epithelium', 'Olfactory epithelium', 'Choroid plexus', 'Meninges', 'Inner ear', 'Eye', 'Jaw and tooth', 'Kidney', 'Adrenal gland', 'Thymus', 'Cavity', 'Blood vessel', 'Connective tissue', 'Adipose tissue','Smooth muscle', 'Testis', 'Heart', 'Muscle','Cartilage primordium', 'Cartilage', 'Bone', 'Liver', 'Pancreas','GI tract', 'Lung']
[5]:
import numpy as np
import pandas as pd
dic = dict(zip(anno, color_anno))
adata = adata[adata.obs.annotation != 'Cavity']
adata.uns['annotation_colors'] = np.array(pd.Series(np.unique(adata.obs['annotation'])).replace(dic))
adata.obsm['spatial_aligned'] = np.array(adata.obsm['spatial_aligned'])
[6]:
sc.pl.embedding(adata,basis='spatial_aligned',color='annotation',s=7,show=False)
plt.xlim(-315,315)
plt.ylim(-315,315)
[6]:
(-315.0, 315.0)
../_images/tutorials_Stereo-seq_Scube_15_1.png