--- title: "`SpatialData.plot`" date: "`r format(Sys.Date(), '%B %d, %Y')`" package: "`r BiocStyle::pkg_ver('SpatialData.plot')`" output: BiocStyle::html_document: toc: true toc_depth: 1 toc_float: true vignette: | %\VignetteIndexEntry{SpatialData.plot} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} abstract: > `SpatialData.plot` provides a visualization suit for `SpatialData` objects in `ggplot2`-style, with support for multi-scale `images` and `labels`, `points` and `shapes`, and layering of elements into composite plots. For the latter, POINT, POLYGON, and MULTIPOLYGON geometries are supported. For all but `images`, there is support to pass information from annotation `tables` as aesthetics (e.g., `colData` or `assay` data). For `images`, auto-contrasting and multi-channel color merging are supported. Each layer returns a standard `ggplot` object, allowing for customization (e.g., using `ggnewscale` for layer-specific fill/color scales), or multi-panel arrangement (e.g., using `patchwork`). --- ```{r setup, include=FALSE} knitr::opts_chunk$set(cache=FALSE, message=FALSE, warning=FALSE) ``` # Installation {-} `SpatialData.plot` can be installed as follows: ```{r inst, eval=FALSE} if (require("BiocManager", quietly=TRUE)) install.packages("BiocManager") BiocManager::install("SpatialData.plot") ``` For the purpose of this vignette, we require the following dependencies: ```{r load-deps} library(ggplot2) library(patchwork) library(ggnewscale) library(spatialdataR) library(SpatialData.plot) ``` # Introduction The `SpatialData.plot` package contains a set of plotting functions for spatial omics data stored as [SpatialData](https://spatialdata.scverse.org/en/latest/index.html) `.zarr` files that follow [OME-NGFF specs](https://ngff.openmicroscopy.org/latest/#image-layout). Each `SpatialData` object is composed of five layers: images, labels, shapes, points, and tables. Each layer may contain an arbitrary number of elements. Images and labels are represented as `ZarrArray`s (`r BiocStyle::Biocpkg("Rarr")`). Points and shapes are represented as `r BiocStyle::CRANpkg("arrow")` objects linked to an on-disk *.parquet* file. As such, all data are represented out of memory. Element annotation as well as cross-layer summarizations (e.g., count matrices) are represented as `r BiocStyle::Biocpkg("SingleCellExperiment")` as tables. **We here demonstrate package functionality using a trivial example dataset. For more realistic technology-focused examples, we refer readers to the companion [demo website](https://helenalc.github.io/SpatialData.demo).** ```{r read-data} x <- file.path("extdata", "blobs.zarr") x <- system.file(x, package="SpatialData.plot") (x <- readSpatialData(x)) ``` # Visualization `SpatialData.plot` provides 5 user-facing plotting functions: - `plotSpatialData()` renders a base (blank) `ggplot` with simple aesthetics and, importantly, a fixed axial ratio as to not distort spatial coordinates. - `plotImage/Label/Point/Shape()` render specific `SpatialData` elements; each requires specification of the element index/name `i`, and coordinate system `j` (by default, the first available element/system will be rendered); different functions further accept different arguments to control aesthetics. ## Images `Image/LabelArray`s are linked to potentially multiscale .zarr stores. Their show method includes the scales available for a given element: ```{r ms-show} image(x, "blobs_image") image(x, "blobs_multiscale_image") ``` Internally, multiscale `ImageArray`s are stored as a list of `ZarrArray`, e.g.: ```{r ms-dims} i <- image(x, "blobs_multiscale_image") vapply(data(i, k=NULL), dim, numeric(3)) ``` To retrieve a specific scale's `ZarrArray`, we can use `data(., k)`, where `k` specifies the target scale. This also works for plotting: ```{r ms-plot} wrap_plots(nrow=1, lapply(seq(3), \(.) plotSpatialData(x) + plotImage(i=2, k=.))) ``` ## Labels Like `image`s, `label`s are represented as `ZarrArray`. Array values, however, are integers that correspond to different instances, typically linked to a `table` of annotations (e.g., expression values, observation metadata, etc.). ```{r plotLabel, fig.width=9, fig.height=3.5} i <- "blobs_labels" t <- getTable(x, i) t$id <- sample(letters, ncol(t)) table(x) <- t p <- plotSpatialData(x) pal_d <- hcl.colors(10, "Spectral") pal_c <- hcl.colors(9, "Inferno")[-9] a <- p + plotLabel(i, pal="grey") # binary b <- p + plotLabel(i, c="id", pal=pal_d) # metadata c <- p + plotLabel(i, c="channel_1_sum", pal=pal_c) # assay (a | b | c) + plot_layout(guides="collect") & theme(legend.position="bottom") ``` ## Points Elements of the `points` layer are rendered using `geom_point()`, and accepts both discrete and continuous color specifications. ```{r plotPoint, fig.width=10, fig.height=3} i <- "blobs_points" a <- p + plotPoint(i=i) b <- p + plotPoint(i=i, col="genes") # discrete c <- p + plotPoint(i=i, col="instance_id") # continuous (a | b | c) ``` ## Shapes For demonstration, we render each `shape` element present in the object, which includes all possible types: circles and (multi)polygons. ```{r plotShape, fig.width=8, fig.height=3} p <- plotSpatialData(x) a <- p + labs(title="polygons") + plotShape(i="blobs_polygons") b <- p + labs(title="multipolygons") + plotShape(i="blobs_multipolygons") c <- p + labs(title="circles") + plotShape(i="blobs_circles") (a | b | c) ``` ## Layering Several `SpatialData` elements (images, labels, points, shapes) can be layered on-top of each other in `ggplot`-style using the `+`-operator. The return value of each such call remains a `ggplot` object, which accepts additional aesthetics. Note that specifying layer-specific fill/color requires setting up a new scale with `ggnewscale::new_scale_fill/color()`; an example is as follows: ```{r blobs-plot, fig.width=8, fig.height=5} p <- plotSpatialData(x) # joint all <- p + plotImage() + plotLabel(a=1/3) + plotShape(i=1) + plotShape(i=3) + new_scale_color() + plotPoint(col="genes") + labs(title="layered") # split one <- list( p + plotImage() + labs(title="image"), p + plotLabel() + labs(title="labels"), p + plotShape(i=1) + labs(title="circles"), p + plotShape(i=3) + labs(title="polygons"), p + plotPoint(col="genes") + labs(title="points")) wrap_plots(c(list(all), one), nrow=2) ``` ## Scalebars A scalebar of a specified length (in the annotated unit) can be added using the `scalebar()` function. ```{r} plotSpatialData(x) + plotImage() + plotLabel(a=1/3) + scalebar(len=10, xrel=0.05, yrel=0.95) ``` # Session info ```{r sessionInfo, echo=FALSE} sessionInfo() ```