Visualization of categorical features
Last compiled: 18 September 2024
categorical_features.Rmd
In this tutorial, we’ll look at basic usage of the
MapLabels()
function for plotting features that represent
discrete groups of spots. This could for example be manually selected
spots or clusters. Such features as stored in the meta.data
slot of our Seurat
object and can be represented as either
‘character’ vectors of ‘factors’.
Load data
First we need to load some 10x Visium data. Here we’ll use a mouse
brain tissue dataset and a mouse colon dataset that are shipped with
semla
.
# Load data
se_mbrain <- readRDS(file = system.file("extdata",
"mousebrain/se_mbrain",
package = "semla"))
se_mbrain$sample_id <- "mousebrain"
se_mcolon <- readRDS(file = system.file("extdata",
"mousecolon/se_mcolon",
package = "semla"))
se_mcolon$sample_id <- "mousecolon"
se <- MergeSTData(se_mbrain, se_mcolon)
Map categorical features
For categorical data, we use MapLabels()
instead of
MapFeatures()
. This function allows us to color our spots
based on some column of our Seurat object containing categorical
data.
# Here we use the & operator from the patchwork R package to add a theme
# You can find more details in the 'advanced' tutorial
MapLabels(se, column_name = "sample_id", ncol = 1) &
theme(legend.position = "right")
Let’s run unsupervised clustering on our data to get slightly more interesting results to work with.
NB: It doesn’t make much sense to run data-driven clustering on two
completely different tissue types, but here we are only interested in
demonstrating how you can use MapLabels
.
se <- se |>
NormalizeData() |>
ScaleData() |>
FindVariableFeatures() |>
RunPCA() |>
FindNeighbors(reduction = "pca", dims = 1:10) |>
FindClusters(resolution = 0.2)
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
##
## Number of nodes: 5164
## Number of edges: 170850
##
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.9210
## Number of communities: 5
## Elapsed time: 0 seconds
Map clusters
We can also use the function MapLabelsSummary()
if want
to add a stacked bar plot next to the spatial plot, summarizing the
percentage of spots for each cluster in the section. If you would rather
view the actual spot count you can pass
bar_display = "count"
instead.
MapLabelsSummary(se,
column_name = "seurat_clusters",
ncol = 1,
section_number = 1) &
theme(legend.position = "none")
Overlay maps on images
And just as with MapFeatures
, we can add our H&E
images to the plots. Before we do this, we just need to load the H&E
images into our Seurat
object first with
LoadImages
.
se <- LoadImages(se, verbose = FALSE)
MapLabels(se,
column_name = "seurat_clusters",
image_use = "raw",
override_plot_dims = TRUE) +
plot_layout(guides = "collect") &
guides(fill = guide_legend(override.aes = list(size = 3),
ncol = 2)) &
theme(legend.position = "right")
Crop image
We can crop the images manually by defining a crop_area
.
The crop_area
should be a vector of length four defining
the corners of a rectangle, where the x- and y-axes are defined from
0-1.
In order to decide how this rectangle should be defined, you can get some help by adding a grid to the plot:
p <- MapLabels(se,
column_name = "seurat_clusters",
image_use = "raw",
pt_alpha = 0.5) &
theme(panel.grid.major = element_line(linetype = "dashed"), axis.text = element_text())
p
Now if we want to crop out the GALT tissue in the mouse colon sample we can cut the image at left=0.45, bottom=0.55, right=0.65, top=0.7:
p <- MapLabels(se,
column_name = "selection",
image_use = "raw",
pt_size = 5,
section_number = 2,
crop_area = c(0.45, 0.55, 0.65, 0.7))
p
And we can patch together a nice figure showing the whole tissue and the zoom in of the GALT:
# override_plot_dims=TRUE can be used to crop the image to only
# include the region that contain spots (see 'advanced' tutorial)
p_global <- MapLabels(se,
column_name = "selection",
image_use = "raw",
pt_size = 1,
section_number = 2,
override_plot_dims = TRUE) &
guides(fill = guide_legend(override.aes = list(size = 3)))
p_GALT <- MapLabels(se,
column_name = "selection",
image_use = "raw",
pt_size = 5,
section_number = 2,
crop_area = c(0.45, 0.55, 0.65, 0.7)) &
theme(plot.title = element_blank(),
plot.subtitle = element_blank(),
legend.position = "none")
(p_global / p_GALT)
Package version
-
semla
: 1.1.6
Session info
## R version 4.4.0 (2024-04-24)
## Platform: aarch64-apple-darwin20
## Running under: macOS Sonoma 14.5
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.0
##
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## time zone: Europe/Stockholm
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices datasets utils methods base
##
## other attached packages:
## [1] patchwork_1.3.0 tibble_3.2.1 semla_1.1.6 ggplot2_3.5.0
## [5] dplyr_1.1.4 SeuratObject_4.1.4 Seurat_4.3.0.1
##
## loaded via a namespace (and not attached):
## [1] RColorBrewer_1.1-3 rstudioapi_0.16.0 jsonlite_1.8.8
## [4] magrittr_2.0.3 magick_2.8.4 spatstat.utils_3.1-0
## [7] farver_2.1.2 rmarkdown_2.28 fs_1.6.4
## [10] ragg_1.3.3 vctrs_0.6.5 ROCR_1.0-11
## [13] spatstat.explore_3.3-2 forcats_1.0.0 htmltools_0.5.8.1
## [16] sass_0.4.9 sctransform_0.4.1 parallelly_1.38.0
## [19] KernSmooth_2.23-24 bslib_0.8.0 htmlwidgets_1.6.4
## [22] desc_1.4.3 ica_1.0-3 plyr_1.8.9
## [25] plotly_4.10.4 zoo_1.8-12 cachem_1.1.0
## [28] igraph_2.0.3 mime_0.12 lifecycle_1.0.4
## [31] pkgconfig_2.0.3 Matrix_1.7-0 R6_2.5.1
## [34] fastmap_1.2.0 fitdistrplus_1.2-1 future_1.34.0
## [37] shiny_1.9.1 digest_0.6.37 colorspace_2.1-1
## [40] tensor_1.5 irlba_2.3.5.1 textshaping_0.4.0
## [43] labeling_0.4.3 progressr_0.14.0 fansi_1.0.6
## [46] spatstat.sparse_3.1-0 httr_1.4.7 polyclip_1.10-7
## [49] abind_1.4-8 compiler_4.4.0 withr_3.0.1
## [52] highr_0.11 MASS_7.3-60.2 tools_4.4.0
## [55] lmtest_0.9-40 httpuv_1.6.15 future.apply_1.11.2
## [58] goftest_1.2-3 glue_1.7.0 dbscan_1.2-0
## [61] nlme_3.1-164 promises_1.3.0 grid_4.4.0
## [64] Rtsne_0.17 cluster_2.1.6 reshape2_1.4.4
## [67] generics_0.1.3 gtable_0.3.5 spatstat.data_3.1-2
## [70] tidyr_1.3.1 data.table_1.16.0 sp_2.1-4
## [73] utf8_1.2.4 spatstat.geom_3.3-2 RcppAnnoy_0.0.22
## [76] ggrepel_0.9.6 RANN_2.6.2 pillar_1.9.0
## [79] stringr_1.5.1 spam_2.10-0 later_1.3.2
## [82] splines_4.4.0 lattice_0.22-6 renv_1.0.2
## [85] survival_3.6-4 deldir_2.0-4 tidyselect_1.2.1
## [88] miniUI_0.1.1.1 pbapply_1.7-2 knitr_1.48
## [91] gridExtra_2.3 scattermore_1.2 xfun_0.47
## [94] matrixStats_1.4.1 stringi_1.8.4 lazyeval_0.2.2
## [97] yaml_2.3.10 evaluate_0.24.0 codetools_0.2-20
## [100] BiocManager_1.30.25 cli_3.6.3 uwot_0.2.2
## [103] xtable_1.8-4 reticulate_1.39.0 systemfonts_1.1.0
## [106] munsell_0.5.1 jquerylib_0.1.4 Rcpp_1.0.13
## [109] globals_0.16.3 spatstat.random_3.3-1 zeallot_0.1.0
## [112] png_0.1-8 spatstat.univar_3.0-1 parallel_4.4.0
## [115] pkgdown_2.1.0 dotCall64_1.1-1 listenv_0.9.1
## [118] viridisLite_0.4.2 scales_1.3.0 ggridges_0.5.6
## [121] leiden_0.4.3.1 purrr_1.0.2 rlang_1.1.4
## [124] cowplot_1.1.3 shinyjs_2.1.0