今天是30号了,马上过年了,不知道大家相亲是否开心呢??这一篇我们回顾一下10X空间转录组的分析软件----Giotto,文章在Giotto, a toolbox for integrative analysis and visualization of spatial expression data,我们简单回顾一下软件的原理和示例代码
Overview of the Giotto toolbox
Giotto 提供了一个全面的空间分析工具箱,其中包含两个独立但完全集成的模块。 第一个模块(Giotto Analyzer)提供有关分析空间单细胞表达数据的不同步骤的分析说明,而第二个模块(Giotto Viewer)在用户本地计算机上提供此类数据的响应式和交互式查看器。 这两个模块可以独立使用,也可以迭代使用。
Giotto Analyzer 需要一个基因的细胞计数矩阵和每个细胞质心位置的空间坐标作为最小输入。 在基础层面,Giotto Analyzer 可用于执行通常类似于 scRNAseq 分析的常见步骤,例如预处理、特征选择、降维和无监督聚类; 另一方面,主要优势在于它整合基因表达和空间信息的能力,以便深入了解组织的结构和功能组织及其表达模式。 Giotto Analyzer 创建了一个空间网格和邻域网络,将物理上彼此靠近的细胞连接起来。 这些对象作为执行与细胞邻域相关的分析的基础。
Giotto Analyzer 是用流行的语言 R 编写的,核心数据结构是 giotto 对象,它是专为基于 R 中灵活的 S4 对象系统而设计的空间表达数据分析。 足以执行所有计算和分析。 这允许用户快速评估和创建自己的灵活管道,用于空间可视化和数据分析。 Giotto Viewer 模块旨在以交互方式探索 Giotto Analyzer 的输出并可视化其他信息,例如细胞形态和转录位置。总之,这两个模块为空间表达数据分析和可视化提供了一个集成工具箱。
示例代码(小鼠脑)
library(Giotto)
# 1\. set working directory
#results_folder = '/path/to/directory/'
results_folder = '/Volumes/Ruben_Seagate/Dropbox (Personal)/Projects/GC_lab/Ruben_Dries/190225_spatial_package/Results/Visium/Brain/201226_results//'
# 2\. set giotto python path
# set python path to your preferred python version path
# set python path to NULL if you want to automatically install (only the 1st time) and use the giotto miniconda environment
python_path = NULL
if(is.null(python_path)) {
installGiottoEnvironment()
}
Dataset explanation(10X平台数据为例)
Part 1: Giotto global instructions and preparations
## create instructions
instrs = createGiottoInstructions(save_dir = results_folder,
save_plot = TRUE,
show_plot = FALSE)
## provide path to visium folder
#data_path = '/path/to/Brain_data/'
data_path = '/Volumes/Ruben_Seagate/Dropbox (Personal)/Projects/GC_lab/Ruben_Dries/190225_spatial_package/Data/Visium_data/Brain_data/'
part 2: Create Giotto object & process data
## directly from visium folder
visium_brain = createGiottoVisiumObject(visium_dir = data_path, expr_data = 'raw',
png_name = 'tissue_lowres_image.png',
gene_column_index = 2, instructions = instrs)
## update and align background image
# problem: image is not perfectly aligned
spatPlot(gobject = visium_brain, cell_color = 'in_tissue', show_image = T, point_alpha = 0.7,
save_param = list(save_name = '2_a_spatplot_image'))
# check name
showGiottoImageNames(visium_brain) # "image" is the default name
# adjust parameters to align image (iterative approach)
visium_brain = updateGiottoImage(visium_brain, image_name = 'image',
xmax_adj = 1300, xmin_adj = 1200,
ymax_adj = 1100, ymin_adj = 1000)
# now it's aligned
spatPlot(gobject = visium_brain, cell_color = 'in_tissue', show_image = T, point_alpha = 0.7,
save_param = list(save_name = '2_b_spatplot_image_adjusted'))
## check metadata
pDataDT(visium_brain)
## compare in tissue with provided jpg
spatPlot(gobject = visium_brain, cell_color = 'in_tissue', point_size = 2,
cell_color_code = c('0' = 'lightgrey', '1' = 'blue'),
save_param = list(save_name = '2_c_in_tissue'))
## subset on spots that were covered by tissue
metadata = pDataDT(visium_brain)
in_tissue_barcodes = metadata[in_tissue == 1]$cell_ID
visium_brain = subsetGiotto(visium_brain, cell_ids = in_tissue_barcodes)
## filter
visium_brain <- filterGiotto(gobject = visium_brain,
expression_threshold = 1,
gene_det_in_min_cells = 50,
min_det_genes_per_cell = 1000,
expression_values = c('raw'),
verbose = T)
## normalize
visium_brain <- normalizeGiotto(gobject = visium_brain, scalefactor = 6000, verbose = T)
## add gene & cell statistics
visium_brain <- addStatistics(gobject = visium_brain)
## visualize
spatPlot2D(gobject = visium_brain, show_image = T, point_alpha = 0.7,
save_param = list(save_name = '2_d_spatial_locations'))
spatPlot2D(gobject = visium_brain, show_image = T, point_alpha = 0.7,
cell_color = 'nr_genes', color_as_factor = F,
save_param = list(save_name = '2_e_nr_genes'))
part 3: dimension reduction
## highly variable genes (HVG)
visium_brain <- calculateHVG(gobject = visium_brain,
save_param = list(save_name = '3_a_HVGplot'))
## run PCA on expression values (default)
gene_metadata = fDataDT(visium_brain)
featgenes = gene_metadata[hvg == 'yes' & perc_cells > 3 & mean_expr_det > 0.4]$gene_ID
visium_brain <- runPCA(gobject = visium_brain,
genes_to_use = featgenes,
scale_unit = F, center = T,
method="factominer")
screePlot(visium_brain, ncp = 30, save_param = list(save_name = '3_b_screeplot'))
plotPCA(gobject = visium_brain,
save_param = list(save_name = '3_c_PCA_reduction'))
## run UMAP and tSNE on PCA space (default)
visium_brain <- runUMAP(visium_brain, dimensions_to_use = 1:10)
plotUMAP(gobject = visium_brain,
save_param = list(save_name = '3_d_UMAP_reduction'))
visium_brain <- runtSNE(visium_brain, dimensions_to_use = 1:10)
plotTSNE(gobject = visium_brain,
save_param = list(save_name = '3_e_tSNE_reduction'))
part 4: cluster
## sNN network (default)
visium_brain <- createNearestNetwork(gobject = visium_brain, dimensions_to_use = 1:10, k = 15)
## Leiden clustering
visium_brain <- doLeidenCluster(gobject = visium_brain, resolution = 0.4, n_iterations = 1000)
plotUMAP(gobject = visium_brain,
cell_color = 'leiden_clus', show_NN_network = T, point_size = 2.5,
save_param = list(save_name = '4_a_UMAP_leiden'))
part 5: co-visualize
# expression and spatial
spatDimPlot(gobject = visium_brain, cell_color = 'leiden_clus',
dim_point_size = 2, spat_point_size = 2.5,
save_param = list(save_name = '5_a_covis_leiden'))
spatDimPlot(gobject = visium_brain, cell_color = 'nr_genes', color_as_factor = F,
dim_point_size = 2, spat_point_size = 2.5,
save_param = list(save_name = '5_b_nr_genes'))
DG_subset = subsetGiottoLocs(visium_brain,
x_max = 6500, x_min = 3000,
y_max = -2500, y_min = -5500,
return_gobject = TRUE)
spatDimPlot(gobject = DG_subset,
cell_color = 'leiden_clus', spat_point_size = 5,
save_param = list(save_name = '5_c_DEG_subset'))
part 6: cell type marker gene detection
gini_markers_subclusters = findMarkers_one_vs_all(gobject = visium_brain,
method = 'gini',
expression_values = 'normalized',
cluster_column = 'leiden_clus',
min_genes = 20,
min_expr_gini_score = 0.5,
min_det_gini_score = 0.5)
topgenes_gini = gini_markers_subclusters[, head(.SD, 2), by = 'cluster']$genes
# violinplot
violinPlot(visium_brain, genes = unique(topgenes_gini), cluster_column = 'leiden_clus',
strip_text = 8, strip_position = 'right',
save_param = list(save_name = '6_a_violinplot_gini', base_width = 5, base_height = 10))
# cluster heatmap
plotMetaDataHeatmap(visium_brain, selected_genes = topgenes_gini,
metadata_cols = c('leiden_clus'),
x_text_size = 10, y_text_size = 10,
save_param = list(save_name = '6_b_metaheatmap_gini'))
scran_markers_subclusters = findMarkers_one_vs_all(gobject = visium_brain,
method = 'scran',
expression_values = 'normalized',
cluster_column = 'leiden_clus')
topgenes_scran = scran_markers_subclusters[, head(.SD, 2), by = 'cluster']$genes
# violinplot
violinPlot(visium_brain, genes = unique(topgenes_scran), cluster_column = 'leiden_clus',
strip_text = 10, strip_position = 'right',
save_param = list(save_name = '6_d_violinplot_scran', base_width = 5))
# cluster heatmap
plotMetaDataHeatmap(visium_brain, selected_genes = topgenes_scran,
metadata_cols = c('leiden_clus'),
save_param = list(save_name = '6_e_metaheatmap_scran'))
part 7: cell-type annotation
# 1.1 create binary matrix of cell signature genes
# small example #
gran_markers = c("Nr3c2", "Gabra5", "Tubgcp2", "Ahcyl2",
"Islr2", "Rasl10a", "Tmem114", "Bhlhe22",
"Ntf3", "C1ql2")
oligo_markers = c("Efhd1", "H2-Ab1", "Enpp6", "Ninj2",
"Bmp4", "Tnr", "Hapln2", "Neu4",
"Wfdc18", "Ccp110")
di_mesench_markers = c("Cartpt", "Scn1a", "Lypd6b", "Drd5",
"Gpr88", "Plcxd2", "Cpne7", "Pou4f1",
"Ctxn2", "Wnt4")
signature_matrix = makeSignMatrixPAGE(sign_names = c('Granule_neurons',
'Oligo_dendrocytes',
'di_mesenchephalon'),
sign_list = list(gran_markers,
oligo_markers,
di_mesench_markers))
# 1.2 [shortcut] fully pre-prepared matrix for all cell types
sign_matrix_path = system.file("extdata", "sig_matrix.txt", package = 'Giotto')
brain_sc_markers = data.table::fread(sign_matrix_path)
sig_matrix = as.matrix(brain_sc_markers[,-1]); rownames(sig_matrix) = brain_sc_markers$Event
# 1.3 enrichment test with PAGE
# runSpatialEnrich() can also be used as a wrapper for all currently provided enrichment options
visium_brain = runPAGEEnrich(gobject = visium_brain, sign_matrix = sig_matrix)
# 1.4 heatmap of enrichment versus annotation (e.g. clustering result)
cell_types = colnames(sig_matrix)
plotMetaDataCellsHeatmap(gobject = visium_brain,
metadata_cols = 'leiden_clus',
value_cols = cell_types,
spat_enr_names = 'PAGE',
x_text_size = 8,
y_text_size = 8,
save_param = list(save_name="7_a_metaheatmap"))
# 1.5 visualizations
cell_types_subset = colnames(sig_matrix)[1:10]
spatCellPlot(gobject = visium_brain,
spat_enr_names = 'PAGE',
cell_annotation_values = cell_types_subset,
cow_n_col = 4,coord_fix_ratio = NULL, point_size = 0.75,
save_param = list(save_name="7_b_spatcellplot_1"))
cell_types_subset = colnames(sig_matrix)[11:20]
spatCellPlot(gobject = visium_brain, spat_enr_names = 'PAGE',
cell_annotation_values = cell_types_subset, cow_n_col = 4,
coord_fix_ratio = NULL, point_size = 0.75,
save_param = list(save_name="7_c_spatcellplot_2"))
spatDimCellPlot(gobject = visium_brain,
spat_enr_names = 'PAGE',
cell_annotation_values = c('Cortex_hippocampus', 'Granule_neurons',
'di_mesencephalon_1', 'Oligo_dendrocyte','Vascular'),
cow_n_col = 1, spat_point_size = 1,
plot_alignment = 'horizontal',
save_param = list(save_name="7_d_spatDimCellPlot", base_width=7, base_height=10))
part 8: spatial grid
visium_brain <- createSpatialGrid(gobject = visium_brain,
sdimx_stepsize = 400,
sdimy_stepsize = 400,
minimum_padding = 0)
spatPlot(visium_brain, cell_color = 'leiden_clus', show_grid = T,
grid_color = 'red', spatial_grid_name = 'spatial_grid',
save_param = list(save_name = '8_grid'))
part 9: spatial network
visium_brain <- createSpatialNetwork(gobject = visium_brain,
method = 'kNN', k = 5,
maximum_distance_knn = 400,
name = 'spatial_network')
showNetworks(visium_brain)
spatPlot(gobject = visium_brain, show_network = T,
network_color = 'blue', spatial_network_name = 'spatial_network',
save_param = list(save_name = '9_a_knn_network'))
part 10: spatial genes
## kmeans binarization
kmtest = binSpect(visium_brain, calc_hub = T, hub_min_int = 5,
spatial_network_name = 'spatial_network')
spatGenePlot(visium_brain, expression_values = 'scaled',
genes = kmtest$genes[1:6], cow_n_col = 2, point_size = 1.5,
save_param = list(save_name = '10_a_spatial_genes_km'))
## rank binarization
ranktest = binSpect(visium_brain, bin_method = 'rank',
calc_hub = T, hub_min_int = 5,
spatial_network_name = 'spatial_network')
spatGenePlot(visium_brain, expression_values = 'scaled',
genes = ranktest$genes[1:6], cow_n_col = 2, point_size = 1.5,
save_param = list(save_name = '10_b_spatial_genes_rank'))
Spatial patterns
# cluster the top 1500 spatial genes into 20 clusters
ext_spatial_genes = ranktest[1:1500,]$gene
# here we use existing detectSpatialCorGenes function to calculate pairwise distances between genes (but set network_smoothing=0 to use default clustering)
spat_cor_netw_DT = detectSpatialCorGenes(visium_brain,
method = 'network',
spatial_network_name = 'spatial_network',
subset_genes = ext_spatial_genes)
# cluster spatial genes
spat_cor_netw_DT = clusterSpatialCorGenes(spat_cor_netw_DT, name = 'spat_netw_clus', k = 20)
# visualize clusters
heatmSpatialCorGenes(visium_brain,
spatCorObject = spat_cor_netw_DT,
use_clus_name = 'spat_netw_clus',
heatmap_legend_param = list(title = NULL),
save_param = list(save_name="10_c_heatmap",
base_height = 6, base_width = 8, units = 'cm'))
table(spat_cor_netw_DT$cor_clusters$spat_netw_clus)
coexpr_dt = data.table::data.table(genes = names(spat_cor_netw_DT$cor_clusters$spat_netw_clus),
cluster = spat_cor_netw_DT$cor_clusters$spat_netw_clus)
data.table::setorder(coexpr_dt, cluster)
top30_coexpr_dt = coexpr_dt[, head(.SD, 30) , by = cluster]
# do HMRF with different betas on 500 spatial genes
my_spatial_genes <- top30_coexpr_dt$genes
hmrf_folder = paste0(results_folder,'/','11_HMRF/')
if(!file.exists(hmrf_folder)) dir.create(hmrf_folder, recursive = T)
HMRF_spatial_genes = doHMRF(gobject = visium_brain,
expression_values = 'scaled',
spatial_genes = my_spatial_genes, k = 20,
spatial_network_name="spatial_network",
betas = c(0, 10, 5),
output_folder = paste0(hmrf_folder, '/', 'Spatial_genes/SG_topgenes_k20_scaled'))
visium_brain = addHMRF(gobject = visium_brain, HMRFoutput = HMRF_spatial_genes,
k = 20, betas_to_add = c(0, 10, 20, 30, 40),
hmrf_name = 'HMRF')
spatPlot(gobject = visium_brain, cell_color = 'HMRF_k20_b.40',
point_size = 2, save_param=c(save_name="10_d_spatPlot2D_HMRF"))
Export and create Giotto Viewer
# check which annotations are available
combineMetadata(visium_brain, spat_enr_names = 'PAGE')
# select annotations, reductions and expression values to view in Giotto Viewer
viewer_folder = paste0(results_folder, '/', 'mouse_Visium_brain_viewer')
exportGiottoViewer(gobject = visium_brain,
output_directory = viewer_folder,
spat_enr_names = 'PAGE',
factor_annotations = c('in_tissue',
'leiden_clus',
'HMRF_k20_b.40'),
numeric_annotations = c('nr_genes',
'clus_25'),
dim_reductions = c('tsne', 'umap'),
dim_reduction_names = c('tsne', 'umap'),
expression_values = 'scaled',
expression_rounding = 2,
overwrite_dir = T)
生活很好,有你更好,我们2022年再见