raphael-group / paste2

Probabilistic Alignment of Spatial Transcriptomics Experiments v.2
BSD 3-Clause "New" or "Revised" License
29 stars 2 forks source link

How to generate 3D Spatial Transcriptomic Maps from PASTE2 analysis results? #6

Open lanyuchunmo opened 7 months ago

lanyuchunmo commented 7 months ago

As a novice user of PASTE2, I'm truly grateful for the provision of such a robust 3D spatial transcriptome reconstruction tool. Having successfully replicated results using the demo data, I'm now confronted with the task of creating a 3D image following pairwise alignment of all consecutive slices. I'm eagerly seeking guidance and tutorials on the downstream analysis processes after completing PASTE2 analyses. Could you advise on the subsequent steps and analyses required, as well as recommend software tools, to generate 3D images suitable for publication, similar to those depicted in the following articles: "High-resolution 3D spatiotemporal transcriptomic maps of developing Drosophila embryos and larvae" (DOI: 10.1016/j.devcel.2022.04.006) and "3D reconstruction of a gastrulating human embryo" (DOI: 10.1016/j.cell.2024.03.041)?

image

image

image

x-h-liu commented 6 months ago

Hi,

Thank you for your interest in PASTE2! I can provide you with the code that I used to generate Fig. S6b of our paper, which is a visualization of a 3D reconstruction of the tissue.

If you follow the tutorial, the last section uses partial_stack_slices_pairwise() to get a list new_slices, where each item in the list is an AnnData object of a slice with the .obsm['spatial'] field updated so that all slices are in the same 2D coordinate system. Now you only need to assign each slice a z coordinate so that each spot from each slice has a (x,y,z) coordinate, then you will have your 3D model. How you assign a z coordinate to each slice is entirely up to you because the z coordinate depends on your specific data, i.e. how far away are the two slices experimentally.

Here is the code for generating Fig. S6b of our paper:

import scanpy as sc
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
import plotly.express as px
import plotly.io as pio
import seaborn as sns

pio.renderers.default='notebook'
config = {
      'toImageButtonOptions': {
        'format': 'svg', 
        'filename': "DLPFC_3d"
      }
    }
layer_to_color_map = {'Layer{0}'.format(i+1):sns.color_palette()[i] for i in range(6)}
layer_to_color_map['WM'] = sns.color_palette()[6]
z_coordinates = np.array([0,1,2,3])*1500
df = pd.DataFrame(columns=['x','y','z','layer'])
for i, L in enumerate(new_slices):
    adata = new_slices[i]
    df_ = pd.DataFrame(np.concatenate((L.obsm['spatial'],np.matrix(z_coordinates[i]*np.ones(len(adata))).T,np.matrix(np.ones(len(adata),dtype=int)).T),axis=1),columns=['x','y','z','layer'])
    df_.loc[:,"layer"] = list(adata.obs['layer_guess_reordered'])
    df = df.append(df_, ignore_index=True)
df = df.sort_values(by=['layer'])
df['y'] = -df['y']
fig = px.scatter_3d(df, x='x', y='y', z='z',
                  color='layer',color_discrete_sequence=[matplotlib.colors.to_hex(layer_to_color_map[c]) for c in sorted(list(adata.obs['layer_guess_reordered'].cat.categories))])
fig.update_layout(scene_aspectmode='data',font=dict(size=8))
fig.show(config=config)

The z_coordinates = np.array([0,1,2,3])*1500 line is where I assign a z to each of the four slices. You can adapt this code to generate the 3D plot you want. The 'layer' column of the data frame is simply a cell type annotation and should be changed to whatever suits your data.

Let me know if you have any other questions! Thanks, Xinhao