Maintainer: Jianhai Zhang

1 Introduction

The spatialHeatmap package offers a generic and flexible environment for visualizing spatial bulk and single-cell assays in anatomical images. It colors spatial features (e.g. tissues) annotated in the images according to the quantitative abundance levels of measured biomolecules (e.g. mRNAs) using a color key. This core functionality of the package is called a spatial heatmap (SHM) plot. Single-cell data can be co-visualized in composite plots that combine SHMs with embedding plots of high-dimensional data. Additional important functionalities include the automated identification of biomolecules with spatially selective abundance patterns and clusters of biomolecules sharing similar abundance profiles.

To plot SHMs, a pair of assay data and anatomical image is required. The format of the latter should be annotated Scalable Vector Graphics (aSVG), where spatial features such as cells, tissues, and organs are annotated with unique identifiers. In addition to the public SVG repository EBI anatomogram, spatialHeatmap also supports custom aSVGs, which is one of the most important features. This tutorial explains how to create custom aSVGs for plotting SHMs. spatialHeatmap offers its own SVG repository (SHM SVG repo) for depositing aSVGs created using this tutorial (SHM SVGs). Furthermore, the Supplement provides information on converting SHM SVG format to EBI SVG format.

2 Getting Started

First, install the spatialHeatmap package from Bioconductor.

if (!requireNamespace("BiocManager", quietly = TRUE))
    install.packages("BiocManager")
BiocManager::install("spatialHeatmap")

Next, the packages required for running the sample code in this tutorial need to be loaded.

library(spatialHeatmap); library(SummarizedExperiment); library(GEOquery)

The following lists the vignette(s) of spatialHeatmap in an HTML browser. Clicking the corresponding name will open this vignette.

browseVignettes('spatialHeatmap')

3 Creating SVGs

This tutorial showcases the creation of custom aSVGs using the SVG editor Inkscape. Within Inkscape, there are three methods for generating spatial features: drawing with templates, employing geometric shapes, and utilizing GIMP.

3.1 Drawing with Templates

A template is a raster image that contains spatial features. An example template of Arabidopsis thaliana (Arabidopsis) root is provided here (Mustroph et al. 2009). Download this template and open it in Inkscape (Figure 1A). Select “Draw Bezier curves and straight lines (shift+F6)” on the left tool bar (Figure 1B).

Open the template in Inkscape.

Figure 1: Open the template in Inkscape

Select “Fill and Stroke…” under the “Object” tab on the top (Figure 2A). On the right panel “Fill and Stroke (Shift+Ctrl+F)”, set “Stroke style” 3.000 px (Figure 2B) and press “Enter” key.

Open the 'Fill and Stroke' panel.

Figure 2: Open the ‘Fill and Stroke’ panel

Press the “+” key to zoom in and select a template shape to start. Draw an outline for each shape by clicking at differencet corners of the shape (Figure 3A-B). At last, click at the start point to seal the outline (Figure 3C), then a spatial feature is created.

Drawing spatial features with a tempate.

Figure 3: Drawing spatial features with a tempate

If the created spatial feature is filled with a color, click “No paint” under the “Fill” tab on the panel “Fill and Stroke (Shift+Ctrl+F)” (Figure 4A). Then it will become transparent (Figure 4B).

Transparent spatial features.

Figure 4: Transparent spatial features

Select “Edit paths by nodes (F2)” on the left tool bar (Figure 5A), and draw a rectangle over the created spatial feature (Figure 5B). Select “Make selected nodes corner” (Figure 5C) on the top.

Turn nodes to corners.

Figure 5: Turn nodes to corners

Drag nodes and edges to well align the spatial feature with the template shape (Figure 6A). On the fill and stroke panel, under the “Fill” tab select “Flat color” and optionally adjust the color scales to label the spatial feature (Figure 6B). Then the first spatial feature is done (Figure 6C).

Refine spatial features.

Figure 6: Refine spatial features

3.2 Using Geometric Shapes

This section showcases transforming basic geometric shapes (e.g. rectangles and circles) into spatial features, serving as a method to create the second spatial feature.

Select “Create rectangles and squares (F4)” on the left (Figure 7A), and draw a rectangle object (Figure 7B). Convert this object to paths by selecting “Object to Path” under the “Path” tab on the top (Figure 6C).

Converting geometric shapes into paths.

Figure 7: Converting geometric shapes into paths

Click “No paint” under the “Fill” tab on the fill and stroke panel to make the rectangle transparent (Figure 8A). Rotate the rectangle if needed (Figure 8B). Select “Edit paths by nodes (F2)” on the left tool bar. If necessary, add a node by double-clicking on an edge (Figure 8C). Drag nodes and edges to align the rectangle with the underlying shape template (Figure 8C).

Adding nodes to rectangles.

Figure 8: Adding nodes to rectangles

Select “Edit paths by nodes (F2)” on the left tool bar (Figure 9A), and draw a rectangle over the spatial feature (Figure 9B). Select “Make selected nodes corner” on the top (Figure 9C).

Aligning rectangles with template shapes.

Figure 9: Aligning rectangles with template shapes

Drag the handles at the nodes of the spatial feature to fine adjust the edges for alignment with the template shape (Figure 10A). On the fill and stroke panel select “Flat color” under the “Fill” tab to optionally color this spatial feature (Figure 10B). Then the second spatial feature is done.

Spatial features created with geometric shapes.

Figure 10: Spatial features created with geometric shapes

3.3 Using GIMP

If shapes in the template image have clear outlines, the SVG image can be automatically extracted with GIMP. Note, unclear outlines would lead to extraction of messy spatial feature.

3.3.1 Extracting Shapes

Open the template image in GIMP (Figure 11A), then open the “Paths” panel (Figure 11B-C). Right click and select “By Color” (Figure 11D).

Selecting shapes by colors.

Figure 11: Selecting shapes by colors

Now the shapes can be selected by colors. For exmaple, first click on a whilte shape to select all shapes in white, then right click and select “To Path” (Figure 12A). After that, all the white shapes are extracted to the “Paths” panel (Figure 12B). Similarly, extract shapes of other colors.

Exporting shapes to paths.

Figure 12: Exporting shapes to paths

Click in front of each extracted shape to show the “eye” icon (Figure 13A). Mouse over the extracted shapes, right click, select “Merge Visible Paths” (Figure 13B). After merged, export the paths as an SVG image (here root_gimp.svg) (Figure 13C). Next, proceed to edit the exported SVG image in Inkscape.

Exporting shapes as an SVG file.

Figure 13: Exporting shapes as an SVG file

3.3.2 Edit the Extracted SVG

Open the exported SVG image (root_gimp.svg) in Inkscape (Figure 14A). Under ‘Object’ tab at the top, select “Fill and Stroke…” (Figure 2A). To make all shapes visible, click the image, select “Flat color” the under “Fill” tab, then adjust color scales (Figure 14B-C).

Opening the extracted SVG in Inkscape.

Figure 14: Opening the extracted SVG in Inkscape

By default, all shapes (paths) in the SVG image extracted by GIMP are combined as a whole. To separate them, first click the image then click “Break Apart” under the top “Path” tab (Figure 15A). After separated, the shape outlines are not stroked by default. To stroke the outlines, first use “Ctrl+A” to select all shapes, on the fill and stroke panel select “Flat color” under the “Stroke paint” tab (Figure 15B), then set a number under the “Stroke style” tab (e.g. 1.333 px) (Figure 15C).

Breaking combined paths.

Figure 15: Breaking combined paths

Click anywhere in the white area to unselect the whole image. Press “+” key to zoom in, then move certain shapes to expected locations if needed. To delete byproduct shapes, first select them then press the “Delete” key (Figure 16A-C).

Deleting byproduct shapes.

Figure 16: Deleting byproduct shapes

Use “Ctrl+A” to select all shapes. Click “No paint” under the “Fill” tab on the fill and stroke panel (Figure 17A). Click anywhere in the white area to unselect the whole image. Then the editing of the extracted SVG by GIMP is done. The edited SVG file (Figure 17B) is downloadable here.

Edited SVGs.

Figure 17: Edited SVGs

3.4 Dealing with Many Shapes

If the SVG image includes numerous spatial features (Figure 18A), the speed of creating SHMs in spatialHeatmap could be compromised. In such cases, a workaround is to overlay elongated and thin shapes existing in two layers to visually represent smaller shapes (Figure 18B). This strategy allows shared borders between spatial features and thus improves the runtime when spatialHeatmap extracting coordinates of the spatial features.

SVGs including many spatial features.

Figure 18: SVGs including many spatial features

4 Formatting SVGs

For plotting SHMs with spatialHeatmap, the spatial features in the SVGs should be formatted according to some conventions. This section focuses on the details of formatting SVGs. In addition, SVGs from EBI Anatomogram are also supported in spatialHeatmap.

4.1 Grouping

If a complex spatial feature consists of multile sub-features, these sub-features should be grouped rather than combined (Ctrl+K). Take the root atrichoblast epidermis feature as example. First, select the sub-features of this tissue by clicking their edges while holding down the “Shift” key (Figure 19A). Next, mouse over any edge of the selected sub-features, then right-click and choose “Group” (Figure 19B). Note, if the spatial features are not expected to be colored in SHMs, it is not necessary to group them.

Grouping spatial features.

Figure 19: Grouping spatial features

In order to make the grouped spatial features visually different from other features, the group can be colored. Sepecifically, click “Flat color” under the “Fill” tab on the fill and stroke panel (Figure 20A), then fill the group with a preferred color (Figure 20B).

Coloring the grouped spatial features.

Figure 20: Coloring the grouped spatial features

4.2 Resizing Groups

A group (e.g. root_pSCR/root endodermis in Figure 21B) could be resized by simply dragging the black arrows on the edge or changing the width (H), height (H) values on the top toolbar. In either case, in the “XML Editor” panel the resized group would have an attribute of transform with a value of matrix (Figure 21B), indicating the coordinates of this group are transformed because of resizing. spatialHeatmap does not accept this “tranform-matrix” pair in groups. To remove this attribute, simply ungroup (Ctrl+Shift+G) and regroup (Ctrl+G) the relevant spatial features.

Resizing grouped spatial features.

Figure 21: Resizing grouped spatial features

4.3 Annotating

To enable coloring based on numeric values in the assay data, it’s necessary for spatial features to be annotated with unique identifiers that correspond to their counterparts in the data. The annotated SVGs are referred to as aSVGs. For grouped features, the group rather individual features needs to be annotated. Figure 22 is the annotating of the “root_pGL2” (root atrichoblast epidermis) group. Specifically, under the “Edit” tab on the top (Figure 22A), select “XML Editor…” (Figure 22B). Click the “root_pGL2” feature to select it. On the “XML Editor (Shift+Ctrl+X)” panel, first click “id”, then type in “root_pGL2” and click “Set” at the bottom. Note, if the spatial features are not expected to be colored in SHMs, it is not necessary to annotate them.

Annotating spatial features.

Figure 22: Annotating spatial features

In addition, it is optional to add an “ontology” attribute for spatial features. Take the spatial feature “root_pGL2” (root atrichoblast epidermis) as an example. First, retrieve the ontology id for this feature at Ontology Lookup Service. Click the feature in the XML Editor, at the bottom type “ontology” and the retreived id in front of and below “Set” respectively, then click “Set” (Figure 23).

Adding ontology ids to spatial features.

Figure 23: Adding ontology ids to spatial features

Similarly, group and annotate other spatial features as required. When grouping the small vasculature features in the center, a shortcut is to draw a rectangle over them to select multiple features, instead of clicking on each one individually. Figure 24 is the final aSVG of Arabidopsis root, colors representing different spatial features.

The aSVG of Arabidopsis root

Figure 24: The aSVG of Arabidopsis root

4.4 Text Group

It is optional to include text in the aSVG. First click “Create and edit text objects (F8)” on the left tool bar (Figure 25A), then click on the target position and type text, here “root_pGL2” (Figure 25B).

Adding text to aSVGs.

Figure 25: Adding text to aSVGs

On top tool bar, click on “View and select font family, font size, and other text properties (Shift+Ctrl+T)” (Figure 26A), then on the text panel, change text styles such as font size (Figure 26B).

Changing text styles.

Figure 26: Changing text styles

Select the text object and convert it to path (Figure 27), then the text becomes a group (indicated by “svg:g” in Figure 27B).

Converting text objects to paths.

Figure 27: Converting text objects to paths

The id of a text group must have specific prefixes and suffixes to achieve the desired appearance in SHMs. Specifically, the prefix should be “text”; otherwise, the text letters in SHMs might become distorted. The suffix should be either “_localLGD” or “_globalLGD”; otherwise, the text color (black) might be missing and the text could appear transparent. If “_localLGD” is used, the text will only be present in the legend plot (Figure 33 right), while if “_globalLGD” is used, the text will be present in both the SHM (Figure 33 middle) and the legend plots. An example of a valid text group id is “text927_globalLGD”.

Text group ids.

Figure 28: Text group ids

If non-text shapes are included as legends, their ids only need to have the suffix “_localLGD” or “_globalLGD” such as “rect161_globalLGD”. Without these suffixes, the legend may appear transparent in SHMs.

Non-text legends.

Figure 29: Non-text legends

4.5 Final Grouping

All shapes, including text, need to be grouped as a whole. The id of this overall group can be random. To achieve this, select all the shapes using “Ctrl+A,” mouse over the selection, right-click, and then click “Group” (Figure 30A). It’s important to note that this overall group must be the last element in the ‘XML Editor’ (Figure 30B).

Grouping all shapes.

Figure 30: Grouping all shapes

4.6 Absolute Positions

All the shapes need to have absolute positions. To achieve so, click “Preferences…” under the “Edit” tab (Figure 31A). Next, go to “Input/Output” → “SVG Output” → “Path data” → “Path string format”, then select “Absolute” (Figure 31B). To trigger the effcts on all shapes, click “Select All in All Layers” under the “Edit” tab (Figure 31C), and use the arrow key to nudge the selection, e.g. one step forward and one step backward. Then all the shapes are rewritten and absolutely positioned. The absolut position is indicated by the capital letters (M, C, etc.) in the “d” attribute of a shape (Figure 31D).

Absolution postitions for each shape.

Figure 31: Absolution postitions for each shape

4.7 Resizing Canvas

To ensure the best overall height and width of the aSVG, go to “Document Properties…” under the “File” tab and select “Custom size” under the “Page” tab, then set “Units” to “px” and click on “Resize page to drawing or selection” (Figure 32). The fully formatted Arabidopsis root aSVG file is downloadable here.

Adjusting overall height and width of the aSVG.

Figure 32: Adjusting overall height and width of the aSVG

4.8 Naming Scheme

In spatialHeatmap, the naming convention for the aSVG file follows the pattern “<species>_[view]_shm.svg,” for example, “arabidopsis.thaliana_root.cross_shm.svg.” It’s important to note that the aSVG file name must end with “.svg,” and the beginning of the file name should only include letters, digits, dots, or underscores. Parentheses should be avoided. For instance, a name like “arabidopsis.thaliana_root.cross_shm(1).svg” is not supported.

5 Formatting the Data

When plotting SHMs, only spatial features that have common identifiers between the aSVG and assay data are colored. As a result, it’s crucial to format the assay data. The supported data containers include vector, data frame, and SummarizedExperiment (SE) (Morgan et al. 2018). This section focuses on SE. Details of the other two data containers are provided in the spatialHeatmap vignette.

For plotting SHMs, the two most important slots in SE are assay and colData. The assay slot stores the numeric data matrix, where rows and columns are biomolecules (e.g. genes) and samples respectively, while the colData slot stores experimental design information such as replicates and treatments. Formatting SE objects is essentially editing information in the colData slot.

The experimental design information can be imported to the colData slot from a tabular targets file. The target file should meet the following requirements:

  1. It contains at least two columns. One column represents spatial features (spFeature) and the other one experimental variables (variable) such as treatments. The rows in the target file correspond to the columns of the numeric data stored in the assay slot.

  2. To be colored in SHMs, the spatial features must have common identifiers between the assay data and aSVG. Note, the double underscore is a special string reserved for specific purposes in spatialHeatmap, and thus should be avoided for naming spatial features and variables.

The following example illustrates the design of a valid SummarizedExperiment object for generating SHMs. In this example, “root_pGL2” (root atrichoblast epidermis) has 2 experiment variables (“control” and “hypoxia”) and each has 2 replicates. Thus, there are 4 assays for “root_pGL2”. The same design applies to root_pCO2 (root cortex). These information is stored in a targets file target.test.

spft <- c(rep('root_pGL2', 4), rep('root_pCO2', 4))
vars <- rep(c('control', 'control', 'hypoxia', 'hypoxia'), 2)
target.test <- data.frame(spFeature=spft, variable=vars, row.names=paste0('assay', 1:8))
target.test
##        spFeature variable
## assay1 root_pGL2  control
## assay2 root_pGL2  control
## assay3 root_pGL2  hypoxia
## assay4 root_pGL2  hypoxia
## assay5 root_pCO2  control
## assay6 root_pCO2  control
## assay7 root_pCO2  hypoxia
## assay8 root_pCO2  hypoxia

The assay slot is populated with a data.frame containing random numbers. Each column corresponds to an assay in the target file, while each row corresponds to a gene.

set.seed(10)
df.se <- data.frame(matrix(sample(x=1:1000, size=160), nrow=20))
rownames(df.se) <- paste0('gene', 1:20)
colnames(df.se) <- row.names(target.test)
df.se[1:3, ]
##       assay1 assay2 assay3 assay4 assay5 assay6 assay7 assay8
## gene1    491    351    946    361     74    192    176    384
## gene2    649    392    670    729    570    761     94    612
## gene3    330    622    324    712    679    847    660    571

Next, a SummarizedExperiment object is constructed by providing the numeric and target data under the assays and colData arguments, respectively.

se <- SummarizedExperiment(assays=df.se, colData=target.test)
se
## class: SummarizedExperiment 
## dim: 20 8 
## metadata(0):
## assays(1): ''
## rownames(20): gene1 gene2 ... gene19 gene20
## rowData names(0):
## colnames(8): assay1 assay2 ... assay7 assay8
## colData names(2): spFeature variable

The replicates are aggregated by means.

se.aggr <- aggr_rep(data=se, sam.factor='spFeature', con.factor='variable', aggr='mean')
assay(se.aggr)[1:2, ]
##       root_pGL2__control root_pGL2__hypoxia root_pCO2__control root_pCO2__hypoxia
## gene1              421.0              653.5              133.0                280
## gene2              520.5              699.5              665.5                353

The aSVG file “arabidopsis.thaliana_root.cross_shm.svg” created in this tutorial are imported to an SVG object (see details here). The annotated spatial features are stored in the “feature” column.

svg.root <- read_svg('data/arabidopsis.thaliana_root.cross_shm.svg')
## Parsing: arabidopsis.thaliana_root.cross_shm.svg ... 
## CPU cores: 1 
## 
## Potential error detected in these elements: 'root_pWOL;root_pWOL'! If they are groups, please remove the 'transform' attribute with a 'matrix' value by ungrouping and regrouping the respective groups in Inkscape. If individual paths, consider deleting them in Inkscape. Otherwise, colors in spatial heatmap might be shifted!
svg.root[, 2][[1]][1:3, 1]
## # A tibble: 3 × 1
##   feature  
##   <chr>    
## 1 root_pSCR
## 2 root_pSCR
## 3 root_pSCR

Spatial features between the assay data and aSVG have common identifiers.

se.aggr$spFeature %in% svg.root[, 2][[1]]$feature
## [1] TRUE TRUE TRUE TRUE

6 Spatial Heatmaps

With the fully formatted assay data and aSVG, SHMs are plotted for gene1.

dat <- SPHM(svg=svg.root, bulk=se.aggr)
shm(data=dat, sam.factor='spFeature', con.factor='variable', ID=c("gene1"), legend.nrow=4, bar.width=0.1, legend.r=1, h=0.7)
SHMs created with a `SummarizedExperiment` object. Spatial features having common identifiers between the assay data and aSVG are colored.

Figure 33: SHMs created with a SummarizedExperiment object
Spatial features having common identifiers between the assay data and aSVG are colored.

7 Supplement

7.1 Troubleshooting

If errors occur when plotting SHMs, the following suggestions may be helpful:

  1. Make sure that spatial feature groups do not contain nested groups.

  2. SVGs are XML-like files (as shown in Figure 30B). Ensure that the SVG elements used are limited to “g,” “path,” “rect,” “ellipse,” “use,” and “title.” Using other elements could result in errors or warnings when utilizing spatialHeatmap. Note that “use” elements are not permitted within “g” elements.

  3. Carefully review the formatting conventions for both SVGs and assay data to ensure compliance.

7.2 Coverting SHM SVGs to EBI SVGs

spatialHeatmap also works with EBI SVGs that are used in Expression Atlas Anatomogram. This section illustrates the conversion of SHM SVGs to EBI SVGs.

7.2.1 SVG Attributes

Download the EBI SVG template EBI_template.svg (Figure 34A) and open it in Inkscape (Figure 34B). The template contains 2 layers “LAYER_OUTLINE” and “LAYER_EFO” (Figure 34C). The former is expected to store outline shapes that encircle all spatial feature shapes while the latter to store shapes of individual spatial features. As a template, both layers are empty (Figure 34B) except that “LAYER_OUTLINE” contains a green icon that links to Expression Atlas Licence.

EBI SVG template.

Figure 34: EBI SVG template

Note, in the EBI format, the “LAYER_OUTLINE” and “LAYER_EFO” elements start with “svg:g”, but they are actually layers, which is indicated by the “groupmode” attribute with the “layer” value (Figure 34D).

Copy “height”, “width”, “viewBox” values in the top “<svg …>” element from arabidopsis.thaliana_root.cross_shm.svg (Figure 35A) to “EBI_template.svg” (Figure 35B).

Copying SVG attributes.

Figure 35: Copying SVG attributes

If the green icon is shrunk, it can be resized. First, select it (Figure 36A), then click the lock on the top toolbar (Figure 36B), which maintains the aspect ratio. Next, increase the height (H) or width (W). Move the icon to the bottom left corner.

Resizing the green icon.

Figure 36: Resizing the green icon

7.2.2 Copying Spatial Features

Open arabidopsis.thaliana_root.cross_shm.svg in Inkscape, ungroup (Ctrl+Shift+G) the overall group (Figure 37), then select and copy all shapes.

Ungrouping the overall group.

Figure 37: Ungrouping the overall group

In “EBI_template.svg”, open layer panel (Ctrl+Shift+L) and make sure the “unlock” icon is present in front of “EFO” and “Outline” (Figure 38A). Click the “EFO” layer and paste all shapes into the “EFO” layer (Figure 38A-C).

Pasting shapes into the EBI template.

Figure 38: Pasting shapes into the EBI template

7.2.3 Annotating Spatial Features

In EBI SVGs, spatial features are annotated with unique identifiers and optional ontology ids. Take the “root_pSCR” (root endodermis) feature for example. Click the shape in “XML Editor” (Figure 39A), then click “New element node” on the top (Figure 39B). Type in “svg:title” and click “Create” (Figure 39C). Then a “title” node is created at the bottom of “root_pSCR”.

Creating title elements.

Figure 39: Creating title elements

Click the “title” node and click “New text node” at the top (Figure 40A). Then an empty text node is created inside the “title” node (Figure 40B). Click the text node and type in “root_pSCR” on the right (Figure 40C).

Adding text to text elements.

Figure 40: Adding text to text elements

Set title id as “root_pSCR” (Figure 41), then the title is done.

Adding ids to text elements.

Figure 41: Adding ids to text elements

Look up for “root endodermis” (root_pSCR) in Ontology Lookup Service (Figure 42A), and set the “root_pSCR” group id as the retrieved ontolody id “PO:0005059” (Figure 42B). Then the annotation of “root_pSCR” is done. Annotate other tissues in the same way.

Adding ontology ids.

Figure 42: Adding ontology ids

7.2.4 Outline Shapes

The “LAYER_OUTLINE” layer is used to store the optional outline shapes. For illustration purpose, a root outline is created.

Click “Outline in the layer panel (Figure 43A), and draw an outline as explained above (Figure 43B-C).

Creating outline shapes.

Figure 43: Creating outline shapes

Make sure all paths have absolute coordinates as shown in Section Absolute Path Position.

7.2.5 Resizing Canvas

Next, resize the canvas as shown in the Section Resizing Canvas.

7.2.6 Transparency

According to the EBI requirements, all shapes (“EFO” layer) need to be transparent by setting style="fill:none; stroke:none". To do so, click on “EFO” in the layer panel (Figure 44A), select all shapes (Ctrl+A), then click “No paint” under both “Fill” and “Stroke paint” in the “XML Editor” panel (Figure 44B-C). After that, only the outline shape is visible (Figure 44D).

Setting all shapes transparent.

Figure 44: Setting all shapes transparent

7.2.7 Naming Scheme

According to the naming scheme of EBI SVGs, the aSVG is named arabidopsis_thaliana.root_cross.svg, which is ready to use for plotting SHMs.

sessionInfo()
## R version 4.3.0 (2023-04-21)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04.3 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0 
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## time zone: America/Los_Angeles
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] stats4    stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] GEOquery_2.70.0             SummarizedExperiment_1.32.0 Biobase_2.62.0              GenomicRanges_1.54.1        GenomeInfoDb_1.38.1         IRanges_2.36.0              S4Vectors_0.40.2           
##  [8] BiocGenerics_0.48.1         MatrixGenerics_1.14.0       matrixStats_1.1.0           spatialHeatmap_2.9.1        knitr_1.45                  BiocStyle_2.30.0            nvimcom_0.9-128            
## [15] colorout_1.2-2             
## 
## loaded via a namespace (and not attached):
##   [1] jsonlite_1.8.8              magrittr_2.0.3              magick_2.8.1                ggbeeswarm_0.7.2            farver_2.1.1                rmarkdown_2.25              fs_1.6.3                   
##   [8] zlibbioc_1.48.0             vctrs_0.6.5                 memoise_2.0.1               DelayedMatrixStats_1.24.0   RCurl_1.98-1.13             htmltools_0.5.7             S4Arrays_1.2.0             
##  [15] BiocNeighbors_1.20.0        SparseArray_1.2.2           gridGraphics_0.5-1          sass_0.4.8                  KernSmooth_2.23-22          bslib_0.6.1                 plyr_1.8.9                 
##  [22] cachem_1.0.8                igraph_1.5.1                mime_0.12                   lifecycle_1.0.4             pkgconfig_2.0.3             rsvd_1.0.5                  Matrix_1.6-4               
##  [29] R6_2.5.1                    fastmap_1.1.1               GenomeInfoDbData_1.2.11     shiny_1.8.0                 digest_0.6.33               rsvg_2.6.0                  colorspace_2.1-0           
##  [36] AnnotationDbi_1.64.1        scater_1.30.1               dqrng_0.3.2                 irlba_2.3.5.1               shinytoastr_2.2.0           RSQLite_2.3.3               beachmat_2.18.0            
##  [43] labeling_0.4.3              fansi_1.0.5                 httr_1.4.7                  abind_1.4-5                 compiler_4.3.0              withr_2.5.2                 bit64_4.0.5                
##  [50] BiocParallel_1.36.0         viridis_0.6.4               DBI_1.1.3                   shinyAce_0.4.2              highr_0.10                  gplots_3.1.3                DelayedArray_0.28.0        
##  [57] bluster_1.12.0              gtools_3.9.5                caTools_1.18.2              tools_4.3.0                 vipor_0.4.5                 beeswarm_0.4.0              httpuv_1.6.12              
##  [64] glue_1.6.2                  promises_1.2.1              grid_4.3.0                  cluster_2.1.6               reshape2_1.4.4              generics_0.1.3              gtable_0.3.4               
##  [71] tzdb_0.4.0                  spsComps_0.3.3.0            tidyr_1.3.0                 hms_1.1.3                   data.table_1.14.8           xml2_1.3.6                  BiocSingular_1.18.0        
##  [78] ScaledMatrix_1.10.0         metapod_1.10.0              utf8_1.2.4                  XVector_0.42.0              ggrepel_0.9.4               pillar_1.9.0                stringr_1.5.1              
##  [85] yulab.utils_0.1.0           limma_3.58.1                later_1.3.1                 genefilter_1.84.0           splines_4.3.0               dplyr_1.1.4                 lattice_0.22-5             
##  [92] survival_3.5-5              bit_4.0.5                   annotate_1.80.0             tidyselect_1.2.0            SingleCellExperiment_1.24.0 locfit_1.5-9.8              Biostrings_2.70.1          
##  [99] scuttle_1.12.0              gridExtra_2.3               bookdown_0.37               edgeR_4.0.2                 shinydashboard_0.7.2        xfun_0.41                   statmod_1.5.0              
## [106] stringi_1.8.2               yaml_2.3.7                  evaluate_0.23               codetools_0.2-19            tibble_3.2.1                BiocManager_1.30.22         ggplotify_0.1.2            
## [113] cli_3.6.1                   xtable_1.8-4                munsell_0.5.0               jquerylib_0.1.4             Rcpp_1.0.11                 grImport_0.9-7              png_0.1-8                  
## [120] XML_3.99-0.16               parallel_4.3.0              ellipsis_0.3.2              readr_2.1.4                 assertthat_0.2.1            ggplot2_3.4.4               blob_1.2.4                 
## [127] scran_1.30.0                sparseMatrixStats_1.14.0    bitops_1.0-7                viridisLite_0.4.2           scales_1.3.0                purrr_1.0.2                 crayon_1.5.2               
## [134] rlang_1.1.2                 KEGGREST_1.42.0

Reference

Morgan, Martin, Valerie Obenchain, Jim Hester, and Hervé Pagès. 2018. SummarizedExperiment: SummarizedExperiment Container.
Mustroph, Angelika, M Eugenia Zanetti, Charles J H Jang, Hans E Holtan, Peter P Repetti, David W Galbraith, Thomas Girke, and Julia Bailey-Serres. 2009. “Profiling Translatomes of Discrete Cell Populations Resolves Altered Cellular Priorities During Hypoxia in Arabidopsis.” Proc Natl Acad Sci U S A 106 (44): 18843–48.