@@ -291,11 +291,11 @@ plot_identity_structure <- function(
291291 )
292292}
293293
294- # ' Plot identity elements for multiple tRNAs side by side
294+ # ' Plot identity elements for multiple tRNAs in a grid
295295# '
296296# ' Generates a combined SVG showing tRNA cloverleaf structures
297- # ' arranged in a horizontal row , each annotated with aminoacylation
298- # ' identity elements. Inspired by Figure 2 of Giege & Eriani (2023).
297+ # ' arranged in a grid , each annotated with aminoacylation identity
298+ # ' elements. Inspired by Figure 2 of Giege & Eriani (2023).
299299# '
300300# ' @param trnas Character vector of tRNA identifiers
301301# ' (e.g., `c("tRNA-Ala-AGC", "tRNA-Phe-GAA")`).
@@ -306,7 +306,9 @@ plot_identity_structure <- function(
306306# ' writes to a temporary file.
307307# ' @param outline_palette Named character vector of colors keyed by
308308# ' strength. Default uses red for strong and blue for weak.
309- # ' @param gap Horizontal gap in SVG units between panels. Default 20.
309+ # ' @param ncol Number of columns in the panel grid. If `NULL`
310+ # ' (default), all tRNAs are placed in a single row.
311+ # ' @param gap Gap in SVG units between panels. Default 20.
310312# ' @param ... Additional arguments passed to
311313# ' [plot_identity_structure()].
312314# '
@@ -331,6 +333,7 @@ plot_identity_panel <- function(
331333 sprinzl_coords ,
332334 output = NULL ,
333335 outline_palette = NULL ,
336+ ncol = NULL ,
334337 gap = 20 ,
335338 ...
336339) {
@@ -382,11 +385,22 @@ plot_identity_panel <- function(
382385 numeric (1 )
383386 )
384387
388+ # Grid layout
389+ n <- length(trnas )
390+ if (is.null(ncol )) {
391+ ncol <- n
392+ }
393+ nrow <- ceiling(n / ncol )
394+
385395 # Label height
386396 label_h <- 16
387397
388- total_width <- sum(widths ) + gap * (length(trnas ) - 1 )
389- total_height <- max(heights ) + label_h
398+ # Cell dimensions based on the largest panel
399+ cell_w <- max(widths )
400+ cell_h <- max(heights ) + label_h
401+
402+ total_width <- ncol * cell_w + (ncol - 1 ) * gap
403+ total_height <- nrow * cell_h + (nrow - 1 ) * gap
390404
391405 # Build combined SVG
392406 combined <- xml2 :: read_xml(paste0(
@@ -405,12 +419,23 @@ plot_identity_panel <- function(
405419 ))
406420 root <- xml2 :: xml_root(combined )
407421
408- x_offset <- 0
409422 for (i in seq_along(svg_docs )) {
423+ col_idx <- (i - 1 ) %% ncol
424+ row_idx <- (i - 1 ) %/% ncol
425+
426+ x_offset <- col_idx * (cell_w + gap )
427+ y_offset <- row_idx * (cell_h + gap )
428+
410429 panel_g <- xml2 :: xml_add_child(
411430 root ,
412431 " g" ,
413- transform = paste0(" translate(" , x_offset , " ," , label_h , " )" )
432+ transform = paste0(
433+ " translate(" ,
434+ x_offset ,
435+ " ," ,
436+ y_offset + label_h ,
437+ " )"
438+ )
414439 )
415440
416441 # Copy all children from the individual SVG
@@ -426,16 +451,14 @@ plot_identity_panel <- function(
426451 root ,
427452 " text" ,
428453 x = as.character(label_x ),
429- y = as.character(label_h - 3 ),
454+ y = as.character(y_offset + label_h - 3 ),
430455 " text-anchor" = " middle" ,
431456 " font-family" = " Helvetica, Arial, sans-serif" ,
432457 " font-size" = " 11" ,
433458 " font-weight" = " bold" ,
434459 fill = " #333333"
435460 )
436461 xml2 :: xml_set_text(label_node , aa )
437-
438- x_offset <- x_offset + widths [i ] + gap
439462 }
440463
441464 # Add shared legend
0 commit comments