Gene model visualization

Introduction

GeneTrackR treats the gene model as the structural coordinate frame for downstream signal, variant, haplotype, and LD visualization. The three primary plotting functions differ only in how the target interval is selected:

Task Function Typical locator
Plot all transcripts of one gene plot_gene() gene_id
Plot one transcript plot_transcript() transcript_id
Plot all models in a genomic interval plot_region() chrom, start, end

All three functions return a ggplot object and accept the same core controls for CDS/UTR geometry, direction arrows, feature labels, colors, highlighting, text size, and plot theme.

library(GeneTrackR)

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

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.

Plot a gene

plot_gene() displays all transcripts assigned to a gene by default. Genomic coordinates preserve introns and therefore provide the most direct view of exon spacing and transcript structure.

gene_figure <- plot_gene(
  gp,
  gene_id = "GeneA",
  coordinate = "genomic",
  collapse = "none",
  direction_mode = "end",
  label_position = "axis",
  label_by = "transcript",
  plot_theme = "classic",
  text_size = 10
)

gene_figure

The returned figure can be saved with the standard ggplot2 workflow:

ggplot2::ggsave(
  "GeneA.gene_model.pdf",
  plot = gene_figure,
  width = 8,
  height = 4.8
)

Transcript collapse modes

Genes with many transcript isoforms can become visually dense. collapse controls whether the original isoforms are retained or summarized before plotting.

collapse Interpretation
"none" Keep every transcript independently.
"union_exon" Build one gene-level collapsed model by combining exon boundaries with the same exon number across transcripts.
"longest" Retain the transcript with the longest genomic transcript span for each gene.

Use "none" when isoform differences are biologically important. Use a collapsed model only when the intended figure represents a gene-level structure rather than transcript-specific architecture.

plot_gene(
  gp,
  gene_id = "GeneA",
  collapse = "longest",
  coordinate = "genomic",
  direction_mode = "end",
  plot_theme = "classic",
  text_size = 10
)

Plot a transcript

plot_transcript() isolates a single transcript and supports two coordinate systems.

Genomic coordinates

coordinate = "genomic" preserves the genomic span and introns.

plot_transcript(
  gp,
  transcript_id = "TxA1",
  coordinate = "genomic",
  direction_mode = "end",
  plot_theme = "classic",
  text_size = 10
)

Spliced transcript coordinates

coordinate = "transcript" removes intronic distance and places exons consecutively in the transcript coordinate system. This representation is useful when the downstream question concerns mature RNA or translation rather than genomic distance.

plot_transcript(
  gp,
  transcript_id = "TxA1",
  coordinate = "transcript",
  direction_mode = "end",
  plot_theme = "classic",
  text_size = 10
)

Coordinate choice also changes the meaning of highlight: highlight intervals are genomic positions in genomic-coordinate plots and spliced transcript positions in transcript-coordinate plots.

Plot a genomic region

plot_region() is the structural view to use when a locus contains multiple genes or when the interval is defined independently of a gene identifier.

plot_region(
  gp,
  chrom = "chr1",
  start = 12339001,
  end = 12374500,
  mode = "overlap",
  direction_mode = "end",
  label_by = "gene",
  plot_theme = "classic",
  text_size = 10
)

The region-selection mode should be chosen explicitly when an interval cuts through gene models:

mode Selection behavior
"overlap" Include models overlapping the requested interval.
"within" Include models completely contained inside the interval.
"trim" Include overlapping models and clip their displayed structure to the requested interval.

Strand direction

GeneTrackR can draw direction information at different structural levels with direction_mode:

direction_mode Meaning
"transcript" One direction arrow for each transcript.
"gene" One direction arrow for each gene.
"end" A compact arrow at the directional end of each gene.
"none" Hide direction arrows.

For regional or browser-style figures, "end" is usually the most compact representation while still preserving strand orientation.

plot_region(
  gp,
  chrom = "chr1",
  start = 12339001,
  end = 12374500,
  direction_mode = "end",
  label_by = "gene",
  plot_theme = "classic",
  text_size = 10
)

CDS, UTR, and exon geometry

By default, coding and non-coding exon segments are drawn with different vertical thicknesses. These can be adjusted without changing genomic coordinates:

plot_gene(
  gp,
  gene_id = "GeneA",
  cds_height = 0.55,
  utr_height = 0.25,
  direction_mode = "end",
  plot_theme = "classic",
  text_size = 10
)

Set show_cds = FALSE when the distinction between CDS and UTR is not required.

Labels

label_position and label_by are independent controls:

  • label_position = "axis" places identifiers on the y axis;
  • label_position = "feature" places identifiers directly on the model;
  • label_by = "gene" uses gene IDs;
  • label_by = "transcript" uses transcript IDs.
plot_gene(
  gp,
  gene_id = "GeneA",
  label_position = "feature",
  label_by = "transcript",
  direction_mode = "end",
  plot_theme = "classic",
  text_size = 10
)

Highlight an interval

highlight accepts a data frame with start and end columns. Optional grouping or label columns can be retained for more complex overlays.

highlight_interval <- data.frame(
  start = 12343000,
  end = 12345500
)

plot_gene(
  gp,
  gene_id = "GeneA",
  coordinate = "genomic",
  highlight = highlight_interval,
  direction_mode = "end",
  plot_theme = "classic",
  text_size = 10
)

Do not reuse genomic highlight coordinates in a transcript-coordinate plot without converting them to the spliced transcript coordinate system first.

Colors and borders

Use gene_palette for automatic discrete colors or gene_colors for an exact feature mapping. Explicit mappings are preferable when figures must remain comparable across analyses.

plot_gene(
  gp,
  gene_id = "GeneA",
  gene_colors = c(
    UTR = "#66C2A5",
    CDS = "#FC8D62",
    exon = "#8DA0CB"
  ),
  gene_border_color = "black",
  direction_mode = "end",
  plot_theme = "classic",
  text_size = 10
)

gene_border_color = NA removes feature borders.

Choosing the structural view

A useful rule is to select the coordinate system before adjusting appearance:

  1. use plot_region() for a locus containing several genes;
  2. use plot_gene() when transcript architecture within one gene matters;
  3. use plot_transcript(..., coordinate = "genomic") when one isoform must remain on the genome;
  4. use plot_transcript(..., coordinate = "transcript") for mature-transcript or translation-oriented interpretation;
  5. only then adjust collapse, labels, direction arrows, highlights, and colors.

The same annotation object can be passed directly to plot_signal_gene(), plot_signal_transcript(), plot_signal_region(), and plot_tracks(), so the structural coordinate definition remains consistent when signal or variant layers are added.

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       zip_3.0.2            Rcpp_1.1.2          
#>  [7] Biostrings_2.81.9    bitops_1.1-0         Rsamtools_2.29.0    
#> [10] GenomicRanges_1.65.4 parallel_4.6.1       jquerylib_0.1.4     
#> [13] IRanges_2.47.5       Seqinfo_1.3.2        scales_1.4.0        
#> [16] BiocParallel_1.47.0  yaml_2.3.12          fastmap_1.2.0       
#> [19] XVector_0.53.0       ggplot2_4.0.3        R6_2.6.1            
#> [22] patchwork_1.3.2      labeling_0.4.3       generics_0.1.4      
#> [25] openxlsx_4.2.9       knitr_1.52           BiocGenerics_0.59.12
#> [28] maketools_1.3.2      bslib_0.12.0         RColorBrewer_1.1-3  
#> [31] rlang_1.3.0          stringi_1.8.9        cachem_1.1.0        
#> [34] xfun_0.61            sass_0.4.10          sys_3.4.3           
#> [37] S7_0.2.2             otel_0.2.0           cli_3.6.6           
#> [40] withr_3.0.3          digest_0.6.39        grid_4.6.1          
#> [43] lifecycle_1.0.5      S4Vectors_0.51.10    vctrs_0.7.3         
#> [46] evaluate_1.0.5       glue_1.8.1           data.table_1.18.6.1 
#> [49] farver_2.1.2         codetools_0.2-20     buildtools_1.0.0    
#> [52] stats4_4.6.1         tools_4.6.1          htmltools_0.5.9