作者剔蹋,Evil Genius
今日參考文獻辛慰,Spatial transcriptomic characterization of pathologic niches in IPF(Science Advances)别凹。
首先搜集一下marker
單細胞 + 空間分析確定了三個與疾病相關的生態(tài)位,具有獨特的細胞組成和定位叶沛。這種IPF生態(tài)位的空間特征將有助于識別破壞疾病驅(qū)動生態(tài)位的藥物靶點惰赋,并有助于開發(fā)與疾病相關的體外模型。
知識背景
- 細胞的位置蕴侧、周圍鄰居和組織結(jié)構(gòu)择同,如IPF中的蜂窩形態(tài)或成纖維細胞灶,對于確定細胞表型净宵、疾病狀態(tài)以及最終的細胞功能和通訊至關重要
- 了解每個生態(tài)位空間內(nèi)細胞和分子的相互作用對于更好地解剖獨特的疾病病理生物學和指導下一代藥物的發(fā)現(xiàn)至關重要敲才。
- 空間轉(zhuǎn)錄組學通過在完整組織的自然組織環(huán)境中提供空間解析的基因表達來解決這一問題,而不會誘導細胞應激择葡、死亡或分離偏差紧武。最近建立的Visium用于福爾馬林固定和石蠟包埋(FFPE)技術(shù)可以對保存的FFPE組織切片進行無偏置的基于探針的近全轉(zhuǎn)錄組mRNA分析,而Xenium原位技術(shù)可以對多達500個選定基因進行亞細胞分辨率敏储。
分析結(jié)果1阻星、空間和scRNA-seq分析定位健康和IPF肺組織中的細胞和基因
- cell2location
- 病理學家對HE染色組織切片的組織病理學注釋
- 細胞類型共定位,異常的細胞共定位引起了疾病的發(fā)生和變化
- Xenium平臺驗證Visium的分析結(jié)果
分析結(jié)果2已添、三種不同的niche出現(xiàn)在IPF肺組織中
- 非負矩陣分解(NMF)
- 將cell2location逐細胞類型輸出矩陣轉(zhuǎn)換為細胞類型和生態(tài)位矩陣妥箕,以及spot和生態(tài)位矩陣。這能夠確定每個spot內(nèi)的主要細胞生態(tài)位和表征每個生態(tài)位的細胞類型更舞,抽象出生物系統(tǒng)的復雜性矾踱,并確定組織內(nèi)最相關的細胞鄰近區(qū)。
- 生態(tài)位的空間組織疏哗,利用位置數(shù)據(jù)并分析相鄰的相互作用呛讲。
分析結(jié)果3、在氣道周圍發(fā)現(xiàn)異常的基底樣細胞
分析結(jié)果4返奉、SPP1+巨噬細胞亞群定位于纖維化氣道的管腔
進一步研究氣道巨噬細胞生態(tài)位贝搁,我們首先旨在了解IPF中細胞巨噬細胞亞型的異質(zhì)性,這些亞型都表達spp1 -被認為是許多纖維化疾病中常見的纖維化巨噬細胞標志物芽偏±啄妫空間Visium數(shù)據(jù)揭示了巨噬細胞亞型在IPF中的差異定位,并提示氣道巨噬細胞生態(tài)位優(yōu)先定位于纖維化氣道的管腔污尉,可以在mRNA和蛋白質(zhì)水平上驗證這一點膀哲。氣道巨噬細胞生態(tài)位也出現(xiàn)在纖維化生態(tài)位附近,特別是異常的基底細胞被碗,這是由預測的和獨特的細胞間通訊支持的某宪。
分析結(jié)果5、免疫細胞病灶是由ipf特異性異位內(nèi)皮細胞募集的
空間轉(zhuǎn)錄組學數(shù)據(jù)以及H&E組織結(jié)構(gòu)顯示锐朴,免疫生態(tài)位是IPF的一個顯著組織病理學特征兴喂,以多種淋巴樣細胞類型的病灶形式存在,可能通過異位內(nèi)皮支氣管血管的不同分泌信號募集。
來看看代碼部分衣迷,我們看一下重點部分
重點畏鼓、hotspot(空間打分)
import scanpy as sc
import squidpy as sq
import numpy as np
import pandas as pd
import os
import sys
import seaborn as sb
import matplotlib.pyplot as plt
from matplotlib import colors
#import scvi
import anndata as ad
import warnings
warnings.filterwarnings("ignore")
from collections import Counter
import ipywidgets as widgets
from ipywidgets import interact, interact_manual
plt.rcParams['figure.figsize'] = (6, 6)
from IPython.core.display import display, HTML
import random
#Define a colour map for gene expression
colors2 = plt.cm.Reds(np.linspace(0, 1, 128))
colors3 = plt.cm.Greys_r(np.linspace(0.7,0.8,20))
#colorsComb = np.vstack([colors3, colors2])
#mymap = colors.LinearSegmentedColormap.from_list('my_colormap', colorsComb)
from matplotlib import colors
colorsComb = np.vstack([plt.cm.Reds(np.linspace(0, 1, 128)), plt.cm.Greys_r(np.linspace(0.7, 0.8, 0))])
mymap = colors.LinearSegmentedColormap.from_list('my_colormap', colorsComb)
# Helper function to split list in chunks
def chunks(lista, n):
for i in range(0, len(lista), n):
yield lista[i:i + n]
plt.rcParams['figure.figsize'] = (6, 5)
sc.set_figure_params(dpi=100, vector_friendly=True)
def mysize(w, h, d):
fig, ax = plt.subplots(figsize = (w, h), dpi = d)
return(fig.gca())
plt.rcParams['figure.figsize'] = (6, 5)
sc.set_figure_params(dpi=100, vector_friendly=True)
sc.settings.figdir = "./figures/"
import scvi
## frequently used variables
from matplotlib import colors
import matplotlib.pyplot as plt
colorsComb = np.vstack([plt.cm.Reds(np.linspace(0, 1, 128)), plt.cm.Greys_r(np.linspace(0.7, 0.8, 0))])
mymap = colors.LinearSegmentedColormap.from_list('my_colormap', colorsComb)
## Along these Lines, a colourmap diverging from gray to red
gray_red = colors.LinearSegmentedColormap.from_list("grouping", ["lightgray", "red", "darkred"], N = 128)
## Some more Colour Maps
gray_violet = colors.LinearSegmentedColormap.from_list("grouping", ["lightgray", "mediumvioletred", "indigo"], N = 128)
gray_blue = colors.LinearSegmentedColormap.from_list("grouping", ["lightgray", "cornflowerblue", "darkblue"], N = 128)
def mysize(w, h, d):
fig, ax = plt.subplots(figsize = (w, h), dpi = d)
return(fig.gca())
#plt.rcParams['figure.figsize'] = (6, 5)
#sc.set_figure_params(dpi=120, vector_friendly=True)
import matplotlib.colors as colors
c_low = colors.colorConverter.to_rgba('orange', alpha = 0)
c_high = colors.colorConverter.to_rgba('red',alpha = 1)
cmap_transparent = colors.LinearSegmentedColormap.from_list('rb_cmap',[c_low, c_high], 512)
import matplotlib.colors as colors
c_low2 = colors.colorConverter.to_rgba('green', alpha = 0)
c_high2 = colors.colorConverter.to_rgba('darkblue',alpha = 1)
cmap_transparent2 = colors.LinearSegmentedColormap.from_list('rb_cmap',[c_low2, c_high2], 512)
print(f"squidpy=={sq.__version__}")
print(f"scanpy=={sc.__version__}")
import cell2location as c2l
from cell2location.utils import select_slide
##load
adata_vis = sc.read(f".h5ad")
Niche_NMF_palette = dict(zip(adata_vis.obs.Niche_NMF.cat.categories, adata_vis.uns["Niche_NMF_colors"]))
sc.pl.umap(adata_vis, color="Niche_NMF", palette=Niche_NMF_palette,)
import hotspot
def compute_scores_hotspot(adata,
genes,
layer=None,
n_neighbors = 30,
neighborhood_factor = 3,
gene_symbols = None,
use_rep = "X_scVI",
model = 'danb'
):
if use_rep is None:
if layer is None:
index = pynndescent.NNDescent(adata.X, n_neighbors=n_neighbors+1)
else:
index = pynndescent.NNDescent(adata.layers[layer], n_neighbors=n_neighbors+1)
else:
index = pynndescent.NNDescent(adata.obsm[use_rep], n_neighbors=n_neighbors+1)
ind, dist = index.neighbor_graph
ind, dist = ind[:, 1:], dist[:, 1:]
ind = pd.DataFrame(ind, index=list(range(adata.n_obs)))
neighbors = ind
weights = compute_weights(dist, neighborhood_factor=neighborhood_factor)
weights = pd.DataFrame(weights, index=neighbors.index,
columns=neighbors.columns)
if layer is None:
if scipy.sparse.issparse(adata.X):
umi_counts = adata.X.sum(axis=1).A1
else:
umi_counts = adata.X.sum(axis=1)
else:
if scipy.sparse.issparse(adata.layers[layer]):
umi_counts = adata.layers[layer].sum(axis=1).A1
else:
umi_counts = adata.layers[layer].sum(axis=1)
if gene_symbols is None:
counts_dense = Hotspot._counts_from_anndata(
adata[:, adata.var_names.isin(genes)], layer, dense=True)
else:
counts_dense = Hotspot._counts_from_anndata(
adata[:, adata.var[gene_symbols].isin(genes)], layer, dense=True)
scores = modules.compute_scores(
counts_dense,
model,
umi_counts,
neighbors.values,
weights.values,
)
return scores
import pynndescent
import scipy.sparse
import hotspot
from hotspot import modules
from hotspot.knn import compute_weights
from hotspot.hotspot import Hotspot
senescence =["GLB1","TP53","SERPINE1","CDKN1A","CDKN1B","CDKN2B"]
scores = compute_scores_hotspot(adata_vis, senescence,layer="log1p",n_neighbors = 30,neighborhood_factor = 3,gene_symbols = None,use_rep = "X_scVI",model = 'danb')
adata_vis.obs["senescence_hs_score"] = scores
#for i in fibs:
gene = "senescence_hs_score"
vmins = None
vcenters= None
vmaxs = 2
img_keys='lowres'
cmaps= "bwr"
palettes=Niche_NMF_palette
group= None #"Fibrotic"
import matplotlib.pyplot as plt
from cell2location.utils import select_slide
fig, (ax1, ax2, ax3, ax4, ax5,ax6) = plt.subplots(1, 6, figsize=(26,4), )
plt.suptitle(" control ", y=1.05)
with plt.rc_context({'axes.facecolor': 'white','figure.figsize': [4, 4]}):
slide = select_slide(adata_vis, "90_C1_RO-730_Healthy_processed_CM")
sc.pl.spatial(slide, cmap=cmaps,color=gene,size=1.3,img_key=img_keys,vmin=vmins, use_raw=False,layer="log1p",groups=group, vmax=vmaxs, ax=ax1, show=False,vcenter= vcenters,palette=palettes, legend_loc=None)
slide = select_slide(adata_vis, "91_A1_RO-727_Healthy_processed_CM")
sc.pl.spatial(slide, cmap=cmaps,color=gene,size=1.3,img_key=img_keys,vmin=vmins, use_raw=False,layer="log1p",groups=group, vmax=vmaxs, ax=ax2, show=False,vcenter= vcenters,palette=palettes, legend_loc=None)
slide = select_slide(adata_vis, "91_B1_RO-728_Healthy_processed_CM")
sc.pl.spatial(slide, cmap=cmaps,color=gene,size=1.3,img_key=img_keys,vmin=vmins, use_raw=False,layer="log1p",groups=group, vmax=vmaxs, ax=ax3, show=False,vcenter= vcenters,palette=palettes, legend_loc=None)
slide = select_slide(adata_vis, "1217_0002_processed_aligned")
sc.pl.spatial(slide, cmap=cmaps,color=gene,size=1.3,img_key=img_keys,vmin=vmins, use_raw=False,layer="log1p",groups=group, vmax=vmaxs, ax=ax4, show=False,vcenter= vcenters,palette=palettes, legend_loc=None)
slide = select_slide(adata_vis, "92_A1_RO-3203_Healthy_processed_CM")
sc.pl.spatial(slide, cmap=cmaps,color=gene,size=1.3,img_key=img_keys,vmin=vmins, use_raw=False,layer="log1p",groups=group, vmax=vmaxs, ax=ax5, show=False,vcenter= vcenters,palette=palettes, legend_loc=None)
slide = select_slide(adata_vis, "1217_0004_processed_aligned")
sc.pl.spatial(slide, cmap=cmaps,color=gene,size=1.3,img_key=img_keys,vmin=vmins, use_raw=False,layer="log1p",groups=group, vmax=vmaxs, ax=ax6, show=False,vcenter= vcenters,palette=palettes, legend_loc=None)
plt.savefig("./figures/spatial_plot_senescence_hs_score_healthy_vmax2.pdf")
fig, (ax7, ax8, ax9, ax10, ax11,) = plt.subplots(1, 5, figsize=(22,4), )
plt.suptitle(" IPF ", y=1.05)
with plt.rc_context({'axes.facecolor': 'white','figure.figsize': [4, 4]}):
slide = select_slide(adata_vis, "90_A1_H237762_IPF_processed_CM")
sc.pl.spatial(slide, cmap=cmaps,color=gene,size=1.3,img_key=img_keys,vmin=vmins, use_raw=False,layer="log1p",groups=group, vmax=vmaxs, ax=ax7, show=False,vcenter= vcenters,palette=palettes, legend_loc=None)
slide = select_slide(adata_vis, "1217_0001_processed_aligned")
sc.pl.spatial(slide, cmap=cmaps,color=gene,size=1.3,img_key=img_keys,vmin=vmins, use_raw=False,layer="log1p",groups=group, vmax=vmaxs, ax=ax8, show=False,vcenter= vcenters,palette=palettes, legend_loc=None)
slide = select_slide(adata_vis, "91_D1_24513-17_IPF_processed_CM")
sc.pl.spatial(slide, cmap=cmaps,color=gene,size=1.3,img_key=img_keys,vmin=vmins, use_raw=False,layer="log1p",groups=group, vmax=vmaxs, ax=ax9, show=False,vcenter= vcenters,palette=palettes, legend_loc=None)
slide = select_slide(adata_vis, "1217_0003_processed_aligned")
sc.pl.spatial(slide, cmap=cmaps,color=gene,size=1.3,img_key=img_keys,vmin=vmins, use_raw=False,layer="log1p",groups=group, vmax=vmaxs, ax=ax10, show=False,vcenter= vcenters,palette=palettes, legend_loc=None)
slide = select_slide(adata_vis, "92_D1_RO-3736_IPF_processed_CM")
sc.pl.spatial(slide, cmap=cmaps,color=gene,size=1.3,img_key=img_keys,vmin=vmins, use_raw=False,layer="log1p",groups=group, vmax=vmaxs, ax=ax11, show=False,vcenter= vcenters,palette=palettes)
plt.savefig("./figures/spatial_plot_senescence_hs_score_IPF_vmax2.pdf")