Skip to contents

Overview

clover includes pre-computed tRNA cloverleaf SVGs that can be annotated with modification highlights, outline circles, text color changes, and linkage arcs. This vignette walks through every customization option for plot_tRNA_structure() and related functions.

Discovering available structures

Bundled SVGs are organized by organism. Use structure_organisms() to list available organisms and structure_trnas() to list tRNAs within an organism.

structure_organisms()
#> [1] "Escherichia coli"         "Homo sapiens"            
#> [3] "Saccharomyces cerevisiae"
head(structure_trnas("Escherichia coli"))
#> [1] "tRNA-Ala-GGC" "tRNA-Ala-TGC" "tRNA-Arg-ACG" "tRNA-Arg-CCG" "tRNA-Arg-CCT"
#> [6] "tRNA-Arg-TCT"

Basic structure

The simplest call renders the bare cloverleaf with base-pair lines, nucleotide letters, and position markers every 10 nucleotides.

svg <- plot_tRNA_structure("tRNA-Glu-TTC", "Escherichia coli")
tRNA-Glu-TTCGUCCCCUUCGUCUAGAGGCCCAGGACACCGCCCUUUCACGGCGGUAACAGGGGUUCGAAUCCCCUAGGGGACGCCAA5'Glu10203040506070

Position markers

By default, grey position numbers are drawn every 10 nucleotides. Set position_markers = FALSE to hide them.

svg <- plot_tRNA_structure(
  "tRNA-Glu-TTC",
  "Escherichia coli",
  position_markers = FALSE
)
tRNA-Glu-TTCGUCCCCUUCGUCUAGAGGCCCAGGACACCGCCCUUUCACGGCGGUAACAGGGGUUCGAAUCCCCUAGGGGACGCCAA5'Glu

Modification highlights

Modifications are shown as colored filled circles behind nucleotide letters. The modifications argument takes a tibble with pos and mod1 columns. Output from modomics_mods() works directly after filtering to the tRNA of interest.

fasta_path <- clover_example("ecoli/trna_only.fa.gz")
mods <- modomics_mods(fasta_path, "Escherichia coli")
#> Processing 182 MODOMICS sequences.
#> Matching MODOMICS sequences to reference FASTA.
#> Found 698 modification annotations.

mods_glu <- mods |>
  filter(ref == "host-tRNA-Glu-TTC-1-1")
mods_glu
#> # A tibble: 11 × 4
#>    ref                     pos mod_full                          mod1   
#>    <chr>                 <int> <chr>                             <chr>  
#>  1 host-tRNA-Glu-TTC-1-1    13 pseudouridine                     Y      
#>  2 host-tRNA-Glu-TTC-1-1    35 5-methylaminomethyl-2-thiouridine mnm5s2U
#>  3 host-tRNA-Glu-TTC-1-1    38 2-methyladenosine                 m2A    
#>  4 host-tRNA-Glu-TTC-1-1    54 5-methyluridine                   m5U    
#>  5 host-tRNA-Glu-TTC-1-1    55 pseudouridine                     Y      
#>  6 host-tRNA-Glu-TTC-1-1     8 4-thiouridine                     s4U    
#>  7 host-tRNA-Glu-TTC-1-1    13 pseudouridine                     Y      
#>  8 host-tRNA-Glu-TTC-1-1    35 5-methylaminomethyl-2-thiouridine mnm5s2U
#>  9 host-tRNA-Glu-TTC-1-1    38 2-methyladenosine                 m2A    
#> 10 host-tRNA-Glu-TTC-1-1    54 5-methyluridine                   m5U    
#> 11 host-tRNA-Glu-TTC-1-1    55 pseudouridine                     Y

Since plot_tRNA_structure() uses 1-based sequence positions, we load Sprinzl coordinates to convert named positions (like the anticodon at Sprinzl 34-36) to their actual sequence indices.

sprinzl <- read_sprinzl_coords(
  clover_example("sprinzl/ecoliK12_global_coords.tsv.gz")
)
glu_coords <- sprinzl |>
  filter(trna_id == "tRNA-Glu-UUC-1-1")
svg <- plot_tRNA_structure(
  "tRNA-Glu-TTC",
  "Escherichia coli",
  modifications = mods_glu
)
tRNA-Glu-TTCGUCCCCUUCGUCUAGAGGCCCAGGACACCGCCCUUUCACGGCGGUAACAGGGGUUCGAAUCCCCUAGGGGACGCCAA5'Glu10203040506070ModificationsYmnm5s2Um2Am5Us4U

Custom modification palettes

default_mod_palette() returns a named character vector mapping modification short names to colors. You can extend or override it.

head(default_mod_palette(), 10)
#>       m1A       m1G       m2A       m2G     m2,2G       m3C       m5C       m5U 
#> "#E41A1C" "#984EA3" "#E68A00" "#66C2A5" "#8DA0CB" "#B3DE69" "#377EB8" "#FF7F00" 
#>       m6A     m6t6A 
#> "#FB9A99" "#D95F02"

To add a custom category (e.g., highlighting anticodon positions), combine MODOMICS modifications with your own entries and extend the palette.

# Add anticodon positions (Sprinzl 34-36) as a custom category
ac_pos <- glu_coords |>
  filter(sprinzl_label %in% c("34", "35", "36")) |>
  pull(pos)

anticodon <- tibble::tibble(
  pos = ac_pos,
  mod1 = rep("anticodon", 3)
)

all_mods <- bind_rows(mods_glu, anticodon)

# Extend the palette with a color for the new category
custom_palette <- c(default_mod_palette(), anticodon = "#4DAF4A")

svg <- plot_tRNA_structure(
  "tRNA-Glu-TTC",
  "Escherichia coli",
  modifications = all_mods,
  mod_palette = custom_palette
)
tRNA-Glu-TTCGUCCCCUUCGUCUAGAGGCCCAGGACACCGCCCUUUCACGGCGGUAACAGGGGUUCGAAUCCCCUAGGGGACGCCAA5'Glu10203040506070ModificationsYmnm5s2Um2Am5Us4Uanticodon

Outline circles

Outlines draw stroke-only circles around nucleotides, useful for highlighting positions without covering the base letter. The outlines argument takes a tibble with pos and group columns; outline_palette maps group names to colors.

# Highlight the discriminator base (Sprinzl position 73)
disc_pos <- glu_coords |>
  filter(sprinzl_label == "73") |>
  pull(pos)

disc_outline <- tibble::tibble(pos = disc_pos, group = "discriminator")

svg <- plot_tRNA_structure(
  "tRNA-Glu-TTC",
  "Escherichia coli",
  outlines = disc_outline,
  outline_palette = c(discriminator = "#E41A1C")
)
tRNA-Glu-TTCGUCCCCUUCGUCUAGAGGCCCAGGACACCGCCCUUUCACGGCGGUAACAGGGGUUCGAAUCCCCUAGGGGACGCCAA5'Glu10203040506070Outlinesdiscriminator

Text colors

Use text_colors to change the color of nucleotide letters at specific positions. This takes a tibble with pos and color columns.

# Color the anticodon triplet (Sprinzl 34-36) green
ac_text <- tibble::tibble(
  pos = ac_pos,
  color = rep("#4DAF4A", 3)
)

svg <- plot_tRNA_structure(
  "tRNA-Glu-TTC",
  "Escherichia coli",
  text_colors = ac_text
)
tRNA-Glu-TTCGUCCCCUUCGUCUAGAGGCCCAGGACACCGCCCUUUCACGGCGGUAACAGGGGUUCGAAUCCCCUAGGGGACGCCAA5'Glu10203040506070

Combining annotations

Modifications, outlines, and text colors can all be used together.

disc_outline <- tibble::tibble(pos = disc_pos, group = "discriminator")
disc_text <- tibble::tibble(pos = disc_pos, color = "#E41A1C")

svg <- plot_tRNA_structure(
  "tRNA-Glu-TTC",
  "Escherichia coli",
  modifications = all_mods,
  mod_palette = custom_palette,
  outlines = disc_outline,
  outline_palette = c(discriminator = "#E41A1C"),
  text_colors = disc_text
)
tRNA-Glu-TTCGUCCCCUUCGUCUAGAGGCCCAGGACACCGCCCUUUCACGGCGGUAACAGGGGUUCGAAUCCCCUAGGGGACGCCAA5'Glu10203040506070ModificationsYmnm5s2Um2Am5Us4UanticodonOutlinesdiscriminator

Linkage arcs

Pairwise modification co-occurrence can be visualized as arcs on the cloverleaf. The linkages argument takes a tibble with pos1, pos2, and optionally value columns. If a log_odds_ratio column is present (as in output from clean_odds_ratios() / filter_linkages()), it is used automatically.

Arc color encodes direction: blue for mutual exclusivity (negative log OR) and vermillion for co-occurrence (positive log OR). Stroke width encodes magnitude.

or_path <- clover_example(
  "ecoli/summary/tables/wt-15-ctl-01/wt-15-ctl-01.odds_ratios.tsv.gz"
)
or_data <- read_odds_ratios(or_path)

linkages_glu <- or_data |>
  filter(ref == "host-tRNA-Glu-TTC-1-1") |>
  clean_odds_ratios() |>
  filter_linkages()
svg <- plot_tRNA_structure(
  "tRNA-Glu-TTC",
  "Escherichia coli",
  modifications = mods_glu,
  linkages = linkages_glu
)
tRNA-Glu-TTCGUCCCCUUCGUCUAGAGGCCCAGGACACCGCCCUUUCACGGCGGUAACAGGGGUUCGAAUCCCCUAGGGGACGCCAA5'Glu10203040506070ModificationsYmnm5s2Um2Am5Us4ULinkagesExclusiveCo-occurring

Custom linkage palettes

The linkage_palette parameter is a character vector of length 2: the first color is used for negative values (exclusive), the second for positive values (co-occurring). The default is c("#0072B2", "#D55E00").

svg <- plot_tRNA_structure(
  "tRNA-Glu-TTC",
  "Escherichia coli",
  linkages = linkages_glu,
  linkage_palette = c("#7570B3", "#D95F02")
)
tRNA-Glu-TTCGUCCCCUUCGUCUAGAGGCCCAGGACACCGCCCUUUCACGGCGGUAACAGGGGUUCGAAUCCCCUAGGGGACGCCAA5'Glu10203040506070LinkagesExclusiveCo-occurring

Long variable arm tRNAs

Leu and Ser tRNAs have a long variable arm with an extra stem-loop. These are properly rendered from the tRNAscan-SE covariance model alignment.

svg <- plot_tRNA_structure("tRNA-Leu-CAA", "Escherichia coli")
tRNA-Leu-CAAGCCGAAGUGGCGAAAUCGGUAGACGCAGUUGAUUCAAAAUCAACCGUAGAAAUACGUGCCGGUUCGAGUCCGGCCUUCGGCACCAA5'Leu1020304050607080
svg <- plot_tRNA_structure("tRNA-Ser-GGA", "Escherichia coli")
tRNA-Ser-GGAGGUGAGGUGUCCGAGUGGCUGAAGGAGCACGCCUGGAAAGUGUGUAUACGGCAACGUAUCGGGGGUUCGAAUCCCCCCCUCACCGCCAA5'Ser1020304050607080

Identity elements

plot_identity_structure() overlays experimentally validated aminoacylation identity elements (from Giege & Eriani, 2023) onto the cloverleaf. Strong determinants are outlined in red, weak determinants in blue.

This requires Sprinzl coordinates to map element positions onto the tRNA sequence. Bundled coordinate files are available for E. coli and S. cerevisiae.

coords <- read_sprinzl_coords(
  clover_example("sprinzl/sacCer_global_coords.tsv.gz")
)

svg <- plot_identity_structure(
  "tRNA-Ala-AGC",
  "Saccharomyces cerevisiae",
  coords
)
tRNA-Ala-AGCGGGCGUGUGGCGUAGUCGGUAGCGCGCUCCCUUAGCAUGGGAGAGGUCUCCGGUUCGAUUCCGGACUCGUCCAA5'Ala10203040506070Outlinesstrong

Identity element panel

plot_identity_panel() arranges multiple tRNAs side by side, each annotated with its amino acid family’s identity elements.

svg <- plot_identity_panel(
  c("tRNA-Ala-AGC", "tRNA-Asp-GTC", "tRNA-Phe-GAA", "tRNA-His-GTG"),
  "Saccharomyces cerevisiae",
  coords
)
tRNA-Ala-AGCGGGCGUGUGGCGUAGUCGGUAGCGCGCUCCCUUAGCAUGGGAGAGGUCUCCGGUUCGAUUCCGGACUCGUCCAA5'AlaOutlinesstrongAlatRNA-Asp-GTCUCCGUGAUAGUUUAAUGGUCAGAAUGGGCGCUUGUCGCGUGCCAGAUCGGGGUUCAAUUCCCCGUCGCGGAGCCAA5'AspOutlinesstrongAsptRNA-Phe-GAAGCGGACUUAGCUCAGUUGGGAGAGCGCCAGACUGAAGAUCUGGAGGUCCUGUGUUCGAUCCACAGAGUUCGCACCAA5'PheOutlinesstrongweakPhetRNA-His-GTGGCCAUCUUAGUAUAGUGGUUAGUACACAUCGUUGUGGCCGAUGAAACCCUGGUUCGAUUCUAGGAGAUGGCACCAA5'HisOutlinesstrongweakHisstrongweak

Output formats

plot_tRNA_structure() writes an SVG file and returns the path invisibly. For embedding in R Markdown or Quarto, use structure_html() to wrap the SVG in a centered <div>. For raster output, use structure_to_png().

# Embed as HTML (used throughout this vignette)
svg <- plot_tRNA_structure("tRNA-Glu-TTC", "Escherichia coli")
structure_html(svg)

# Convert to PNG
png <- structure_to_png(svg, width = 600)

Session info

sessionInfo()
#> R version 4.5.2 (2025-10-31)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 24.04.3 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.26.so;  LAPACK version 3.12.0
#> 
#> locale:
#>  [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8       
#>  [4] LC_COLLATE=C.UTF-8     LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8   
#>  [7] LC_PAPER=C.UTF-8       LC_NAME=C              LC_ADDRESS=C          
#> [10] LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   
#> 
#> time zone: UTC
#> tzcode source: system (glibc)
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] dplyr_1.2.0       clover_0.0.0.9000
#> 
#> loaded via a namespace (and not attached):
#>  [1] SummarizedExperiment_1.40.0 gtable_0.3.6               
#>  [3] xfun_0.56                   bslib_0.10.0               
#>  [5] ggplot2_4.0.2               htmlwidgets_1.6.4          
#>  [7] Biobase_2.70.0              lattice_0.22-7             
#>  [9] tzdb_0.5.0                  vctrs_0.7.1                
#> [11] tools_4.5.2                 generics_0.1.4             
#> [13] parallel_4.5.2              stats4_4.5.2               
#> [15] tibble_3.3.1                pkgconfig_2.0.3            
#> [17] Matrix_1.7-4                RColorBrewer_1.1-3         
#> [19] S7_0.2.1                    desc_1.4.3                 
#> [21] S4Vectors_0.48.0            lifecycle_1.0.5            
#> [23] compiler_4.5.2              farver_2.1.2               
#> [25] textshaping_1.0.4           Biostrings_2.78.0          
#> [27] Seqinfo_1.0.0               htmltools_0.5.9            
#> [29] sass_0.4.10                 yaml_2.3.12                
#> [31] pkgdown_2.2.0               pillar_1.11.1              
#> [33] crayon_1.5.3                jquerylib_0.1.4            
#> [35] DelayedArray_0.36.0         cachem_1.1.0               
#> [37] abind_1.4-8                 tidyselect_1.2.1           
#> [39] digest_0.6.39               purrr_1.2.1                
#> [41] fastmap_1.2.0               grid_4.5.2                 
#> [43] cli_3.6.5                   SparseArray_1.10.8         
#> [45] magrittr_2.0.4              S4Arrays_1.10.1            
#> [47] utf8_1.2.6                  readr_2.2.0                
#> [49] withr_3.0.2                 scales_1.4.0               
#> [51] bit64_4.6.0-1               rmarkdown_2.30             
#> [53] pwalign_1.6.0               XVector_0.50.0             
#> [55] matrixStats_1.5.0           bit_4.6.0                  
#> [57] ragg_1.5.0                  hms_1.1.4                  
#> [59] evaluate_1.0.5              knitr_1.51                 
#> [61] GenomicRanges_1.62.1        IRanges_2.44.0             
#> [63] rlang_1.1.7                 glue_1.8.0                 
#> [65] xml2_1.5.2                  BiocGenerics_0.56.0        
#> [67] vroom_1.7.0                 jsonlite_2.0.0             
#> [69] R6_2.6.1                    MatrixGenerics_1.22.0      
#> [71] systemfonts_1.3.1           fs_1.6.6