Integrated browser tracks

Introduction

plot_tracks() builds a genome-browser-like view in which gene models, quantitative genomic signals, interval features, and variants share one genomic x-axis. It is intended for integrated locus inspection. Use the dedicated plot_gene(), plot_signal_*(), plot_feature_track(), or plot_variant() functions when one track needs detailed track-specific annotation.

The browser workflow is:

  1. prepare annotation plus optional signal, feature, and variant objects;
  2. select exactly one locus by gene, transcript, or explicit genomic region;
  3. choose which track classes should be displayed;
  4. control sample selection, strand, panel layout, heights, and styling;
  5. keep regional data access lazy or targeted for large datasets.

Package documentation: https://renscq.github.io/GeneTrackR/.

Installation

After Bioconductor acceptance, install GeneTrackR with BiocManager:

if (!requireNamespace("BiocManager", quietly = TRUE)) {
  install.packages("BiocManager")
}
BiocManager::install("GeneTrackR")
library(GeneTrackR)

The development version remains available from the GeneTrackR GitHub repository.

Prepare the track objects

The bundled deterministic example contains all four track classes needed for an integrated locus view.

library(GeneTrackR)

gp <- read_genepred(
  system.file(
    "extdata",
    "gtr_demo.genePredExt",
    package = "GeneTrackR"
  ),
  format = "genePredExt",
  verbose = FALSE,
  progress = FALSE
)

signal_all <- read_bwg(
  system.file(
    "extdata",
    c(
      "gtr_demo_rnaseq_plus.bedgraph",
      "gtr_demo_rnaseq_minus.bedgraph",
      "gtr_demo_riboseq_plus.bedgraph",
      "gtr_demo_riboseq_minus.bedgraph"
    ),
    package = "GeneTrackR"
  ),
  format = "bedgraph",
  sample_names = c(
    "RNA_seq_plus",
    "RNA_seq_minus",
    "Ribo_seq_plus",
    "Ribo_seq_minus"
  ),
  strand = c("+", "-", "+", "-"),
  mode = "memory",
  verbose = FALSE
)

features <- read_bed(
  system.file(
    "extdata",
    "gtr_demo_features.bed",
    package = "GeneTrackR"
  ),
  verbose = FALSE,
  progress = FALSE
)

variants <- read_vcf(
  system.file(
    "extdata",
    "gtr_demo_variants.vcf",
    package = "GeneTrackR"
  ),
  mode = "memory",
  keep_genotype = TRUE,
  verbose = FALSE,
  progress = FALSE
)

The four inputs have distinct roles:

Argument Object Role
annotation GenePred / gene-model Feature Defines genes, transcripts, exons, and the structural coordinate frame.
signal BwgTrack Adds quantitative RNA-seq, Ribo-seq, or other continuous signals.
features FeatureTrack or named list Adds interval annotations such as promoters, QTLs, or candidate regions.
variants VariantTrack or named list Adds VCF-derived variant positions.

Only annotation is required.

Choose exactly one genomic locator

Each plot_tracks() call accepts one and only one locus definition:

  • gene_id;
  • transcript_id;
  • complete chrom + start + end coordinates.

Do not combine these locator styles in the same call. Gene and transcript locators are resolved from annotation; explicit coordinates are appropriate for multi-gene or externally defined candidate intervals.

Gene-centered view

Start with the structural gene model alone.

plot_tracks(
  annotation = gp,
  gene_id = "GeneA",
  direction_mode = "transcript",
  plot_theme = "classic",
  text_size = 9
)

Add strand-specific RNA-seq and Ribo-seq signals over the same gene locus.

plot_tracks(
  annotation = gp,
  signal = signal_all,
  gene_id = "GeneA",
  samples = c("RNA_seq_plus", "Ribo_seq_plus"),
  strand = "+",
  signal_type = "bar",
  signal_palette = "Paired",
  signal_y_scale = "free",
  signal_y_ticks = "pretty",
  heights = c(
    signal = 4,
    gene = 1,
    feature = 0.8,
    variant = 0.7
  ),
  plot_theme = "classic",
  text_size = 9
)

Unlike the gene-specific signal helpers, plot_tracks() does not use strand = "auto". Select +, -, both, or ignore explicitly.

Transcript-centered view and Ribo-seq frames

A transcript locator allows GeneTrackR to associate Ribo-seq signal with one transcript model while keeping every browser panel aligned in genomic coordinates.

plot_tracks(
  annotation = gp,
  signal = signal_all,
  transcript_id = "TxA1",
  samples = c("RNA_seq_plus", "Ribo_seq_plus"),
  strand = "+",
  signal_type = "bar",
  ribo_signal_type = "auto",
  frame_palette = "Paired",
  signal_y_scale = "free",
  collapse = "none",
  direction_mode = "transcript",
  heights = c(
    signal = 4,
    gene = 1,
    feature = 0.8,
    variant = 0.7
  ),
  plot_theme = "classic",
  text_size = 9
)

With ribo_signal_type = "auto", samples whose names look like Ribo-seq/RPF/footprint tracks are rendered in frame mode when a transcript is supplied. RNA-seq remains a standard genomic signal panel. Without a transcript locator, frame rendering is not available because one transcript model is required to define the reading frame.

Explicit multi-gene region

Use genomic coordinates for a multi-gene candidate region or an interval defined outside the annotation.

browser_chrom <- "chr1"
browser_start <- 12339001
browser_end <- 12374500

plot_tracks(
  annotation = gp,
  signal = signal_all,
  chrom = browser_chrom,
  start = browser_start,
  end = browser_end,
  samples = c(
    "RNA_seq_plus",
    "RNA_seq_minus",
    "Ribo_seq_plus",
    "Ribo_seq_minus"
  ),
  strand = "both",
  signal_type = "bar",
  signal_palette = "Paired",
  signal_y_scale = "free",
  signal_y_ticks = "pretty",
  collapse = "none",
  direction_mode = "gene",
  heights = c(
    signal = 5,
    gene = 1.2,
    feature = 0.8,
    variant = 0.7
  ),
  plot_theme = "classic",
  text_size = 9
)

Use signal_y_scale = "free" when assays have substantially different ranges. Use fixed only when a shared quantitative y-axis is biologically meaningful.

Add feature and variant panels

FeatureTrack and VariantTrack objects are region-filtered internally to the selected browser interval.

plot_tracks(
  annotation = gp,
  signal = signal_all,
  features = features,
  variants = variants,
  chrom = browser_chrom,
  start = browser_start,
  end = browser_end,
  samples = c("RNA_seq_plus", "Ribo_seq_plus"),
  strand = "+",
  signal_type = "bar",
  signal_palette = "Paired",
  signal_y_scale = "free",
  signal_y_ticks = "pretty",
  gene_palette = "Paired",
  feature_color_by = "auto",
  feature_max_legend_levels = 5,
  variant_colors = c(
    SNP = "#1F78B4",
    INS = "#33A02C",
    DEL = "#E31A1C"
  ),
  direction_mode = "gene",
  heights = c(
    signal = 4,
    gene = 1.2,
    feature = 0.9,
    variant = 0.8
  ),
  plot_theme = "classic",
  text_size = 9
)
#> [GeneTrackR] Retrieved variants: 26.

The integrated feature panel deliberately uses compact labeling. feature_color_by = "auto" attempts to select an informative low-cardinality field and feature_max_legend_levels limits legend complexity. Use plot_feature_track() when individual feature labels are required.

Integrated variant panels also hide individual labels to keep dense loci readable. Use plot_variant() for detailed variant labeling, then return to plot_tracks() for the compact overview.

Named color vectors are useful when stable biological categories should keep the same color across loci.

Multiple independent feature or variant tracks

features and variants may be named lists. Each entry becomes an independent browser panel.

feature_tracks <- list(
  Regulatory = regulatory_features,
  QTL = qtl_features
)

variant_tracks <- list(
  Natural = natural_variants,
  Candidate = candidate_variants
)

plot_tracks(
  annotation = gp,
  features = feature_tracks,
  variants = variant_tracks,
  chrom = browser_chrom,
  start = browser_start,
  end = browser_end,
  text_size = 9
)

The named feature and variant entries in heights are reused for every panel of that track class.

Layout and panel heights

The default layout = "signal_top" orders available panels as:

  1. signal;
  2. feature track(s);
  3. variant track(s);
  4. gene model.

layout = "gene_top" moves the gene model above the other panels. The heights vector controls relative vertical space rather than absolute figure size.

ld_highlight <- data.frame(
  start = 12342620,
  end = 12343180
)

browser_figure <- plot_tracks(
  annotation = gp,
  signal = signal_all,
  features = features,
  variants = variants,
  chrom = browser_chrom,
  start = browser_start,
  end = browser_end,
  samples = c("RNA_seq_plus", "Ribo_seq_plus"),
  strand = "+",
  signal_type = "bar",
  signal_transform = "sqrt",
  signal_y_scale = "free",
  signal_y_ticks = "pretty",
  signal_alpha = 0.85,
  signal_bar_width = 0.9,
  feature_color_by = "auto",
  feature_max_legend_levels = 5,
  highlight = ld_highlight,
  layout = "gene_top",
  heights = c(
    signal = 4,
    gene = 1.5,
    feature = 0.9,
    variant = 0.8
  ),
  direction_mode = "gene",
  plot_theme = "classic",
  show_panel_border = FALSE,
  text_size = 9
)
#> [GeneTrackR] Retrieved variants: 26.

browser_figure

highlight uses genomic coordinates and is currently applied to the signal and gene-model panels. It is useful for marking a candidate interval while retaining the shared x-axis.

Styling responsibilities

The integrated browser exposes track-specific controls without forcing every track to share one color scale.

Track Main controls
Signal signal_palette, signal_colors, signal_transform, signal_y_scale, signal_alpha, signal_bar_width
Gene model gene_palette, gene_colors, gene_border_color, cds_height, utr_height, direction_mode, label_position, label_by
Feature feature_color_by, feature_palette, feature_colors, feature_border_color, feature_max_legend_levels
Variant variant_palette, variant_colors

The integrated view intentionally prioritizes alignment and compactness over exhaustive labels. Detailed interpretation should use the dedicated track-specific plotting articles first.

Large-dataset workflow

For real whole-genome datasets, keep the browser query regional:

  • use lazy BwgTrack access for indexed bigWig signal when possible;
  • use bgzip-compressed VCF plus .tbi / .csi and read_vcf(mode = "lazy") for regional variants;
  • preselect the signal samples needed for the biological question;
  • avoid chromosome-scale rendering of dense base-level Ribo-seq or variant tracks;
  • use dedicated track functions when one data type needs detailed labels or diagnostics.

plot_tracks() returns the assembled ggplot/patchwork figure. Figure export is handled by the standard GeneTrackR export workflow rather than duplicated here.

Session information

sessionInfo()
#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 26.04.1 LTS
#> 
#> Matrix products: default
#> BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so;  LAPACK version 3.12.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                 
#>  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
#> 
#> time zone: Etc/UTC
#> tzcode source: system (glibc)
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] GeneTrackR_0.99.2 rmarkdown_2.32   
#> 
#> loaded via a namespace (and not attached):
#>  [1] gtable_0.3.6         jsonlite_2.0.0       crayon_1.5.3        
#>  [4] compiler_4.6.1       Biostrings_2.81.9    bitops_1.1-0        
#>  [7] Rsamtools_2.29.0     GenomicRanges_1.65.4 parallel_4.6.1      
#> [10] jquerylib_0.1.4      IRanges_2.47.5       Seqinfo_1.3.2       
#> [13] scales_1.4.0         BiocParallel_1.47.0  yaml_2.3.12         
#> [16] fastmap_1.2.0        XVector_0.53.0       ggplot2_4.0.3       
#> [19] R6_2.6.1             patchwork_1.3.2      labeling_0.4.3      
#> [22] generics_0.1.4       knitr_1.52           BiocGenerics_0.59.12
#> [25] maketools_1.3.2      bslib_0.12.0         RColorBrewer_1.1-3  
#> [28] rlang_1.3.0          cachem_1.1.0         xfun_0.61           
#> [31] sass_0.4.10          sys_3.4.3            S7_0.2.2            
#> [34] otel_0.2.0           cli_3.6.6            withr_3.0.3         
#> [37] digest_0.6.39        grid_4.6.1           lifecycle_1.0.5     
#> [40] S4Vectors_0.51.10    vctrs_0.7.3          evaluate_1.0.5      
#> [43] glue_1.8.1           data.table_1.18.6.1  farver_2.1.2        
#> [46] codetools_0.2-20     buildtools_1.0.0     stats4_4.6.1        
#> [49] tools_4.6.1          htmltools_0.5.9