scplotter to work with 10x Xenium data prepared by Giotto¶
See: https://drieslab.github.io/giotto_workshop_2024/xenium-1.html
Go back to scplotter documentation: https://pwwang.github.io/scplotter/
InĀ [1]:
library(Giotto)
# Ensure Giotto can access a python env
genv_exists <- suppressMessages(checkGiottoEnvironment())
print(genv_exists)
python_path <- file.path(Sys.getenv("HOME"), "miniconda3", "envs", "giotto_env", "bin", "python")
Sys.setenv(RETICULATE_PYTHON = python_path)
invisible(capture.output(suppressMessages(set_giotto_python_path(python_path = python_path))))
# library(scplotter)
devtools::load_all()
Loading required package: GiottoClass
Newer devel version of GiottoClass on GitHub: 0.4.8 Giotto Suite 4.2.1
[1] TRUE
ā¹ Loading scplotter
InĀ [2]:
instrs <- createGiottoInstructions(
save_dir = "data/Xenium_giotto_workshop_results",
save_plot = FALSE,
show_plot = TRUE,
return_plot = TRUE,
python_path = python_path
)
feat_types <- c(
"rna",
"UnassignedCodeword",
"NegControlCodeword",
"NegControlProbe"
)
split_keywords = list(
c("NegControlProbe"),
c("UnassignedCodeword"),
c("NegControlCodeword)"
))
data_path <- "data/Xenium_Giotto_workshop"
# 4. Create the object
# If error, remove <data_path>/morphology_focus/morphology_focus_0000.xml
g <- createGiottoXeniumObject(
xenium_dir = data_path,
qv_threshold = 20, # qv of 20 is the default and also what 10x uses
feat_type = feat_types,
split_keyword = split_keywords,
# * if aligned images already converted to .tif, they could be added as named list
# * instead, see next section
# load_aligned_images = list(
# post_he = c(
# "path/to/...he_image.tif",
# "path/to/...he_imagealignment.csv"
# ),
# CD20 = ...,
# HER2 = ...,
# DAPI = ...
# ),
instructions = instrs
)
g <- addSpatialCentroidLocations(g, poly_info = "cell")
g <- addSpatialCentroidLocations(g, poly_info = "nucleus")
force(g)
python already initialized in this session active environment : 'giotto_env' python version : 3.10 Loading transcript level info... QV cutoff: 20.000000 Feature points removed: 80635, out of 559826 Loading boundary info 'cell' Warning message in `[.data.table`(spatial_info, , `:=`((part_col), NULL)): āTried to assign NULL to column 'label_id', but this column does not exist to removeā Loading boundary info 'nucleus' Warning message in `[.data.table`(spatial_info, , `:=`((part_col), NULL)): āTried to assign NULL to column 'label_id', but this column does not exist to removeā Loading feature metadata... loading image as 'dapi' loading image as 'bound1' loading image as 'bound2' loading image as 'bound3' calculating centroids done Start centroid calculation for polygon information layer: cell > spatial locations for polygon information layer " cell " and name " raw " already exists and will be replaced Start centroid calculation for polygon information layer: nucleus > spatial locations for polygon information layer " nucleus " and name " raw " already exists and will be replaced
An object of class giotto >Active spat_unit: cell >Active feat_type: rna dimensions : 384, 7655 (features, cells) [SUBCELLULAR INFO] polygons : cell nucleus features : rna UnassignedCodeword NegControlCodeword NegControlProbe [AGGREGATE INFO] spatial locations ---------------- [cell] raw [nucleus] raw attached images ------------------ images : 4 items... Use objHistory() to see steps and params used
InĀ [Ā ]:
# Simple Visualization
options(repr.plot.width = 8, repr.plot.height = 6)
SpatDimPlot(
g,
image = "black",
# put shapes at last
layers = c("image", "points", "shapes"),
features = head(featIDs(g)),
shapes_border_color = "cyan",
shapes_border_size = 0.1,
shapes_fill_by = "black"
)
ā¹ Loading scplotter
InĀ [4]:
x <- importXenium(data_path)
x$filetype$expression <- "mtx" # change to mtx instead of .h5 which is not in the mini dataset
ex <- x$load_expression()
featType(ex)
featType(ex[[2]]) <- c("NegControlProbe")
featType(ex[[3]]) <- c("NegControlCodeword")
featType(ex[[4]]) <- c("UnassignedCodeword")
force(ex)
g2 <- g
# append the expression info
g2 <- setGiotto(g2, ex)
# load cell metadata
cx <- x$load_cellmeta()
g2 <- setGiotto(g2, cx)
force(g2)
Loading 10x pre-aggregated expression...
- 'rna'
- 'NegControlProbe'
- 'NegControlCodeword'
- 'UnassignedCodeword'
[[1]] An object of class exprObj : "raw" spat_unit : "cell" feat_type : "rna" provenance: cell contains: 377 x 7655 sparse Matrix of class "dgTMatrix" ABCC11 . . . . . . . . . . . . . ...... ACE2 . . . . . . . . . . . . . ...... ACKR1 . . . . . . . . . . . . . ...... ........suppressing 7642 columns and 371 rows VSIG4 . . . . . . . . . . . . . ...... VWA5A . . . . . 2 . 1 . 1 . . . ...... VWF . . . 1 1 . . . . . . . . ...... First four colnames: caijolig-1 caikcgdg-1 cailegle-1 cailnfaf-1 [[2]] An object of class exprObj : "raw" spat_unit : "cell" feat_type : "NegControlProbe" provenance: cell contains: 13 x 7655 sparse Matrix of class "dgTMatrix" NegControlProbe_00042 . . . . . . . . . . . . . ...... NegControlProbe_00035 . . . . . . . . . . . . . ...... NegControlProbe_00034 . . . . . . . . . . . . . ...... ........suppressing 7642 columns and 7 rows NegControlProbe_00013 . . . . . . . . . . . . . ...... NegControlProbe_00004 . . . . . . . . . . . . . ...... NegControlProbe_00003 . . . . . . . . . . . . . ...... First four colnames: caijolig-1 caikcgdg-1 cailegle-1 cailnfaf-1 [[3]] An object of class exprObj : "raw" spat_unit : "cell" feat_type : "NegControlCodeword" provenance: cell contains: 6 x 7655 sparse Matrix of class "dgTMatrix" NegControlCodeword_0500 . . . . . . . . . . . . . . ...... NegControlCodeword_0501 . . . . . . . . . . . . . . ...... NegControlCodeword_0510 . . . . . . . . . . . . . . ...... ........suppressing 7641 columns and 1 rows NegControlCodeword_0532 . . . . . . . . . . . . . . ...... NegControlCodeword_0533 . . . . . . . . . . . . . . ...... First four colnames: caijolig-1 caikcgdg-1 cailegle-1 cailnfaf-1 [[4]] An object of class exprObj : "raw" spat_unit : "cell" feat_type : "UnassignedCodeword" provenance: cell contains: 25 x 7655 sparse Matrix of class "dgTMatrix" UnassignedCodeword_0006 . . . . . . . . . . . . . ...... UnassignedCodeword_0401 . . . . . . . . . . . . . ...... UnassignedCodeword_0409 . . . . . . . . . . . . . ...... ........suppressing 7642 columns and 19 rows UnassignedCodeword_0496 . . . . . . . . . . . . . ...... UnassignedCodeword_0498 . . . . . . . . . . . . . ...... UnassignedCodeword_0499 . . . . . . . . . . . . . ...... First four colnames: caijolig-1 caikcgdg-1 cailegle-1 cailnfaf-1
Setting expression [cell][rna] raw Setting expression [cell][NegControlProbe] raw Setting expression [cell][NegControlCodeword] raw Setting expression [cell][UnassignedCodeword] raw Loading 10X cell metadata... Warning message: āPotentially unsafe or invalid elements have been discarded from R metadata. ā¹ Type: "externalptr" ā If you trust the source, you can set `options(arrow.unsafe_metadata = TRUE)` to preserve them.ā Warning message: āPotentially unsafe or invalid elements have been discarded from R metadata. ā¹ Type: "externalptr" ā If you trust the source, you can set `options(arrow.unsafe_metadata = TRUE)` to preserve them.ā Warning message: āPotentially unsafe or invalid elements have been discarded from R metadata. ā¹ Type: "externalptr" ā If you trust the source, you can set `options(arrow.unsafe_metadata = TRUE)` to preserve them.ā Warning message: āPotentially unsafe or invalid elements have been discarded from R metadata. ā¹ Type: "externalptr" ā If you trust the source, you can set `options(arrow.unsafe_metadata = TRUE)` to preserve them.ā Warning message: āPotentially unsafe or invalid elements have been discarded from R metadata. ā¹ Type: "externalptr" ā If you trust the source, you can set `options(arrow.unsafe_metadata = TRUE)` to preserve them.ā > Cell metadata for spat_unit " cell " and feat_type " rna " already exists and will be replaced with new metadata. Setting cell metadata [cell][rna]
An object of class giotto >Active spat_unit: cell >Active feat_type: rna dimensions : 377, 7655 (features, cells) [SUBCELLULAR INFO] polygons : cell nucleus features : rna UnassignedCodeword NegControlCodeword NegControlProbe [AGGREGATE INFO] expression ----------------------- [cell][rna] raw [cell][NegControlProbe] raw [cell][NegControlCodeword] raw [cell][UnassignedCodeword] raw spatial locations ---------------- [cell] raw [nucleus] raw attached images ------------------ images : 4 items... Use objHistory() to see steps and params used
InĀ [5]:
options(repr.plot.width = 13, repr.plot.height = 5)
p1 <- SpatFeaturePlot(
g2,
image = "black",
points = FALSE, # don't show points
shapes_border_size = 0.1,
shapes_fill_by = "cell_area"
)
p2 <- SpatFeaturePlot(
g2,
image = "black",
points = FALSE, # don't show points
shapes_border_size = 0.1,
shapes_fill_by = "transcript_counts"
)
p1 + p2
InĀ [6]:
img_paths <- c(
sprintf("data/Xenium_Giotto_workshop/morphology_focus/morphology_focus_%04d.tif", 0:3),
"data/Xenium_Giotto_workshop/he_mini.tif"
)
img_list <- createGiottoLargeImageList(
img_paths,
# naming is based on the channel metadata above
names = c("DAPI", "18S", "ATP1A1/CD45/E-Cadherin", "alphaSMA/Vimentin", "HE"),
use_rast_ext = TRUE,
verbose = FALSE
)
# make some images brighter
img_list[[1]]@max_window <- 5000
img_list[[2]]@max_window <- 5000
img_list[[3]]@max_window <- 5000
# append images to gobject
g <- setGiotto(g, img_list)
InĀ [7]:
options(repr.plot.width = 12, repr.plot.height = 10)
p1 <- SpatDimPlot(g, image = "HE", points = FALSE)
p2 <- SpatDimPlot(g, image = "DAPI", shapes_feat_type = "nucleus", points = FALSE)
p3 <- SpatDimPlot(g, image = "18S", points = FALSE)
p4 <- SpatDimPlot(g, image = "ATP1A1/CD45/E-Cadherin", shapes_feat_type = "nucleus",
points = FALSE)
(p1 + p2) / (p3 + p4)
InĀ [8]:
g <- addStatistics(g2, expression_values = "raw")
g <- normalizeGiotto(g)
g <- filterGiotto(g,
expression_threshold = 1,
feat_det_in_min_cells = 1,
min_det_feats_per_cell = 5
)
# overwrite original results with those for normalized values
g <- addStatistics(g)
calculating statistics for "raw" expression Warning message in .libzero_warn(libsizes = libsizes): āTotal library size or counts for individual spat units are 0. This will likely result in normalization problems. filter (filterGiotto) or impute (imputeGiotto) spatial units.ā first scale feats and then cells Setting expression [cell][rna] normalized Setting expression [cell][rna] scaled completed 1: preparation completed 2: subset expression data completed 3: subset spatial locations completed 4: subset cell metadata completed 5: subset feature metadata completed 6: subset spatial network(s) completed 7: subsetted dimension reductions completed 8: subsetted nearest network(s) completed 9: subsetted spatial enrichment results for cell --> cell found back in polygon layer: cell for nucleus completed 10: subsetted spatial information data subset feature info: rna completed 11: subsetted spatial feature data
Feature type: rna Number of cells removed: 69 out of 7655 Number of feats removed: 0 out of 377
calculating statistics for "normalized" expression feat statistics has already been applied once; overwriting cells statistics has already been applied once; overwriting These column names were already used: area and will be overwritten
InĀ [9]:
options(repr.plot.width = 13, repr.plot.height = 5)
p1 <- SpatFeaturePlot(
g,
image = "black",
points = FALSE, # don't show points
shapes_fill_by = "nr_feats"
)
p2 <- SpatFeaturePlot(
g,
image = "black",
points = FALSE, # don't show points
shapes_fill_by = "total_expr"
)
p1 + p2
InĀ [10]:
g <- runPCA(g, feats_to_use = NULL)
g <- runUMAP(g,
dimensions_to_use = seq(15),
n_neighbors = 40 # default
)
g <- createNearestNetwork(g,
dimensions_to_use = seq(15),
k = 40
)
# takes roughly 1 min to run
g <- doLeidenCluster(g)
g@cell_metadata$cell$rna$leiden_clus <- factor(g@cell_metadata$cell$rna$leiden_clus)
Setting dimension reduction [cell][rna] pca Setting dimension reduction [cell][rna] umap
InĀ [11]:
options(repr.plot.width = 7, repr.plot.height = 6)
g <- setGiotto(g, img_list)
SpatDimPlot(
g,
image = "HE",
points = FALSE, # don't show points
shapes_fill_by = "leiden_clus"
)
InĀ [12]:
pvis <- makePseudoVisium(
extent = ext(g, prefer = c("polygon", "points"), all_data = TRUE),
# all_data = TRUE is the default
micron_size = 1
)
g <- setGiotto(g, pvis)
g <- addSpatialCentroidLocations(g, poly_info = "pseudo_visium")
activeSpatUnit(g) <- "pseudo_visium"
g <- calculateOverlap(g,
spatial_info = "pseudo_visium",
feat_info = "rna"
)
g <- overlapToMatrix(g)
g <- filterGiotto(g,
expression_threshold = 1,
feat_det_in_min_cells = 1,
min_det_feats_per_cell = 100
)
g <- normalizeGiotto(g)
g <- addStatistics(g)
g <- createSpatialNetwork(g, method = "Delaunay")
Warning message: āThe `micron_size` argument of `makePseudoVisium()` is deprecated as of <NA> 0.4.2. ā¹ Please use the `micron_scale` argument instead. ā¹ The deprecated feature was likely used in the base package. Please report the issue to the authors.ā 1738 polygons generated Setting polygon info [pseudo_visium]
Start centroid calculation for polygon information layer: pseudo_visium 1. convert polygon to raster 2. overlap raster and points 3. add polygon information 4. add points information 5. create overlap polygon information completed 1: preparation completed 2: subset expression data completed 3: subset spatial locations completed 4: subset cell metadata completed 5: subset feature metadata completed 6: subset spatial network(s) completed 7: subsetted dimension reductions completed 8: subsetted nearest network(s) completed 9: subsetted spatial enrichment results for cell for nucleus for pseudo_visium --> pseudo_visium found back in polygon layer: pseudo_visium completed 10: subsetted spatial information data subset feature info: rna completed 11: subsetted spatial feature data
Feature type: rna Number of cells removed: 1654 out of 1738 Number of feats removed: 1 out of 377
first scale feats and then cells Setting expression [pseudo_visium][rna] normalized Setting expression [pseudo_visium][rna] scaled calculating statistics for "normalized" expression Setting spatial network [pseudo_visium] Delaunay_network
InĀ [13]:
options(repr.plot.width = 7, repr.plot.height = 6)
SpatDimPlot(
g,
image = "HE",
points = FALSE, # don't show points
shapes_fill_by = "leiden_clus",
shapes_highlight = 'leiden_clus %in% c("2", "9")',
shapes_highlight_color = "red2",
shapes_highlight_stroke = 0.1
)
InĀ [14]:
options(repr.plot.width = 7, repr.plot.height = 6)
devtools::load_all()
p <- SpatDimPlot(
g,
group_by = "leiden_clus",
graph = "pseudo_visium:Delaunay_network",
spat_unit = "cell",
points_raster = FALSE,
points_size = 0.2,
points_edge_alpha = 1,
points_edge_color = "black",
points_edge_size = 0.5
)
p
ā¹ Loading scplotter
InĀ [15]:
options(repr.plot.width = 7, repr.plot.height = 6)
SpatFeaturePlot(
g,
image = "HE",
points = FALSE, # don't show points
shapes_fill_by = "total_expr",
shapes_feat_type = "pseudo_visium"
)
InĀ [2]:
x <- sessionInfo()
x <- capture.output(print(x))
# hide the BLAS/LAPACK paths
x <- x[!startsWith(x, "BLAS/LAPACK:")]
cat(paste(x, collapse = "\n"))
R version 4.4.3 (2025-02-28) Platform: x86_64-conda-linux-gnu Running under: Red Hat Enterprise Linux 8.10 (Ootpa) Matrix products: default locale: [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C [3] LC_TIME=en_US.UTF-8 LC_COLLATE=C [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 [7] LC_PAPER=en_US.UTF-8 LC_NAME=C [9] LC_ADDRESS=C LC_TELEPHONE=C [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C time zone: America/Chicago tzcode source: system (glibc) attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] scplotter_0.4.0 Giotto_4.2.1 GiottoClass_0.4.7 loaded via a namespace (and not attached): [1] fs_1.6.6 matrixStats_1.5.0 [3] spatstat.sparse_3.1-0 bitops_1.0-9 [5] devtools_2.4.5 httr_1.4.7 [7] RColorBrewer_1.1-3 repr_1.1.7 [9] profvis_0.4.0 tools_4.4.3 [11] sctransform_0.4.2 backports_1.5.0 [13] R6_2.6.1 uwot_0.2.3 [15] lazyeval_0.2.2 urlchecker_1.0.1 [17] withr_3.0.2 sp_2.2-0 [19] gridExtra_2.3 GiottoUtils_0.2.5 [21] progressr_0.15.1 quantreg_6.00 [23] cli_3.6.5 Biobase_2.62.0 [25] spatstat.explore_3.4-3 fastDummies_1.7.5 [27] iNEXT_3.0.1 Seurat_5.3.0 [29] spatstat.data_3.1-6 ggridges_0.5.6 [31] pbapply_1.7-2 pbdZMQ_0.3-14 [33] stringdist_0.9.15 parallelly_1.45.0 [35] sessioninfo_1.2.3 VGAM_1.1-13 [37] rstudioapi_0.17.1 generics_0.1.4 [39] shape_1.4.6.1 gtools_3.9.5 [41] ica_1.0-3 spatstat.random_3.4-1 [43] dplyr_1.1.4 Matrix_1.7-3 [45] S4Vectors_0.40.2 abind_1.4-5 [47] terra_1.8-42 lifecycle_1.0.4 [49] SummarizedExperiment_1.32.0 SparseArray_1.2.4 [51] Rtsne_0.17 grid_4.4.3 [53] promises_1.3.2 crayon_1.5.3 [55] miniUI_0.1.2 lattice_0.22-7 [57] cowplot_1.1.3 pillar_1.10.2 [59] GenomicRanges_1.54.1 rjson_0.2.23 [61] future.apply_1.20.0 codetools_0.2-20 [63] glue_1.8.0 spatstat.univar_3.1-3 [65] data.table_1.17.4 remotes_2.5.0 [67] vctrs_0.6.5 png_0.1-8 [69] spam_2.11-1 gtable_0.3.6 [71] assertthat_0.2.1 cachem_1.1.0 [73] S4Arrays_1.2.1 mime_0.13 [75] tidygraph_1.3.0 survival_3.8-3 [77] SingleCellExperiment_1.24.0 ellipsis_0.3.2 [79] scRepertoire_2.2.1 fitdistrplus_1.2-2 [81] ROCR_1.0-11 nlme_3.1-168 [83] usethis_3.1.0 RcppAnnoy_0.0.22 [85] evd_2.3-7.1 GenomeInfoDb_1.38.8 [87] rprojroot_2.0.4 irlba_2.3.5.1 [89] KernSmooth_2.23-26 plotthis_0.7.0 [91] colorspace_2.1-1 BiocGenerics_0.48.1 [93] tidyselect_1.2.1 compiler_4.4.3 [95] SparseM_1.84-2 xml2_1.3.8 [97] desc_1.4.3 ggdendro_0.2.0 [99] DelayedArray_0.28.0 plotly_4.10.4 [101] checkmate_2.3.2 scales_1.4.0 [103] lmtest_0.9-40 rappdirs_0.3.3 [105] stringr_1.5.1 digest_0.6.37 [107] goftest_1.2-3 spatstat.utils_3.1-4 [109] XVector_0.42.0 htmltools_0.5.8.1 [111] GiottoVisuals_0.2.12 pkgconfig_2.0.3 [113] base64enc_0.1-3 MatrixGenerics_1.14.0 [115] fastmap_1.2.0 rlang_1.1.6 [117] GlobalOptions_0.1.2 htmlwidgets_1.6.4 [119] shiny_1.10.0 farver_2.1.2 [121] zoo_1.8-14 jsonlite_2.0.0 [123] RCurl_1.98-1.17 magrittr_2.0.3 [125] GenomeInfoDbData_1.2.11 dotCall64_1.2 [127] patchwork_1.3.0 IRkernel_1.3.2 [129] Rcpp_1.0.14 evmix_2.12 [131] ggnewscale_0.5.1 viridis_0.6.5 [133] reticulate_1.42.0 truncdist_1.0-2 [135] stringi_1.8.7 ggalluvial_0.12.5 [137] ggraph_2.2.1 zlibbioc_1.48.2 [139] MASS_7.3-64 plyr_1.8.9 [141] pkgbuild_1.4.8 parallel_4.4.3 [143] listenv_0.9.1 ggrepel_0.9.6 [145] forcats_1.0.0 deldir_2.0-4 [147] graphlayouts_1.2.2 IRdisplay_1.1 [149] splines_4.4.3 gridtext_0.1.5 [151] tensor_1.5 circlize_0.4.16 [153] colorRamp2_0.1.0 igraph_2.0.3 [155] uuid_1.2-1 spatstat.geom_3.4-1 [157] cubature_2.1.4 RcppHNSW_0.6.0 [159] reshape2_1.4.4 stats4_4.4.3 [161] pkgload_1.4.0 evaluate_1.0.3 [163] SeuratObject_5.1.0 tweenr_2.0.3 [165] httpuv_1.6.15 MatrixModels_0.5-4 [167] RANN_2.6.2 tidyr_1.3.1 [169] purrr_1.0.4 polyclip_1.10-7 [171] future_1.58.0 scattermore_1.2 [173] ggplot2_3.5.2 ggforce_0.4.2 [175] xtable_1.8-4 RSpectra_0.16-2 [177] later_1.4.2 viridisLite_0.4.2 [179] gsl_2.1-8 tibble_3.2.1 [181] memoise_2.0.1 IRanges_2.36.0 [183] cluster_2.1.8.1 globals_0.18.0