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")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
)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 YSince 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
)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
)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")
)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
)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
)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
)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")
)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")
svg <- plot_tRNA_structure("tRNA-Ser-GGA", "Escherichia coli")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
)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
)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