Spatial transcriptomics (ST) enables single cell resolution gene expression analysis assessment across histology sections while preserving native tissue morphology. In this context, SpatialTime package empower users to assess differential gene expression and module score pathways across a distance gradient by establishing spatially defined reference points and calculating ST spots distances against reference spots using Euclidean distances. Thus, a distance gradient can be established allowing the evaluation of gene expression profiling based on proximity of any reference point.
Development version install:
#(install.packages("devtools")
devtools::install_github("dimitrisokolowskei/SpatialTime")
The igraph package version < 2.1.0 are
required for SpatialTime package. For instance:
library(remotes)
remove.packages("igraph") # remove package if previously installed
install_version("igraph", version = "2.0.3")
SpatialTime package requires a spatial dataset already processed and integrated. For help in generating a Seurat object, please visit Seurat vignette.
For this vignette tutorial, we provide a ST example dataset of mice subjected to tibia osteotomy obtained from Rios et al., 2024. Additional files to run the vignette can be found at zenodo repository here.
SpatialTime supports different strategies for delimiting spatial reference spots by: 1) manually defining references spots using the packages built-in Shiny App; 2) selecting single cell types based on cluster identities, or 3) manually defining references lines using imaging softwares such as Fiji/ImageJ. For tutorial purposes, we will first show how to select spots using the three different approaches possible. Then, we’ll present how to investigate and visualize gene expression and module score across these established distance gradients.
1.1 First, import required libraries and the processed Seurat object.
# Libraries
library(Seurat)
library(tidyverse)
library(SpatialTime)
library(shiny)
library(plotly)
library(monocle3)
library(reshape2)
# set.seed for reproducibilty
set.seed(12345)
# Import object
demo <- readRDS("fracture_demo.rds")
View([email protected])
# Visualize spatial data colored by specified identity
ratio <- ScaleRatio(demo) # Adjust image scale (OPTIONAL)
SpatialDimPlot(demo, images = "slice1") +
theme(aspect.ratio = ratio)
1.2 Export XY coordinates of the spatial spot clusters of interest.
Make sure the clustering of interest is set as the object active
identity. If not, clusters labels from [email protected] can
be added into Idents(). For instance:
Idents(demo) # Check cluster names in Seurat object identity
Idents(demo) <- demo$Tissue # Change active identity to those defined in the "Tissue" meta data column
# Export cell type coordinates to an output directory. For this example, we subset only the repaired cartilage and bone tissue
subset2Labels(demo, cluster = c("Cartilage","HypCH","Woven"), export.all = F, dir.out = "coord_out")
1.3 Once the coordinates from desired clusters have been exported, we next need to select our reference for gradient distance calculation. The package’s build-in Shiny app allows the visualization of individual spatial spots colored by cluster. Additionally, hoovering the mouse cursor over individual spots shows the information of which cluster that spots belongs to as well its XY coordinate.
Run Shiny app and select reference spots:
# Selecting reference spots
app <- ShinySelection(demo, id = "Tissue")
app
To navigate trough the app, use shift+left click to move
around the sample. Use the left click to select spatial
spots to be used as reference and ctrl + left click to
unselect the spots. Users can scroll with the mouse wheel or use the
+ and - signs in the top right corner to zoom
in or zoom out, respectively. In the example below, we have manually
selected spatial spots representing the central fracture line of the
bone.
For each spot selected, information on spot barcode, cluster it belongs to and XY coordinates are displayed in the Shiny App UI as below:
# First spots selected
Selected spots:
Barcode: GACCGTCAGGTCGTGA-1_1, Cluster: Cartilage, Coordinates: (379.704, -135.0951)
Barcode: CTAGTATTCGGAATTA-1_1, Cluster: Cartilage, Coordinates: (376.2911, -141.045)
Barcode: CAACTATATCGAATGC-1_1, Cluster: Cartilage, Coordinates: (372.8783, -147.0251)
...
After spots selection, click Export Selected Spots and
close the Shiny app. The id parameter have to include
[email protected] column name that contains cell types
ID’s for better visualization in the shiny app.
By importing the desired cluster coordinates and the above reference
spots selected in the shiny app, SpatialTime distance gradient can be
calculated using CoordMerge function by specifying the path
of the coord files and cell cluster name. Additionally, import the
reference spots coordinates using ShinySpots function. For
example, using the cluster labeled as Woven, it
follows:
#Import coordinates of cluster and reference spotsof interest
target <- CoordMerge("coord_out/", pattern = "Woven")
# Import reference spot coordinates
ref <- ShinySpots(demo, coord_file = "selected_spots_random.csv") # image below can be generated by changing the coord_file="selected_spots.csv"
# Calculate SpatialTime between cluster and reference
```sh
sp <- SpatialShinyTime(target, ref)
sp
Next, we can visualize distance gradients to confirm accuracy for the following steps.
# Visualize spots gradient
gradient_vis <- SpatialVis(demo, sp, spatial.by = "rel", slice = "slice1", return_obj = F)
gradient_vis +
theme(aspect.ratio = ratio)
# Calculate gradient distance values and add Spatialtime (st) values into metadata
gradient_calc <- SpatialVis(demo, sp, spatial.by = "rel", slice = "slice1", return_obj = T)
View([email protected])
# Remove spots outside regions of interest with a calculated distance of 0 to improve visualization
gradient_calc <- subset(gradient_calc, subset = st != 0)
# Continue to in "Gene Expression Assessment & Visualization" section below
As an alternative to manually reference spot selection, entire annotated clusters can be used as the reference instead.
2.1 Import Seurat’s object and ensure that cell clusters are
annotated and present in your object Idents().
# Libraries
library(Seurat)
library(tidyverse)
library(SpatialTime)
library(monocle3)
library(reshape2)
# Import NF1 data ----
demo <- readRDS("fracture_demo.rds")
View([email protected])
# Export cell type coordinates to an output directory
subset2Labels(demo, cluster = c("Cartilage","HypCH","Woven"), export.all = F, dir.out = "coord_out")
2.2 Import coordinates to be used as references, as well as clusters
of interest to calculate distance in, and run Spatial2Time
for gradient distance calculation:
# Selecting clusters of interest ----
target <- CoordMerge("coord_out", pattern = "Woven")
# Selecting clusters to be used as reference ----
ref <- CoordMerge("coord_out", pattern = "Cartilage")
# Calculate SpatialTime between clusters of interest ----
sp <- Spatial2Time(target, ref)
sp
2.3 Visualize gradient distance:
# Distance gradient visualization ----
gradient_vis <- SpatialVis(demo, sp, spatial.by = "rel", slice = "slice1", return_obj = F)
ratio <- ScaleRatio(demo) # Adjust image scale
gradient_vis +
theme(aspect.ratio = ratio)
# Add st values into metadata
gradient_calc <- SpatialVis(demo, sp, spatial.by = "rel", slice = "slice1", return_obj = T)
View([email protected])
# Subset out spots not selected as target tissue where spatialtime (st) value were not calculated
gradient_calc <- subset(gradient_calc, subset = st != 0)
# Continue to "Gene Expression Assessment & Visualization" section below
Fiji is a broadly used open source scientific image processing tool. Fiji allows drawing the reference lines of interest and exporting each delineated pixel as an XY coordinates later used for euclidean distance calculation. Fiji can be downloaded here and a brief Fiji tutorial on how draw and export references lines can be found here.
3.1 First, import your Seurat ST object using readRDS()
function. Then, we proceed using subsetLabels() which
allows us to export ST clusters coordinates as excel sheets.
# Required packages
library(Seurat)
library(tidyverse)
library(SpatialTime)
library(monocle3)
library(reshape2)
# Import dataset ----
demo <- readRDS("fracture_demo.rds")
View([email protected])
# Export clusters coordinates
subsetLabels("fracture_demo.rds", cluster = c("Cartilage","Woven"), slice.n = "slice1", dir.out = "coord_out")
3.2 Import Fiji XY coordinates previously prepared. Furthermore, we
need to match the reference line colors to their respective
tissue/region names. Be aware that the tissue names must exist in your
Seurat object identities. Notice that each slice image have its own
factor value that can be found in the .json file in each
10x output folder. Then, by running SpatialCalc() each XY
coordinate can be transformed accordingly to the slice factor.
fiji <- read.csv("Fiji_C1.csv")
colors <- c("Red", "Blue")
tissue <- c("Cartilage","Woven")
data <- SpatialCalc("Fiji_C1.csv", factor = 0.10067452, colors = colors, tissue = tissue)
3.3 At this step, SpatialTime distance are ready to be calculated. First, import your cluster type coordinates as reference and calculate the spots distances against other cluster.
# Calculate minimum spots distances from reference line of interest
file <- read.csv("coord_out/Woven_coordinates.csv")
sp <- SpatialTime(data, reference = "Cartilage", compare = file)
sp
3.4 SpatialTime distance gradient can be assessed using:
gradient_vis <- SpatialVis(demo, sp, spatial.by = "rel", slice = "slice1", return_obj = F)
gradient_vis
3.5 Adding
spatialtime values into metadata and subsetting only cells with st
values:
# Visualization spatialtime gradient ----
gradient_calc <- SpatialVis(demo, sp, spatial.by = "rel", slice = "slice1", return_obj = T)
gradient_calc <- subset(gradient_calc, subset = st != 0)
In this step, independently of spots selection approach use, st
values should be included in [email protected]. Consequently,
pseudotime can be calculated and gene expression analysis visualized as
heatmap across distance gradient. For example:
# Calculate pseudotime and visualize genes differentialy expressed across distance gradient
ps <- PseudoM3Time(gradient_calc, assay = "SCT", values = "st", return_obj = F)
hm <- gradient_heatmap(ps, rownames = F)
Genes expressed
across heatmap clusters could be obtained by:
# Obtain gene names in each heatmap clusters
genes <- GeneGet(hm, n_clusters = 3)
genes
Cluster Gene
Jph1 1 Jph1
Mcm3 2 Mcm3
Col9a1 3 Col9a1
Ptpn18 2 Ptpn18
Ankrd23 1 Ankrd23
...
By using return_obj = T Seurat object is returned
allowing for individuals gene expression visualization across distances.
Additionally, module score pathways can be assessed as follows:
# Calculate pseudotime
ps <- PseudoM3Time(gradient_calc, assay = "SCT", values = "st", return_obj = T)
GeneVis(file = ps, column = c("Col2a1", "Ihh","Sox9"), span = 0.5, signal = "gene")
# Gene list pathways
bmp <- c("Acvr1","Amh","Bmp2","Bmp4","Bmp5","Bmp6","Bmp7","Bmp8a","Bmpr1a","Bmpr1b",
"Bmpr2","Gdf5","Gdf6","Gdf7","Hamp","Hamp2","Id1","Id2","Id3","Id4",
"Inhbb","Rgma","Rgmb","Smad1","Smad4","Smad5","Smad9")
wnt <- c("Rspo3","Rspo4","Tcf7","Tcf7l1","Tcf7l2","Wnt1","Wnt10a","Wnt10b","Wnt11",
"Wnt16","Wnt2","Wnt2b","Wnt3","Wnt3a","Wnt4","Wnt5a","Wnt6","Wnt7a","Wnt7b",
"Wnt8a","Wnt8b","Wnt9a","Wnt9b","Wnt5b","Axin1","Axin2")
# Add gene modules in object with pseudotime calculated
gene_modules <- list(Module1 = bmp, Module2 = wnt)
module <- AddModuleScore(gradient_calc, features = gene_modules, assay = "SCT", name = "module", nbin = 16)
GeneVis(file = module, column = c("module1", "module2"), signal = "pathway", span = 0.5)
SpatialTime package also supports 10x genomics Visium HD analysis allowing user to calculate distance gradients in a true single cell resolution. The SpatialTime rationale for HD assays remains with minor modifications from standard cluster-based or image-based approaches. For instance:
library(Seurat)
library(tidyverse)
library(SpatialTime)
library(monocle3)
library(reshape2)
mm <- readRDS("path/seurat_object.rds")
subset2LabelsHD(mm, cluster = c("CellType1", "CellType2"))
ref <- CoordMergeHD("coord_out", pattern = "CellType1")
other <- CoordMergeHD("coord_out", pattern = "CellType2")
sp <- Spatial2TimeHD(other, ref)
gradient_vis <- SpatialVis(mm, sp, spatial.by = "rel", slice = "slice1", return_obj = F)
gradient_vis
...
For Fiji image-based analysis:
library(Seurat)
library(tidyverse)
library(SpatialTime)
library(monocle3)
library(reshape2)
mm <- readRDS("path/seurat_object.rds")
colors <- c("Red")
tissue <- c("CellType1")
data <- SpatialCalc("fiji_output.csv", factor = 1, colors = colors, tissue = tissue)
file <- read.csv("coord_out/{cluster_name}_slice1_coordinates.csv")
sp <- SpatialTimeHD(data, reference = "CellType1", compare = file)
sp
gradient_vis <- SpatialVis(mm, sp, spatial.by = "rel", slice = "slice1", return_obj = F)
gradient_vis
...
SpatialTime package was originally conceived using
monocle for spatialvalues calculation mainly to its
reliability and heatmap plotting facility. However, monocle’s newer
versions such as monocle3 brought series of performance and
analysis enhancements. Thus, we additionally provide a monocle wrapper
function that allows equivalent spatialtime calculation in the standard
SpatialTime pipeline. For instance:
library(monocle)
ps <- Pseudo2Time(gradient_calc, assay = "SCT", return_obj = F)
p <- plot_pseudotime_heatmap(ps, num_clusters = 2, cores = 2, show_rownames = F, return_heatmap = T)
p
For downstream analysis,
such as module scores, object
seurat_obj$meta.data should
be returned instead of a expression matrix. Thus, set
return_obj = T:
ps <- Pseudo2Time(fracture, assay = "SCT", return_obj = T)
R version 4.3.2 (2023-10-31 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19045)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.utf8 LC_CTYPE=English_United States.utf8 LC_MONETARY=English_United States.utf8
[4] LC_NUMERIC=C LC_TIME=English_United States.utf8
time zone: America/Chicago
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] SpatialTime_0.0.0.9000 testthat_3.2.0 devtools_2.4.5 usethis_2.2.2
loaded via a namespace (and not attached):
[1] RcppAnnoy_0.0.21 splines_4.3.2 later_1.3.1 DDRTree_0.1.5 tibble_3.2.1
[6] polyclip_1.10-6 rpart_4.1.21 lifecycle_1.0.4 rprojroot_2.0.4 globals_0.16.2
[11] processx_3.8.2 lattice_0.21-9 MASS_7.3-60 backports_1.4.1 magrittr_2.0.3
[16] limma_3.58.1 Hmisc_5.1-1 plotly_4.10.3 rmarkdown_2.28 yaml_2.3.7
[21] remotes_2.4.2.1 httpuv_1.6.12 Seurat_4.2.1 sctransform_0.4.1 askpass_1.2.0
[26] spam_2.10-0 spatstat.sparse_3.0-3 sp_2.1-1 sessioninfo_1.2.2 pkgbuild_1.4.2
[31] reticulate_1.34.0 cowplot_1.1.1 pbapply_1.7-2 RColorBrewer_1.1-3 abind_1.4-5
[36] pkgload_1.3.3 Rtsne_0.16 purrr_1.0.2 BiocGenerics_0.48.1 nnet_7.3-19
[41] ggrepel_0.9.4 irlba_2.3.5.1 listenv_0.9.0 spatstat.utils_3.1-0 pheatmap_1.0.12
[46] umap_0.2.10.0 RSpectra_0.16-1 goftest_1.2-3 spatstat.random_3.2-1 fitdistrplus_1.1-11
[51] parallelly_1.36.0 commonmark_1.9.0 leiden_0.4.3 codetools_0.2-19 xml2_1.3.5
[56] tidyselect_1.2.0 viridis_0.6.5 matrixStats_1.1.0 stats4_4.3.2 base64enc_0.1-3
[61] spatstat.explore_3.2-5 roxygen2_7.3.2 jsonlite_1.8.7 ellipsis_0.3.2 progressr_0.14.0
[66] Formula_1.2-5 ggridges_0.5.4 survival_3.5-7 HSMMSingleCell_1.22.0 tools_4.3.2
[71] ica_1.0-3 Rcpp_1.0.11 glue_1.6.2 gridExtra_2.3 xfun_0.44
[76] dplyr_1.1.4 withr_2.5.2 combinat_0.0-8 fastmap_1.1.1 xopen_1.0.0
[81] fansi_1.0.5 openssl_2.1.1 callr_3.7.3 digest_0.6.33 rcmdcheck_1.4.0
[86] R6_2.5.1 mime_0.12 colorspace_2.1-0 scattermore_1.2 tensor_1.5
[91] spatstat.data_3.0-3 monocle_2.30.1 utf8_1.2.4 tidyr_1.3.0 generics_0.1.3
[96] data.table_1.14.8 prettyunits_1.2.0 httr_1.4.7 htmlwidgets_1.6.2 uwot_0.1.16
[101] pkgconfig_2.0.3 gtable_0.3.4 lmtest_0.9-40 brio_1.1.3 htmltools_0.5.7
[106] profvis_0.3.8 dotCall64_1.1-0 tidyverse_2.0.0 SeuratObject_5.0.2 scales_1.3.0
[111] Biobase_2.62.0 png_0.1-8 knitr_1.48 rstudioapi_0.15.0 tzdb_0.4.0
[116] reshape2_1.4.4 curl_5.1.0 nlme_3.1-163 checkmate_2.3.0 cachem_1.0.8
[121] zoo_1.8-12 stringr_1.5.0 KernSmooth_2.23-22 parallel_4.3.2 miniUI_0.1.1.1
[126] foreign_0.8-85 desc_1.4.2 pillar_1.9.0 grid_4.3.2 fastICA_1.2-3
[131] vctrs_0.6.4 RANN_2.6.1 slam_0.1-50 urlchecker_1.0.1 VGAM_1.1-9
[136] promises_1.2.1 xtable_1.8-4 cluster_2.1.4 waldo_0.5.2 htmlTable_2.4.2
[141] evaluate_0.23 readr_2.1.4 cli_3.6.1 compiler_4.3.2 rlang_1.1.2
[146] crayon_1.5.2 leidenbase_0.1.25 future.apply_1.11.0 ps_1.7.5 plyr_1.8.9
[151] fs_1.6.3 stringi_1.7.12 deldir_1.0-9 viridisLite_0.4.2 munsell_0.5.0
[156] lazyeval_0.2.2 spatstat.geom_3.2-7 Matrix_1.6-4 hms_1.1.3 patchwork_1.2.0.9000
[161] future_1.33.0 ggplot2_3.5.0 statmod_1.5.0 shiny_1.7.5.1 ROCR_1.0-11
[166] igraph_2.0.3 memoise_2.0.1R version 4.3.2 (2023-10-31 ucrt)