In this vignette we will demonstrate how to visualize single-cell data in genome-browser-track style plots with Signac.

To demonstrate we’ll use the human PBMC dataset processed in this vignette.

library(Signac)

pbmc <- readRDS("../vignette_data/pbmc.rds")

There are several different genome browser style plot types available in Signac, including accessibility tracks, gene annotations, peak coordinate, genomic links, and fragment positions.

## Plotting aggregated signal

The main plotting function in Signac is CoveragePlot(), and this computes the averaged frequency of sequenced DNA fragments for different groups of cells within a given genomic region.

cov_plot <- CoveragePlot(
object = pbmc,
region = "chr2-87011729-87035519",
annotation = FALSE,
peaks = FALSE
)
cov_plot

We can also request regions of the genome by gene name. This will use the gene coordinates stored in the Seurat object to determine which genomic region to plot

CoveragePlot(
object = pbmc,
region = "CD8A",
annotation = FALSE,
peaks = FALSE
)

## Plotting gene annotations

Gene annotations within a given genomic region can be plotted using the AnnotationPlot() function.

gene_plot <- AnnotationPlot(
object = pbmc,
region = "chr2-87011729-87035519"
)
gene_plot

## Plotting peak coordinates

Peak coordinates within a genomic region can be plotted using the PeakPlot() function.

peak_plot <- PeakPlot(
object = pbmc,
region = "chr2-87011729-87035519"
)
peak_plot

## Plotting per-cell fragment abundance

While the CoveragePlot() function computes an aggregated signal within a genomic region for different groups of cells, sometimes it’s also useful to inspect the frequency of sequenced fragments within a genomic region for individual cells, without aggregation. This can be done using the TilePlot() function.

tile_plot <- TilePlot(
object = pbmc,
region = "chr2-87011729-87035519",
idents = c("CD4 Memory", "CD8 Effector")
)
tile_plot

By default, this selects the top 100 cells for each group based on the total number of fragments in the genomic region. The genomic region is then tiled and the total fragments in each tile counted for each cell, and the resulting counts for each position displayed as a heatmap.

## Plotting additional data alongside genomic tracks

Multimodal single-cell datasets generate multiple experimental measurements for each cell. Several methods now exist that are capable of measuring single-cell chromatin data (such as chromatin accessibility) alongside other measurements from the same cell, such as gene expression or mitochondrial genotype. In these cases it’s often informative to visualize the multimodal data together in a single plot. This can be achieved using the ExpressionPlot() function. This is similar to the VlnPlot() function in Seurat, but is designed to be incorportated with genomic track plots generated by CoveragePlot().

expr_plot <- ExpressionPlot(
object = pbmc,
features = "CD8A",
assay = "RNA"
)
expr_plot

We can create similar plots for multiple genes at once simply by passing a list of gene names

ExpressionPlot(
object = pbmc,
features = c("CD8A", "CD4"),
assay = "RNA"
)

## Combining genomic tracks

Above we’ve demonstrated how to generate individual tracks and panels that can be combined into a single plot for a single genomic region. These panels can be easily combined using the CombineTracks() function.

CombineTracks(
plotlist = list(cov_plot, tile_plot, peak_plot, gene_plot, link_plot),
expression.plot = expr_plot,
heights = c(10, 6, 1, 2, 3),
widths = c(10, 1)
)

The heights and widths parameters control the relative heights and widths of the individual tracks, according to the order that the tracks appear in the plotlist. The CombineTracks() function ensures that the tracks are aligned vertically and horizontally, and moves the x-axis labels (describing the genomic position) to the bottom of the combined tracks.

## Generating multiple tracks

Above we’ve shown how to create genomic plot panels individually and how to combine them. This allows more control over how each panel is constructed and how they’re combined, but involves multiple steps. For convenience, we’ve included the ability to generate and combine different panels automatically in the CoveragePlot() function, through the annotation, peaks, tile, and features arguments. We can generate a similar plot to that shown above in a single function call:

CoveragePlot(
object = pbmc,
region = "chr2-87011729-87035519",
features = "CD8A",
annotation = TRUE,
peaks = TRUE,
tile = TRUE,
)

Notice that in this example we create the tile plot for every group of cells that is shown in the coverage track, whereas above we were able to create a plot that showed the aggregated coverage for all groups of cells and the tile plot for only the CD4 memory cells and the CD8 effector cells. A higher degree of customization is possible when creating each track separately.

## Interactive visualization

Above we demonstrated the different types of plots that can be constructed using Signac. Often when exploring genomic data it’s useful to be able to interactively browse through different regions of the genome and adjust tracks on the fly. This can be done in Signac using the CoverageBrowser() function. This provides all the same functionality of the CoveragePlot() function, except that we can scroll upstream/downstream, zoom in/out of regions, navigate to new region, and adjust which tracks are shown or how the cells are grouped. In exploring the data interactively, often you will find interesting plots that you’d like to save for viewing later. We’ve included a “Save plot” button that will add the current plot to a list of plots that is returned when the interactive session is ended. Here’s a recorded demonstration of the CoverageBrowser() function:

Session Info

sessionInfo()
## R version 4.1.3 (2022-03-10)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04.4 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
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] stats4    stats     graphics  grDevices utils     datasets  methods
## [8] base
##
## other attached packages:
## [1] GenomicRanges_1.46.1 GenomeInfoDb_1.30.1  IRanges_2.28.0
## [4] S4Vectors_0.32.4     BiocGenerics_0.40.0  Signac_1.7.0
##
## loaded via a namespace (and not attached):
##  [1] bitops_1.0-7           fs_1.5.2               rprojroot_2.0.3
##  [4] tools_4.1.3            bslib_0.3.1            utf8_1.2.2
##  [7] R6_2.5.1               irlba_2.3.5            rgeos_0.5-9
## [10] DBI_1.1.1              colorspace_2.0-3       sp_1.4-7
## [13] tidyselect_1.1.2       compiler_4.1.3         progressr_0.10.0
## [16] textshaping_0.3.6      cli_3.2.0              desc_1.4.0
## [19] labeling_0.4.2         sass_0.4.1             scales_1.2.0
## [22] pbapply_1.5-0          pkgdown_1.6.1.9001     systemfonts_1.0.3
## [25] stringr_1.4.0          digest_0.6.29          Rsamtools_2.10.0
## [28] rmarkdown_2.11         XVector_0.34.0         pkgconfig_2.0.3
## [31] htmltools_0.5.2        parallelly_1.31.1      fastmap_1.1.0
## [34] highr_0.9              rlang_1.0.2            jquerylib_0.1.4
## [37] generics_0.1.2         farver_2.1.0           jsonlite_1.8.0
## [40] BiocParallel_1.28.3    dplyr_1.0.8            RCurl_1.98-1.6
## [43] magrittr_2.0.3         GenomeInfoDbData_1.2.7 patchwork_1.1.1
## [46] Matrix_1.4-1           Rcpp_1.0.8.3           munsell_0.5.0
## [49] fansi_1.0.3            lifecycle_1.0.1        stringi_1.7.6
## [52] yaml_2.3.5             MASS_7.3-56            zlibbioc_1.40.0
## [55] grid_4.1.3             parallel_4.1.3         listenv_0.8.0
## [58] crayon_1.5.1           lattice_0.20-45        Biostrings_2.62.0
## [61] knitr_1.36             pillar_1.7.0           future.apply_1.9.0
## [64] codetools_0.2-18       fastmatch_1.1-3        glue_1.6.2
## [67] evaluate_0.14          SeuratObject_4.1.0     data.table_1.14.2
## [70] tweenr_1.0.2           vctrs_0.4.1            polyclip_1.10-0
## [73] gtable_0.3.0           purrr_0.3.4            tidyr_1.2.0
## [76] future_1.26.1          assertthat_0.2.1       cachem_1.0.6
## [79] ggplot2_3.3.5          xfun_0.28              ggforce_0.3.3
## [82] ragg_1.2.0             RcppRoll_0.3.0         tibble_3.1.6
## [85] memoise_2.0.0          globals_0.15.0         ellipsis_0.3.2