SPACEL workflow (3/3): Alignment 3D tissue by Scube on mouse brain ST dataset

July 2023

Dataset: 75 ST slices of mouse brain (here)

[1]:
import SPACEL
from SPACEL import Scube
[2]:
import numpy as np
import matplotlib.pyplot as plt
import scanpy as sc

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.

[3]:
adata = sc.read('../data/ST_mouse_brain/mouse_brain_st.h5ad')
adata_list = []
for i in range(75):
    adata_list.append(adata[adata.obs.slice==i])

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, knn_exclude_cutoff = n_neighbors, which means a spot/cell in source slices consider knn_exclude_cutoff neighbors in target slices, and neighbor will be exclude when the distance of neighbors larger than the median of neareast knn_exclude_cutoff + n_neighbors 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.

[4]:
Scube.align(adata_list,
  cluster_key='spatial_domain',
  n_neighbors = 4,
  p=1,
  write_loc_path='Scube_outputs/aligned_coordinates.csv'
 )
sc.concat(adata_list).write('../data/ST_mouse_brain/mouse_brain_st.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
Alignment slice 13 to 12
Alignment slice 14 to 13
Alignment slice 15 to 14
Alignment slice 16 to 15
Alignment slice 17 to 16
Alignment slice 18 to 17
Alignment slice 19 to 18
Alignment slice 20 to 19
Alignment slice 21 to 20
Alignment slice 22 to 21
Alignment slice 23 to 22
Alignment slice 24 to 23
Alignment slice 25 to 24
Alignment slice 26 to 25
Alignment slice 27 to 26
Alignment slice 28 to 27
Alignment slice 29 to 28
Alignment slice 30 to 29
Alignment slice 31 to 30
Alignment slice 32 to 31
Alignment slice 33 to 32
Alignment slice 34 to 33
Alignment slice 35 to 34
Alignment slice 36 to 35
Alignment slice 37 to 36
Alignment slice 38 to 37
Alignment slice 39 to 38
Alignment slice 40 to 39
Alignment slice 41 to 40
Alignment slice 42 to 41
Alignment slice 43 to 42
Alignment slice 44 to 43
Alignment slice 45 to 44
Alignment slice 46 to 45
Alignment slice 47 to 46
Alignment slice 48 to 47
Alignment slice 49 to 48
Alignment slice 50 to 49
Alignment slice 51 to 50
Alignment slice 52 to 51
Alignment slice 53 to 52
Alignment slice 54 to 53
Alignment slice 55 to 54
Alignment slice 56 to 55
Alignment slice 57 to 56
Alignment slice 58 to 57
Alignment slice 59 to 58
Alignment slice 60 to 59
Alignment slice 61 to 60
Alignment slice 62 to 61
Alignment slice 63 to 62
Alignment slice 64 to 63
Alignment slice 65 to 64
Alignment slice 66 to 65
Alignment slice 67 to 66
Alignment slice 68 to 67
Alignment slice 69 to 68
Alignment slice 70 to 69
Alignment slice 71 to 70
Alignment slice 72 to 71
Alignment slice 73 to 72
Alignment slice 74 to 73
Runtime: 1316.9635601043701 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 brain region annotations.

[5]:
adata = sc.concat(adata_list)
[6]:
import pandas as pd
colors = ['#EEEE7C','#8ECD82','#F99A86','#82C748','#E7422F','#118165','#C975B2','#98D2BC','#8498CE','#30B743','#99D5F6','#F46F7F','white','#CDCDCC','#ABABAB']
adata.uns['ABA_parent_colors'] = colors
adata.obsm['spatial_aligned'] = np.array(adata.obsm['spatial_aligned'])

adata_list = []
for j in range(75):
    adata_list.append(adata[adata.obs.slice == j].copy())
    adata_list[j].uns['ABA_parent_colors'] = pd.Series(np.unique(adata_list[j].obs.ABA_parent)).replace(dict(zip(np.unique(adata.obs.ABA_parent),colors))).values.flatten()
[7]:
plt.rcParams['figure.figsize'] = (3,3)
sc.pl.embedding(adata, basis='spatial_aligned',color='ABA_parent',s=10,show=False)
[7]:
<Axes: title={'center': 'ABA_parent'}, xlabel='spatial_aligned1', ylabel='spatial_aligned2'>
../_images/tutorials_ST_mouse_brain_Scube_16_1.png