Set up Giotto Environment

library(Giotto)

# 1. set working directory
results_folder = 'path/to/result'

# 2. set giotto python path
# set python path to your preferred python version path
# set python path to conda env/bin/ directory if manually installed Giotto python dependencies by conda
# python_path = '/path_to_conda/.conda/envs/giotto/bin/python'
# 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 genomics recently launched a new platform to obtain spatial expression data using a Visium Spatial Gene Expression slide.

The Visium brain data to run this tutorial can be found here

Visium technology:
{ width=50% }

High resolution png from original tissue:
{ width=50% }

Part 1: Create Giotto Visium Object and visualize

## provide path to visium folder
data_path = '/path/to/Brain_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)

## show associated images with giotto object
showGiottoImageNames(visium_brain) # "image" is the default name

## check metadata
pDataDT(visium_brain)

## show plot
spatPlot2D(gobject = visium_brain, cell_color = 'in_tissue', point_size = 2,
           cell_color_code = c('0' = 'lightgrey', '1' = 'blue'), 
           show_image = T, image_name = 'image')

{ width=50% }

Part 2: Process Giotto Visium Object

## 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,
                              feat_det_in_min_cells = 50,
                              min_det_feats_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,
           cell_color = 'nr_feats', color_as_factor = F)

{ width=50% }

Part 3: Dimention Reduction

## highly variable features / genes (HVF)
visium_brain <- calculateHVF(gobject = visium_brain, save_plot = TRUE)

{ width=50% }

## run PCA on expression values (default)
gene_metadata = fDataDT(visium_brain)
featgenes = gene_metadata[hvf == 'yes' & perc_cells > 3 & mean_expr_det > 0.4]$feat_ID

## run PCA on expression values (default)
visium_brain <- runPCA(gobject = visium_brain,
                       genes_to_use = featgenes)

screePlot(visium_brain, ncp = 30)

{ width=50% }

plotPCA(gobject = visium_brain)

{ width=50% }

## run UMAP and tSNE on PCA space (default)
visium_brain <- runUMAP(visium_brain, dimensions_to_use = 1:10)
plotUMAP(gobject = visium_brain)

{ width=50% }

visium_brain <- runtSNE(visium_brain, dimensions_to_use = 1:10)
plotTSNE(gobject = visium_brain)

{ width=50% }

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)

{ width=50% }

# spatial and dimension plots
spatDimPlot(gobject = visium_brain, cell_color = 'leiden_clus',
            dim_point_size = 2, spat_point_size = 2.5)

{ width=50% }

spatDimPlot(gobject = visium_brain, cell_color = 'nr_feats', color_as_factor = F,
            dim_point_size = 2, spat_point_size = 2.5)

{ width=50% }

# dimension plots grouped by cluster
spatPlot2D(visium_brain, cell_color = 'leiden_clus',
           coord_fix_ratio = 1)

{ width=50% }

Plot with group by:

spatPlot2D(visium_brain, cell_color = 'leiden_clus',
           group_by = 'leiden_clus', coord_fix_ratio = 1,
           cow_n_col = 6, show_legend = F,
           save_param = list(base_width = 14, base_height = 14))

{ width=50% }

Highlight one or more groups:

spatPlot2D(visium_brain, cell_color = 'leiden_clus',
           select_cell_groups = '8', coord_fix_ratio = 1, show_other_cells = TRUE,
           cell_color_code = c('8' = 'red'), other_cell_color = "grey", other_point_size = 1.5,
           save_param = list(base_width = 7, base_height = 7))

{ width=50% }

Part 5: subset data

# create and show subset
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)

{ width=50% }

Part 6: marker gene detection for clusters

## ------------------ ##
## Gini markers
gini_markers_subclusters = findMarkers_one_vs_all(gobject = visium_brain,
                                                  method = 'gini',
                                                  expression_values = 'normalized',
                                                  cluster_column = 'leiden_clus',
                                                  min_feats = 20,
                                                  min_expr_gini_score = 0.5,
                                                  min_det_gini_score = 0.5)
topgenes_gini = gini_markers_subclusters[, head(.SD, 2), by = 'cluster']$feats

# violinplot
violinPlot(visium_brain, feats = unique(topgenes_gini), cluster_column = 'leiden_clus',
           strip_text = 8, strip_position = 'right',
           save_param = list(base_width = 5, base_height = 10))

{ width=50% }

# cluster heatmap
plotMetaDataHeatmap(visium_brain, selected_feats = unique(topgenes_gini),
                    metadata_cols = c('leiden_clus'),
                    x_text_size = 10, y_text_size = 10)

{ width=50% }

# umap plots
dimFeatPlot2D(visium_brain, expression_values = 'scaled',
              feats = gini_markers_subclusters[, head(.SD, 1), by = 'cluster']$feats,
              cow_n_col = 4, point_size = 0.75,
              save_param = list(base_width = 8, base_height = 8))

{ width=50% }

## ------------------ ##
# Scran Markers
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']$feats

# violinplot
violinPlot(visium_brain, feats = unique(topgenes_scran), cluster_column = 'leiden_clus',
           strip_text = 10, strip_position = 'right',
           save_param = list(base_width = 5))

{ width=50% }

# cluster heatmap
plotMetaDataHeatmap(visium_brain, selected_feats = topgenes_scran,
                    metadata_cols = c('leiden_clus'))

{ width=50% }

# umap plots
dimFeatPlot2D(visium_brain, expression_values = 'scaled',
              feats = scran_markers_subclusters[, head(.SD, 1), by = 'cluster']$feats,
              cow_n_col = 3, point_size = 1,
              save_param = list(base_width = 8, base_height = 8))

{ width=50% }

Part 7: Cell type enrichment

Visium spatial transcriptomics does not provide single-cell resolution, making cell type annotation a harder problem. Giotto provides several ways to calculate enrichment of specific cell-type signature gene lists:
- PAGE
- hypergeometric test
- Rank
- DWLS Deconvolution

7.1 PAGE enrichment

# Create PAGE matrix
# PAGE matrix should be a binary matrix with each row represent a gene marker and each column represent a cell type
# There are several ways to create PAGE matrix

# 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")

PAGE_matrix_1 = makeSignMatrixPAGE(sign_names = c('Granule_neurons',
                                                     'Oligo_dendrocytes',
                                                     'di_mesenchephalon'),
                                      sign_list = list(gran_markers,
                                                       oligo_markers,
                                                       di_mesench_markers))



sign_matrix_path = system.file("extdata", "sig_matrix.txt", package = 'Giotto')
brain_sc_markers = data.table::fread(sign_matrix_path)
PAGE_matrix_2 = as.matrix(brain_sc_markers[,-1])
rownames(PAGE_matrix_2) = brain_sc_markers$Event

visium_brain = runPAGEEnrich(gobject = visium_brain, sign_matrix = PAGE_matrix_2)



# 1.3 heatmap of enrichment versus annotation (e.g. clustering result)
cell_types_PAGE = colnames(PAGE_matrix_2)
plotMetaDataCellsHeatmap(gobject = visium_brain,
                         metadata_cols = 'leiden_clus',
                         value_cols = cell_types_PAGE,
                         spat_enr_names = 'PAGE',
                         x_text_size = 8,
                         y_text_size = 8)

{ width=50% }

# 1.4 visualizations
spatCellPlot2D(gobject = visium_brain,
               spat_enr_names = 'PAGE',
               cell_annotation_values = cell_types_PAGE[1:4],
               cow_n_col = 2,coord_fix_ratio = 1, point_size = 1.25, show_legend = T)

{ width=50% }

spatDimCellPlot2D(gobject = visium_brain,
                  spat_enr_names = 'PAGE',
                  cell_annotation_values = cell_types_PAGE[1:4],
                  cow_n_col = 1, spat_point_size = 1,
                  plot_alignment = 'horizontal',
                  save_param = list(base_width=7, base_height=10))

{ width=50% }

7.2 HyperGeometric test

visium_brain = runHyperGeometricEnrich(gobject = visium_brain,
                                       expression_values = "normalized",
                                       sign_matrix = PAGE_matrix_2)

cell_types_HyperGeometric = colnames(PAGE_matrix_2)
spatCellPlot(gobject = visium_brain,
             spat_enr_names = 'hypergeometric',
             cell_annotation_values = cell_types_HyperGeometric[1:4],
             cow_n_col = 2,coord_fix_ratio = NULL, point_size = 1.75)

{ width=50% }

Part 8: Spatial Grid

visium_brain <- createSpatialGrid(gobject = visium_brain,
                                  sdimx_stepsize = 400,
                                  sdimy_stepsize = 400,
                                  minimum_padding = 0)

showGiottoSpatGrids(visium_brain)

spatPlot2D(visium_brain, cell_color = 'leiden_clus', show_grid = T,
           grid_color = 'red', spatial_grid_name = 'spatial_grid')

{ width=50% }

Part 9: spatial network

visium_brain <- createSpatialNetwork(gobject = visium_brain,
                                     method = 'kNN', k = 5,
                                     maximum_distance_knn = 400,
                                     name = 'spatial_network')

showGiottoSpatNetworks(visium_brain)

spatPlot2D(gobject = visium_brain,  show_network= T,
           network_color = 'blue', spatial_network_name = 'spatial_network')

{ width=50% }

Part 10: Spatial Genes

## rank binarization
ranktest = binSpect(visium_brain, bin_method = 'rank',
                    calc_hub = T, hub_min_int = 5,
                    spatial_network_name = 'spatial_network')

spatFeatPlot2D(visium_brain, expression_values = 'scaled',
               feats = ranktest$feats[1:6], cow_n_col = 2, point_size = 1.5)

{ width=50% }

Part 11: Spatial Co-Expression modules

# cluster the top 500 spatial genes into 20 clusters
ext_spatial_genes = ranktest[1:1500,]$feats

# 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 = detectSpatialCorFeats(visium_brain,
                                         method = 'network',
                                         spatial_network_name = 'spatial_network',
                                         subset_feats = ext_spatial_genes)

# 2. identify most similar spatially correlated genes for one gene
top10_genes = showSpatialCorFeats(spat_cor_netw_DT, feats = 'Ptprn', show_top_feats = 10)

spatFeatPlot2D(visium_brain, expression_values = 'scaled',
               feats = top10_genes$variable[1:4], point_size = 3)

{ width=50% }

# cluster spatial genes
spat_cor_netw_DT = clusterSpatialCorFeats(spat_cor_netw_DT, name = 'spat_netw_clus', k = 20)

# visualize clusters
heatmSpatialCorFeats(visium_brain,
                     spatCorObject = spat_cor_netw_DT,
                     use_clus_name = 'spat_netw_clus',
                     heatmap_legend_param = list(title = NULL),
                     save_param = list(base_height = 6, base_width = 8, units = 'cm'))

{ width=50% }

# 4. rank spatial correlated clusters and show genes for selected clusters
netw_ranks = rankSpatialCorGroups(visium_brain,
                                  spatCorObject = spat_cor_netw_DT, use_clus_name = 'spat_netw_clus',
                                  save_param = list(  base_height = 3, base_width = 5))



top_netw_spat_cluster = showSpatialCorFeats(spat_cor_netw_DT, use_clus_name = 'spat_netw_clus',
                                            selected_clusters = 6, show_top_feats = 1)

{ width=50% }

# 5. create metagene enrichment score for clusters
cluster_genes_DT = showSpatialCorFeats(spat_cor_netw_DT, use_clus_name = 'spat_netw_clus', show_top_feats = 1)
cluster_genes = cluster_genes_DT$clus; names(cluster_genes) = cluster_genes_DT$feat_ID

visium_brain = createMetafeats(visium_brain, feat_clusters = cluster_genes, name = 'cluster_metagene')

showGiottoSpatEnrichments(visium_brain)

spatCellPlot(visium_brain,
             spat_enr_names = 'cluster_metagene',
             cell_annotation_values = netw_ranks$clusters,
             point_size = 1, cow_n_col = 5, save_param = list(base_width = 15))

{ width=50% }

Part 12: Spatially informed clusters

# top 30 genes per spatial co-expression cluster
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]
my_spatial_genes <- top30_coexpr_dt$genes



visium_brain <- runPCA(gobject = visium_brain,
                       feats_to_use = my_spatial_genes,
                       name = 'custom_pca')
visium_brain <- runUMAP(visium_brain, dim_reduction_name = 'custom_pca', dimensions_to_use = 1:20,
                        name = 'custom_umap')
visium_brain <- createNearestNetwork(gobject = visium_brain,
                                     dim_reduction_name = 'custom_pca',
                                     dimensions_to_use = 1:20, k = 5,
                                     name = 'custom_NN')
visium_brain <- doLeidenCluster(gobject = visium_brain, network_name = 'custom_NN',
                                resolution = 0.15, n_iterations = 1000,
                                name = 'custom_leiden')


cell_meta = pDataDT(visium_brain)
cell_clusters = unique(cell_meta$custom_leiden)

selected_colors = getDistinctColors(length(cell_clusters))
names(selected_colors) = cell_clusters

spatPlot2D(visium_brain, cell_color = 'custom_leiden', cell_color_code = selected_colors, coord_fix_ratio = 1)

{ width=50% }

plotUMAP(gobject = visium_brain, cell_color = 'custom_leiden', cell_color_code = selected_colors, point_size = 1.5)

{ width=50% }

Part 13: Spatial domains with HMRF

# do HMRF with different betas on top 30 genes per spatial co-expression module
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')

spatPlot2D(gobject = visium_brain, cell_color = 'HMRF_k20_b.40')

{ width=50% }



drieslab/Giotto_site_suite documentation built on April 26, 2023, 11:51 p.m.