From 5c688c63bdd56568cb540fd8bb133b54274c75ff Mon Sep 17 00:00:00 2001 From: whelena Date: Wed, 14 Jan 2026 19:32:26 -0800 Subject: [PATCH 01/14] add rotation to polygons --- R/SRCGrob.R | 7 ------- R/get.CP.polygons.R | 25 ++++++++++++++++++++++--- R/make.clone.tree.grobs.R | 22 +++++++++++++++++++++- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/R/SRCGrob.R b/R/SRCGrob.R index ad4f3898..90841f7e 100644 --- a/R/SRCGrob.R +++ b/R/SRCGrob.R @@ -34,13 +34,6 @@ SRCGrob <- function( scale.size.2 = NA, scale.padding = 1 ) { - if ('CP' %in% colnames(tree) && !(plotting.direction %in% c('down', 0))) { - warning(paste( - '"plotting.direction" is not yet supported with "CP" polygon column.', - '"plotting.direction" will be ignored.' - )); - } - add.node.text <- !is.null(node.text); add.polygons <- !is.null(tree$CP) && !disable.polygons; text.on.nodes <- FALSE; diff --git a/R/get.CP.polygons.R b/R/get.CP.polygons.R index cf550a95..5261d7b2 100644 --- a/R/get.CP.polygons.R +++ b/R/get.CP.polygons.R @@ -1,11 +1,30 @@ -get.CP.polygons <- function(clone.out, ...) { +get.CP.polygons <- function(clone.out, start.angle = 0, ...) { polygon.list <- list(); for (j in 1:length(clone.out$clones)) { + # Get original polygon coordinates + poly.x <- clone.out$clones[[j]]$x; + poly.y <- clone.out$clones[[j]]$y; + + # Apply rotation if start.angle is non-zero + if (start.angle != 0) { + # Use the existing rotate.coords function to apply rotation + # Rotation origin is (0, 0) which should align with the root node + rotated <- rotate.coords( + x = poly.x, + y = poly.y, + rotate.by = start.angle, + x.origin = 0, + y.origin = 0 + ); + poly.x <- rotated$x; + poly.y <- rotated$y; + } + polygon.list[[j]] <- polygonGrob( name = paste0('clone.polygon.', j), - x = clone.out$clones[[j]]$x, - y = clone.out$clones[[j]]$y, + x = poly.x, + y = poly.y, default.units = 'native', gp = gpar( fill = clone.out$clones[[j]]$col, diff --git a/R/make.clone.tree.grobs.R b/R/make.clone.tree.grobs.R index c93120cc..048c2cd8 100644 --- a/R/make.clone.tree.grobs.R +++ b/R/make.clone.tree.grobs.R @@ -110,6 +110,26 @@ make.clone.tree.grobs <- function( ); clone.out$no.ccf <- no.ccf; + + # Rotate node positions and branch angles for fish plots (with CP data) when start.angle is non-zero + # This ensures branches and nodes rotate along with the polygons + if (!no.ccf && start.angle != 0) { + # Rotate all node positions + rotated.nodes <- rotate.coords( + x = clone.out$v$x, + y = clone.out$v$y, + rotate.by = start.angle, + x.origin = 0, + y.origin = 0 + ); + clone.out$v$x <- rotated.nodes$x; + clone.out$v$y <- rotated.nodes$y; + + # Rotate branch angles to match the rotated coordinate system + # Note: rotate.coords negates the angle internally, so we add the original start.angle + clone.out$tree$angle <- clone.out$tree$angle + start.angle; + } + plot.size <- calculate.main.plot.size( clone.out, scale1, @@ -119,7 +139,7 @@ make.clone.tree.grobs <- function( ); if (!no.ccf) { - get.CP.polygons(clone.out); + get.CP.polygons(clone.out, start.angle = start.angle); } add.tree.segs( From 4487c7313ebda885a231a660deb8cbda3947eb9c Mon Sep 17 00:00:00 2001 From: whelena Date: Thu, 15 Jan 2026 17:10:31 -0800 Subject: [PATCH 02/14] it's semi working, need to align xaxis and test with other plot types --- R/SRCGrob.R | 3 +- R/make.clone.tree.grobs.R | 3 +- R/set.up.plot.area.R | 147 ++++++++++++++++++++++++++------------ 3 files changed, 107 insertions(+), 46 deletions(-) diff --git a/R/SRCGrob.R b/R/SRCGrob.R index 90841f7e..b8735a0d 100644 --- a/R/SRCGrob.R +++ b/R/SRCGrob.R @@ -126,7 +126,8 @@ SRCGrob <- function( scale.bar.coords = scale.bar.coords, scale.size.1 = scale.size.1, scale.size.2 = scale.size.2, - scale.padding = scale.padding + scale.padding = scale.padding, + plotting.direction = plotting.direction ); out.tree <- gTree( diff --git a/R/make.clone.tree.grobs.R b/R/make.clone.tree.grobs.R index 048c2cd8..dfbe17b6 100644 --- a/R/make.clone.tree.grobs.R +++ b/R/make.clone.tree.grobs.R @@ -179,7 +179,8 @@ make.clone.tree.grobs <- function( no.ccf = no.ccf, xaxis.label = xaxis.label, yaxis1.label = yaxis1.label, - yaxis2.label = yaxis2.label + yaxis2.label = yaxis2.label, + plotting.direction = list(...)$plotting.direction ); if (scale.bar) { diff --git a/R/set.up.plot.area.R b/R/set.up.plot.area.R index 8789873e..6f9da17e 100644 --- a/R/set.up.plot.area.R +++ b/R/set.up.plot.area.R @@ -16,9 +16,28 @@ calculate.main.plot.size <- function( ) { padding <- 2 * node.radius / scale1; - ymax <- clone.out$v$y[which.max(abs(clone.out$v$y))]; - ymax <- ymax + (- sign(ymax) * padding); - height <- ymax * scale1; + # ymax <- clone.out$v$y[which.max(abs(clone.out$v$y))]; + # ymax <- ymax + (- sign(ymax) * padding); + # height <- ymax * scale1; + if (!is.null(clone.out$clones) && length(clone.out$clones) > 0) { + # Get all polygon y coordinates + all.poly.y <- unlist(lapply(clone.out$clones, function(cl) cl$y)); + # Combine with node y coordinates + all.y <- c(clone.out$v$y, all.poly.y); + } else { + # Original logic for non-fish plots + all.y <- clone.out$v$y; + } + ymin <- min(all.y) + ymax <- max(all.y) + # y.center <- (ymax + ymin)/2 + # half_height <- (ymax - ymin)/2 + # ylims <- c(y_center + half_height, y_center - half_height) + ylims <- c( + ymax + (- sign(ymax) * padding/2), + ymin - (- sign(ymin) * padding/2) + ) + height <- (max(ylims) - min(ylims)) * scale1; if (is.null(min.width)) { xmax <- wid; @@ -28,19 +47,23 @@ calculate.main.plot.size <- function( xmax / 2 + padding ); } else { - xmin <- min(c(clone.out$v$x)); - xmax <- max(c(clone.out$v$x)); - xlims <- c(xmin, xmax); + all.x <- clone.out$v$x; + xmin <- min(all.x); + xmax <- max(all.x); + xlims <- c( + xmin - (sign(xmin) * padding / 2), + xmax - (sign(xmax) * padding / 2) + ) width <- (max(xlims) - min(xlims)) * scale1; diff <- min.width - width; if (diff > 0) { xmin <- xmin - 0.5 * diff / scale1 xmax <- xmax + 0.5 * diff / scale1; xlims <- c( - xmin - padding, - xmax + padding - ); + xmin - (sign(xmin) * padding), + xmax - (sign(xmax) * padding) + ) width <- (max(xlims) - min(xlims)) * scale1; } @@ -49,11 +72,12 @@ calculate.main.plot.size <- function( clone.out$height <- height; clone.out$width <- width; clone.out$xlims <- xlims; - clone.out$ymax <- ymax; + clone.out$ylims <- ylims; + # clone.out$ymax <- ymax; clone.out$vp <- make.plot.viewport( clone.out, - clip = if (clone.out$no.ccf) 'off' else 'on' + clip = 'off' #if (clone.out$no.ccf) 'off' else 'on' ); } @@ -70,7 +94,8 @@ make.plot.viewport <- function( width = unit(clone.out$width, 'inches'), name = 'plot.vp', xscale = clone.out$xlims, - yscale = c(clone.out$ymax, 0), + yscale = clone.out$ylims, + # yscale = c(clone.out$ymax, 0), just = just, gp = gpar(fill = 'pink'), clip = clip @@ -94,6 +119,12 @@ add.axis.label <- function(axisGrob, axis.label, axis.position, axis.label.cex, rot <- 0; x <- unit(0.5, 'npc'); y <- (getGrob(axisGrob, 'labels')$y + getGrob(axisGrob, 'ticks')$y1) * 1.75; + } else if (axis.position == 'top') { + d <- 'y'; + just <- c('centre', 'bottom'); + rot <- 0; + x <- unit(0.5, 'npc'); + y <- (getGrob(axisGrob, 'labels')$y + getGrob(axisGrob, 'ticks')$y1) * 1.75; } else { pushViewport(vp); @@ -162,17 +193,22 @@ add.axes <- function( yaxis2.label = NULL, no.ccf = FALSE, axis.label.cex = list(x = 1.55, y = 1.55), - axis.cex = list(x = 1, y = 1) + axis.cex = list(x = 1, y = 1), + plotting.direction = 'down' ) { - if (!no.ccf && 'ccf' %in% colnames(clone.out$v) && all(!is.na(clone.out$v$ccf))) { + # Skip x-axis if plotting.direction is numeric (custom angle) + draw.xaxis <- !is.numeric(plotting.direction); + + if (!no.ccf && 'ccf' %in% colnames(clone.out$v) && all(!is.na(clone.out$v$ccf)) && draw.xaxis) { add.xaxis( clone.out, scale1 = scale1, axis.label = xaxis.label, no.ccf = no.ccf, axis.label.cex = axis.label.cex[['x']], - axis.cex = axis.cex[['x']] + axis.cex = axis.cex[['x']], + plotting.direction = plotting.direction ); } @@ -287,9 +323,21 @@ add.xaxis <- function( axis.label = 'CCF', no.ccf = FALSE, axis.label.cex = 1.55, - axis.cex = 1 + axis.cex = 1, + plotting.direction = 'down' ) { + # Determine axis position based on plotting direction + # down -> bottom, up -> top, left -> left, right -> right + axis.position <- switch( + as.character(plotting.direction), + 'down' = 'bottom', + 'up' = 'top', + 'left' = 'left', + 'right' = 'right', + 'bottom' # default + ); + # Necessary to get the right positioning vp.unclipped <- make.plot.viewport(clone.out, clip = 'off'); @@ -298,41 +346,52 @@ add.xaxis <- function( xat <- c(min(clone.widths), max(clone.widths)); xlabels <- c(0, paste0(round(max(clone.out$v$ccf) * 100, 0), '%')); - xaxis <- xaxisGrob( - name = 'axis.content', - at = xat, - label = xlabels, - gp = gpar(cex = axis.label.cex), - main = TRUE - ); - - # Move the labels up slightly - xaxis.labels <- editGrob( - getGrob(xaxis, 'labels'), - y = unit(-0.09, 'npc'), - vjust = 1 - ); + # Create appropriate axis grob based on position + if (axis.position %in% c('left', 'right')) { + # For horizontal plots, use yaxisGrob + xaxis <- yaxisGrob( + name = 'axis.content', + at = xat, + label = xlabels, + gp = gpar(cex = axis.label.cex), + main = (axis.position == 'left') + ); + } else { + # For vertical plots, use xaxisGrob + xaxis <- xaxisGrob( + name = 'axis.content', + at = xat, + label = xlabels, + gp = gpar(cex = axis.label.cex), + main = (axis.position == 'bottom') + ); - xaxis <- setGrob( - xaxis, - 'labels', - xaxis.labels - ); + # Move the labels slightly for bottom position + if (axis.position == 'bottom') { + xaxis.labels <- editGrob( + getGrob(xaxis, 'labels'), + y = unit(-0.09, 'npc'), + vjust = 1 + ); + xaxis <- setGrob(xaxis, 'labels', xaxis.labels); + } + } - if (diff(xat) / scale1 != clone.out$width) { - # Extending the axis line beyond the clone limits - xaxis <- extend.axis( - xaxis, - limits = unit(clone.out$xlims,'native'), - type = 'x' - ); - } + # if (diff(xat) / scale1 != clone.out$width) { + # # Extending the axis line beyond the clone limits + # axis.type <- if (axis.position %in% c('left', 'right')) 'y' else 'x'; + # xaxis <- extend.axis( + # xaxis, + # limits = unit(clone.out$xlims, 'native'), + # type = axis.type + # ); + # } # Add the axis label xaxis.gTree <- add.axis.label( xaxis, axis.label, - axis.position = 'bottom', + axis.position = axis.position, axis.label.cex, vp = vp.unclipped ); From d9e1ac30302d4e4ca977be3d4777ec3e45a45083 Mon Sep 17 00:00:00 2001 From: whelena Date: Fri, 8 May 2026 11:58:38 -0700 Subject: [PATCH 03/14] fix rotations to ensure plots remain centered in the viewplot --- R/get.CP.polygons.R | 25 ++------- R/make.clone.tree.grobs.R | 20 ++++++-- R/set.up.plot.area.R | 103 ++++++++++++++++---------------------- 3 files changed, 60 insertions(+), 88 deletions(-) diff --git a/R/get.CP.polygons.R b/R/get.CP.polygons.R index 5261d7b2..cf550a95 100644 --- a/R/get.CP.polygons.R +++ b/R/get.CP.polygons.R @@ -1,30 +1,11 @@ -get.CP.polygons <- function(clone.out, start.angle = 0, ...) { +get.CP.polygons <- function(clone.out, ...) { polygon.list <- list(); for (j in 1:length(clone.out$clones)) { - # Get original polygon coordinates - poly.x <- clone.out$clones[[j]]$x; - poly.y <- clone.out$clones[[j]]$y; - - # Apply rotation if start.angle is non-zero - if (start.angle != 0) { - # Use the existing rotate.coords function to apply rotation - # Rotation origin is (0, 0) which should align with the root node - rotated <- rotate.coords( - x = poly.x, - y = poly.y, - rotate.by = start.angle, - x.origin = 0, - y.origin = 0 - ); - poly.x <- rotated$x; - poly.y <- rotated$y; - } - polygon.list[[j]] <- polygonGrob( name = paste0('clone.polygon.', j), - x = poly.x, - y = poly.y, + x = clone.out$clones[[j]]$x, + y = clone.out$clones[[j]]$y, default.units = 'native', gp = gpar( fill = clone.out$clones[[j]]$col, diff --git a/R/make.clone.tree.grobs.R b/R/make.clone.tree.grobs.R index dfbe17b6..4ad762a6 100644 --- a/R/make.clone.tree.grobs.R +++ b/R/make.clone.tree.grobs.R @@ -114,7 +114,6 @@ make.clone.tree.grobs <- function( # Rotate node positions and branch angles for fish plots (with CP data) when start.angle is non-zero # This ensures branches and nodes rotate along with the polygons if (!no.ccf && start.angle != 0) { - # Rotate all node positions rotated.nodes <- rotate.coords( x = clone.out$v$x, y = clone.out$v$y, @@ -125,9 +124,19 @@ make.clone.tree.grobs <- function( clone.out$v$x <- rotated.nodes$x; clone.out$v$y <- rotated.nodes$y; - # Rotate branch angles to match the rotated coordinate system - # Note: rotate.coords negates the angle internally, so we add the original start.angle clone.out$tree$angle <- clone.out$tree$angle + start.angle; + + for (j in seq_along(clone.out$clones)) { + rot.poly <- rotate.coords( + x = clone.out$clones[[j]]$x, + y = clone.out$clones[[j]]$y, + rotate.by = start.angle, + x.origin = 0, + y.origin = 0 + ); + clone.out$clones[[j]]$x <- rot.poly$x; + clone.out$clones[[j]]$y <- rot.poly$y; + } } plot.size <- calculate.main.plot.size( @@ -135,11 +144,12 @@ make.clone.tree.grobs <- function( scale1, wid, min.width, - node.radius + node.radius, + plotting.direction = list(...)$plotting.direction ); if (!no.ccf) { - get.CP.polygons(clone.out, start.angle = start.angle); + get.CP.polygons(clone.out); } add.tree.segs( diff --git a/R/set.up.plot.area.R b/R/set.up.plot.area.R index 6f9da17e..1f52ad06 100644 --- a/R/set.up.plot.area.R +++ b/R/set.up.plot.area.R @@ -12,61 +12,42 @@ calculate.main.plot.size <- function( scale1, wid, min.width, - node.radius + node.radius, + plotting.direction = 'down' ) { padding <- 2 * node.radius / scale1; - # ymax <- clone.out$v$y[which.max(abs(clone.out$v$y))]; - # ymax <- ymax + (- sign(ymax) * padding); - # height <- ymax * scale1; - if (!is.null(clone.out$clones) && length(clone.out$clones) > 0) { - # Get all polygon y coordinates - all.poly.y <- unlist(lapply(clone.out$clones, function(cl) cl$y)); - # Combine with node y coordinates - all.y <- c(clone.out$v$y, all.poly.y); - } else { - # Original logic for non-fish plots - all.y <- clone.out$v$y; - } - ymin <- min(all.y) - ymax <- max(all.y) - # y.center <- (ymax + ymin)/2 - # half_height <- (ymax - ymin)/2 - # ylims <- c(y_center + half_height, y_center - half_height) - ylims <- c( - ymax + (- sign(ymax) * padding/2), - ymin - (- sign(ymin) * padding/2) - ) - height <- (max(ylims) - min(ylims)) * scale1; - - if (is.null(min.width)) { - xmax <- wid; - width <- wid * scale1 + 4 * node.radius; - xlims <- c( - -(xmax / 2) - padding, - xmax / 2 + padding - ); - } else { - all.x <- clone.out$v$x; - xmin <- min(all.x); - xmax <- max(all.x); - - xlims <- c( - xmin - (sign(xmin) * padding / 2), - xmax - (sign(xmax) * padding / 2) - ) - width <- (max(xlims) - min(xlims)) * scale1; - diff <- min.width - width; - if (diff > 0) { - xmin <- xmin - 0.5 * diff / scale1 - xmax <- xmax + 0.5 * diff / scale1; - xlims <- c( - xmin - (sign(xmin) * padding), - xmax - (sign(xmax) * padding) - ) - - width <- (max(xlims) - min(xlims)) * scale1; - } + + all.x <- clone.out$v$x; + all.y <- clone.out$v$y; + if (!is.null(clone.out$clones) && length(clone.out$clones) > 0) { + all.x <- c(all.x, unlist(lapply(clone.out$clones, function(cl) cl$x))); + all.y <- c(all.y, unlist(lapply(clone.out$clones, function(cl) cl$y))); + } + + xmin <- min(all.x); + xmax <- max(all.x); + ymin <- min(all.y); + ymax <- max(all.y); + + # Remove padding on the axis edge so the CCF axis grob sits flush + # against the polygon tip. Numeric angles have no defined axis side. + pad.bottom <- if (is.character(plotting.direction) && plotting.direction == 'down') 0 else padding; + pad.top <- if (is.character(plotting.direction) && plotting.direction == 'up') 0 else padding; + pad.left <- if (is.character(plotting.direction) && plotting.direction == 'left') 0 else padding; + pad.right <- if (is.character(plotting.direction) && plotting.direction == 'right') 0 else padding; + + xlims <- c(xmin - pad.left, xmax + pad.right); + ylims <- c(ymax + pad.bottom, ymin - pad.top); + + width <- (xmax - xmin + pad.left + pad.right) * scale1; + height <- (ymax - ymin + pad.bottom + pad.top) * scale1; + + if (!is.null(min.width) && width < min.width) { + expand <- (min.width - width) / (2 * scale1); + xlims[1] <- xlims[1] - expand; + xlims[2] <- xlims[2] + expand; + width <- min.width; } clone.out$height <- height; @@ -377,15 +358,15 @@ add.xaxis <- function( } } - # if (diff(xat) / scale1 != clone.out$width) { - # # Extending the axis line beyond the clone limits - # axis.type <- if (axis.position %in% c('left', 'right')) 'y' else 'x'; - # xaxis <- extend.axis( - # xaxis, - # limits = unit(clone.out$xlims, 'native'), - # type = axis.type - # ); - # } + # Extend the axis line to the full viewport extent so it touches + # the polygon flat edge and extends slightly past it on both sides + axis.type <- if (axis.position %in% c('left', 'right')) 'y' else 'x'; + axis.limits <- if (axis.position %in% c('left', 'right')) { + unit(clone.out$ylims, 'native') + } else { + unit(clone.out$xlims, 'native') + }; + xaxis <- extend.axis(xaxis, axis.limits, type = axis.type); # Add the axis label xaxis.gTree <- add.axis.label( From fecad392512baebd139c34195503bcf646420cbc Mon Sep 17 00:00:00 2001 From: whelena Date: Tue, 12 May 2026 14:58:24 -0700 Subject: [PATCH 04/14] fix extend axis for both directions --- R/make.clone.tree.grobs.R | 5 +- R/set.up.plot.area.R | 441 ++++++++++++++++++-------------------- 2 files changed, 215 insertions(+), 231 deletions(-) diff --git a/R/make.clone.tree.grobs.R b/R/make.clone.tree.grobs.R index 4ad762a6..121e6ca8 100644 --- a/R/make.clone.tree.grobs.R +++ b/R/make.clone.tree.grobs.R @@ -41,6 +41,7 @@ make.clone.tree.grobs <- function( scale.size.1, scale.size.2, scale.padding, + plotting.direction = 'down', ... ) { #initializing dataframe for subclones @@ -145,7 +146,7 @@ make.clone.tree.grobs <- function( wid, min.width, node.radius, - plotting.direction = list(...)$plotting.direction + start.angle = start.angle ); if (!no.ccf) { @@ -190,7 +191,7 @@ make.clone.tree.grobs <- function( xaxis.label = xaxis.label, yaxis1.label = yaxis1.label, yaxis2.label = yaxis2.label, - plotting.direction = list(...)$plotting.direction + plotting.direction = plotting.direction ); if (scale.bar) { diff --git a/R/set.up.plot.area.R b/R/set.up.plot.area.R index 1f52ad06..f2805f2c 100644 --- a/R/set.up.plot.area.R +++ b/R/set.up.plot.area.R @@ -13,7 +13,7 @@ calculate.main.plot.size <- function( wid, min.width, node.radius, - plotting.direction = 'down' + start.angle = 0 ) { padding <- 2 * node.radius / scale1; @@ -31,11 +31,12 @@ calculate.main.plot.size <- function( ymax <- max(all.y); # Remove padding on the axis edge so the CCF axis grob sits flush - # against the polygon tip. Numeric angles have no defined axis side. - pad.bottom <- if (is.character(plotting.direction) && plotting.direction == 'down') 0 else padding; - pad.top <- if (is.character(plotting.direction) && plotting.direction == 'up') 0 else padding; - pad.left <- if (is.character(plotting.direction) && plotting.direction == 'left') 0 else padding; - pad.right <- if (is.character(plotting.direction) && plotting.direction == 'right') 0 else padding; + # against the polygon tip. Non-cardinal angles have no defined axis side. + tol <- 1e-9; + pad.bottom <- 0 #if (abs(start.angle) < tol) 0 else padding; + pad.top <- 0 #if (abs(start.angle - pi) < tol) 0 else padding; + pad.right <- 0 #if (abs(start.angle - pi/2) < tol) 0 else padding; + pad.left <- 0 #if (abs(start.angle + pi/2) < tol) 0 else padding; xlims <- c(xmin - pad.left, xmax + pad.right); ylims <- c(ymax + pad.bottom, ymin - pad.top); @@ -54,12 +55,12 @@ calculate.main.plot.size <- function( clone.out$width <- width; clone.out$xlims <- xlims; clone.out$ylims <- ylims; - # clone.out$ymax <- ymax; + # clone.out$ymax <- ymax; - clone.out$vp <- make.plot.viewport( - clone.out, - clip = 'off' #if (clone.out$no.ccf) 'off' else 'on' - ); + clone.out$vp <- make.plot.viewport( + clone.out, + clip = 'off' #if (clone.out$no.ccf) 'off' else 'on' + ); } make.plot.viewport <- function( @@ -69,28 +70,28 @@ make.plot.viewport <- function( y = 0.5 ) { - vp <- viewport( - y = y, - height = unit(clone.out$height, 'inches'), - width = unit(clone.out$width, 'inches'), - name = 'plot.vp', - xscale = clone.out$xlims, - yscale = clone.out$ylims, - # yscale = c(clone.out$ymax, 0), - just = just, - gp = gpar(fill = 'pink'), - clip = clip - ); - - return(vp); + vp <- viewport( + y = y, + height = unit(clone.out$height, 'inches'), + width = unit(clone.out$width, 'inches'), + name = 'plot.vp', + xscale = clone.out$xlims, + yscale = clone.out$ylims, + # yscale = c(clone.out$ymax, 0), + just = just, + gp = gpar(fill = 'pink'), + clip = clip + ); + + return(vp); } extend.axis <- function(axisGrob, limits, type) { - arg.list <- list(getGrob(axisGrob, 'major'), limits); - names(arg.list) <- c('grob', type); - axisGrob <- setGrob(axisGrob, 'major', do.call(editGrob, arg.list)); + arg.list <- list(getGrob(axisGrob, 'major'), limits); + names(arg.list) <- c('grob', type); + axisGrob <- setGrob(axisGrob, 'major', do.call(editGrob, arg.list)); - return(axisGrob); + return(axisGrob); } add.axis.label <- function(axisGrob, axis.label, axis.position, axis.label.cex, vp) { @@ -100,66 +101,66 @@ add.axis.label <- function(axisGrob, axis.label, axis.position, axis.label.cex, rot <- 0; x <- unit(0.5, 'npc'); y <- (getGrob(axisGrob, 'labels')$y + getGrob(axisGrob, 'ticks')$y1) * 1.75; - } else if (axis.position == 'top') { + } else if (axis.position == 'top') { d <- 'y'; just <- c('centre', 'bottom'); rot <- 0; x <- unit(0.5, 'npc'); y <- (getGrob(axisGrob, 'labels')$y + getGrob(axisGrob, 'ticks')$y1) * 1.75; - } else { - pushViewport(vp); - - tick.length <- unit( - diff(c( - as.numeric(getGrob(axisGrob, 'ticks')$x0), - as.numeric(getGrob(axisGrob, 'ticks')$x1) - )), - 'lines' - ); - - y <- convertY( - unit(max(as.numeric(getGrob(axisGrob, 'major')$y)) * 0.5, 'native'), - 'inches' - ); - - if (axis.position == 'left') { - d <- 'x'; - just <- c('centre', 'centre'); - rot <- 90; - - x <- unit( - convertX(grobWidth(getGrob(axisGrob, 'labels')), 'mm', valueOnly = TRUE) * -(axisGrob$gp$cex) - - convertX(unit(1, 'lines') * axisGrob$gp$cex, 'mm', valueOnly = TRUE) + - convertX(getGrob(axisGrob, 'labels')$x * axisGrob$gp$cex, 'mm', valueOnly = TRUE), - 'mm' - ); - } else if (axis.position == 'right') { - d <- 'x'; - just <- c('left', 'centre'); - x <- (getGrob(axisGrob, 'labels')$x + tick.length) * 1.5; - rot <- 270; - } - - popViewport() - } - - axis.lab <- textGrob( - name = 'axis.label', - axis.label, - gp = gpar(cex = axis.label.cex), - vjust = 0, - x = x, - rot = rot, - y = y - ); - - axis.gTree <- gTree( - name = paste0('axis.', axis.position), - children = gList(axis.lab, axisGrob), - vp = vp - ); - - return(axis.gTree); + } else { + pushViewport(vp); + + tick.length <- unit( + diff(c( + as.numeric(getGrob(axisGrob, 'ticks')$x0), + as.numeric(getGrob(axisGrob, 'ticks')$x1) + )), + 'lines' + ); + + y <- convertY( + unit(max(as.numeric(getGrob(axisGrob, 'major')$y)) * 0.5, 'native'), + 'inches' + ); + + if (axis.position == 'left') { + d <- 'x'; + just <- c('right', 'centre'); + rot <- 90; + + x <- unit( + convertX(grobWidth(getGrob(axisGrob, 'labels')), 'mm', valueOnly = TRUE) * -(axisGrob$gp$cex) - + convertX(unit(1, 'lines') * axisGrob$gp$cex, 'mm', valueOnly = TRUE) + + convertX(getGrob(axisGrob, 'labels')$x * axisGrob$gp$cex, 'mm', valueOnly = TRUE), + 'mm' + ); + } else if (axis.position == 'right') { + d <- 'x'; + just <- c('left', 'centre'); + x <- (getGrob(axisGrob, 'labels')$x + tick.length) * 1.5; + rot <- 270; + } + + popViewport() + } + + axis.lab <- textGrob( + name = 'axis.label', + axis.label, + gp = gpar(cex = axis.label.cex), + vjust = 0, + x = x, + rot = rot, + y = y + ); + + axis.gTree <- gTree( + name = paste0('axis.', axis.position), + children = gList(axis.lab, axisGrob), + vp = vp + ); + + return(axis.gTree); } add.axes <- function( @@ -181,60 +182,60 @@ add.axes <- function( # Skip x-axis if plotting.direction is numeric (custom angle) draw.xaxis <- !is.numeric(plotting.direction); - if (!no.ccf && 'ccf' %in% colnames(clone.out$v) && all(!is.na(clone.out$v$ccf)) && draw.xaxis) { - add.xaxis( - clone.out, - scale1 = scale1, - axis.label = xaxis.label, - no.ccf = no.ccf, - axis.label.cex = axis.label.cex[['x']], - axis.cex = axis.cex[['x']], - plotting.direction = plotting.direction - ); - } + if (!no.ccf && 'ccf' %in% colnames(clone.out$v) && all(!is.na(clone.out$v$ccf)) && draw.xaxis) { + add.xaxis( + clone.out, + scale1 = scale1, + axis.label = xaxis.label, + no.ccf = no.ccf, + axis.label.cex = axis.label.cex[['x']], + axis.cex = axis.cex[['x']], + plotting.direction = plotting.direction + ); + } if (yaxis.position != 'none' & scale.bar == FALSE) { ylabels1 <- unlist(yat[1]); ylabels2 <- unlist(yat[2]); if (yaxis.position == 'both') { - if (is.null(yaxis2.label)) { - warning('Missing second y-axis label'); - yaxis2.label <- ''; - } + if (is.null(yaxis2.label)) { + warning('Missing second y-axis label'); + yaxis2.label <- ''; + } conversion.factor <- scale1 / scale2 - ymax1 <- add.yaxis( - clone.out, - yaxis.position = 'left', - axis1.label = yaxis1.label, - no.ccf = no.ccf, - axis.label.cex = axis.label.cex[['y']], - axis.cex = axis.cex[['y']], - ylabels = ylabels1 - ); - - add.yaxis( - clone.out, - yaxis.position = 'right', - conversion.factor = conversion.factor, - axis1.label = yaxis2.label, - no.ccf = no.ccf, - axis.label.cex = axis.label.cex[['y']], - axis.cex = axis.cex[['y']], - ylabels = ylabels2 - ); + ymax1 <- add.yaxis( + clone.out, + yaxis.position = 'left', + axis1.label = yaxis1.label, + no.ccf = no.ccf, + axis.label.cex = axis.label.cex[['y']], + axis.cex = axis.cex[['y']], + ylabels = ylabels1 + ); + + add.yaxis( + clone.out, + yaxis.position = 'right', + conversion.factor = conversion.factor, + axis1.label = yaxis2.label, + no.ccf = no.ccf, + axis.label.cex = axis.label.cex[['y']], + axis.cex = axis.cex[['y']], + ylabels = ylabels2 + ); } else { - add.yaxis( - clone.out, - yaxis.position = yaxis.position, - axis1.label = yaxis1.label, - no.ccf = no.ccf, - axis.label.cex = axis.label.cex[['y']], - axis.cex = axis.cex[['y']], - ylabels = ylabels1 - ); + add.yaxis( + clone.out, + yaxis.position = yaxis.position, + axis1.label = yaxis1.label, + no.ccf = no.ccf, + axis.label.cex = axis.label.cex[['y']], + axis.cex = axis.cex[['y']], + ylabels = ylabels1 + ); } } } @@ -254,48 +255,48 @@ add.yaxis <- function( # Necessary to get the right positioning vp.unclipped <- make.plot.viewport(clone.out, clip = 'off'); - ymax <- clone.out$ymax; + ymax <- clone.out$ymax; # Set up tick labels - if (is.null(ylabels)) { - ylabels <- get.default.yat(ymax, conversion.factor); - } + if (is.null(ylabels)) { + ylabels <- get.default.yat(ymax, conversion.factor); + } - y.ticks.at <- ylabels / conversion.factor; + y.ticks.at <- ylabels / conversion.factor; - if (length(ylabels) == 0 || length(y.ticks.at) == 0) { + if (length(ylabels) == 0 || length(y.ticks.at) == 0) { warning('No y-axis ticks to draw. Skipping axis rendering.'); return(ymax); } - yaxis1 <- yaxisGrob( - name = 'axis.content', - at = y.ticks.at, - label = ylabels, - gp = gpar(cex = axis.cex), - main = yaxis.position == 'left' - ); + yaxis1 <- yaxisGrob( + name = 'axis.content', + at = y.ticks.at, + label = ylabels, + gp = gpar(cex = axis.cex), + main = yaxis.position == 'left' + ); if (max(y.ticks.at) / conversion.factor != ymax && !no.ccf) { # Extend the axis line beyond the last tick - yaxis1 <- extend.axis( - yaxis1, - limits = unit(c(0, ymax), 'native'), - type = 'y' - ); + yaxis1 <- extend.axis( + yaxis1, + limits = unit(c(0, ymax), 'native'), + type = 'y' + ); } - yaxis.gTree <- add.axis.label( - yaxis1, - axis1.label, - axis.position = yaxis.position, - axis.label.cex, - vp = vp.unclipped - ); + yaxis.gTree <- add.axis.label( + yaxis1, + axis1.label, + axis.position = yaxis.position, + axis.label.cex, + vp = vp.unclipped + ); - clone.out$grobs <- c(clone.out$grobs, list(yaxis.gTree)); + clone.out$grobs <- c(clone.out$grobs, list(yaxis.gTree)); - return(ymax) + return(ymax) } add.xaxis <- function( @@ -320,12 +321,12 @@ add.xaxis <- function( ); # Necessary to get the right positioning - vp.unclipped <- make.plot.viewport(clone.out, clip = 'off'); + vp.unclipped <- make.plot.viewport(clone.out, clip = 'off'); - # Set up tick labels - clone.widths <- as.numeric(as.matrix(clone.out$v[, c('x1', 'x2')])); - xat <- c(min(clone.widths), max(clone.widths)); - xlabels <- c(0, paste0(round(max(clone.out$v$ccf) * 100, 0), '%')); + # Set up tick labels + clone.widths <- as.numeric(as.matrix(clone.out$v[, c('x1', 'x2')])); + xat <- c(min(clone.widths), max(clone.widths)); + xlabels <- c(0, paste0(round(max(clone.out$v$ccf) * 100, 0), '%')); # Create appropriate axis grob based on position if (axis.position %in% c('left', 'right')) { @@ -337,6 +338,8 @@ add.xaxis <- function( gp = gpar(cex = axis.label.cex), main = (axis.position == 'left') ); + clone.out$ylims <- unit(clone.out$ylims * 1.5, 'native') + xaxis <- extend.axis(xaxis, unit(clone.out$ylims, 'native'), type = 'y'); } else { # For vertical plots, use xaxisGrob xaxis <- xaxisGrob( @@ -346,38 +349,18 @@ add.xaxis <- function( gp = gpar(cex = axis.label.cex), main = (axis.position == 'bottom') ); - - # Move the labels slightly for bottom position - if (axis.position == 'bottom') { - xaxis.labels <- editGrob( - getGrob(xaxis, 'labels'), - y = unit(-0.09, 'npc'), - vjust = 1 - ); - xaxis <- setGrob(xaxis, 'labels', xaxis.labels); - } + xaxis <- extend.axis(xaxis, unit(clone.out$xlims, 'native'), type = 'x'); } + # Add the axis label + xaxis.gTree <- add.axis.label( + xaxis, + axis.label, + axis.position = axis.position, + axis.label.cex, + vp = vp.unclipped + ); - # Extend the axis line to the full viewport extent so it touches - # the polygon flat edge and extends slightly past it on both sides - axis.type <- if (axis.position %in% c('left', 'right')) 'y' else 'x'; - axis.limits <- if (axis.position %in% c('left', 'right')) { - unit(clone.out$ylims, 'native') - } else { - unit(clone.out$xlims, 'native') - }; - xaxis <- extend.axis(xaxis, axis.limits, type = axis.type); - - # Add the axis label - xaxis.gTree <- add.axis.label( - xaxis, - axis.label, - axis.position = axis.position, - axis.label.cex, - vp = vp.unclipped - ); - - clone.out$grobs <- c(clone.out$grobs, list(xaxis.gTree)); + clone.out$grobs <- c(clone.out$grobs, list(xaxis.gTree)); } add.main <- function( @@ -388,43 +371,43 @@ add.main <- function( size.units = 'npc' ) { - # y.pos <- unit(1.08,'npc'); - y.pos <- unit(0.5,'npc'); - - if (!is.null(main.y)) { - pushViewport(clone.out$vp); - plot.top <- convertY(unit(1,'npc'), size.units, valueOnly = TRUE); - popViewport(); - y.pos <- plot.top + main.y; - } - - main.label <- textGrob( - main, - just = 'center', - gp = gpar( - col = 'black', - cex = main.cex - )); - - main.grob <- gTree( - children = gList(main.label), - name = 'main.gtree', - cl = 'main.label', - vp = vpStack( - make.plot.viewport( - clone.out, - clip = 'off', - just = c('centre', 'centre') - ), - viewport( - y = unit(y.pos, size.units), - x = unit(0, 'native'), - height = grobHeight(main.label), - width = grobWidth(main.label), - just = c('centre', 'bottom') - ) - ) - ); - - clone.out$grobs <- c(clone.out$grobs, list(main.grob)); + # y.pos <- unit(1.08,'npc'); + y.pos <- unit(0.5,'npc'); + + if (!is.null(main.y)) { + pushViewport(clone.out$vp); + plot.top <- convertY(unit(1,'npc'), size.units, valueOnly = TRUE); + popViewport(); + y.pos <- plot.top + main.y; + } + + main.label <- textGrob( + main, + just = 'center', + gp = gpar( + col = 'black', + cex = main.cex + )); + + main.grob <- gTree( + children = gList(main.label), + name = 'main.gtree', + cl = 'main.label', + vp = vpStack( + make.plot.viewport( + clone.out, + clip = 'off', + just = c('centre', 'centre') + ), + viewport( + y = unit(y.pos, size.units), + x = unit(0, 'native'), + height = grobHeight(main.label), + width = grobWidth(main.label), + just = c('centre', 'bottom') + ) + ) + ); + + clone.out$grobs <- c(clone.out$grobs, list(main.grob)); } From bc518c6b235d314dae778d95152d97c8e75fca37 Mon Sep 17 00:00:00 2001 From: whelena Date: Tue, 12 May 2026 16:22:23 -0700 Subject: [PATCH 05/14] make axes flush against polygon --- R/calculate.clone.polygons.R | 2 +- R/set.up.plot.area.R | 53 ++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/R/calculate.clone.polygons.R b/R/calculate.clone.polygons.R index 79f4d6f0..d7341092 100644 --- a/R/calculate.clone.polygons.R +++ b/R/calculate.clone.polygons.R @@ -34,7 +34,7 @@ make.polygon <- function( vaf <- wid; beta <- len / beta.in; - y1 <- max(y0 + beta, y0 + 1); + y1 <- y0 + beta #max(y0 + beta, y0 + 1); yy <- seq(y0, y1, length.out = 100); params.d <- c(-0.7310133, sig.shape); diff --git a/R/set.up.plot.area.R b/R/set.up.plot.area.R index f2805f2c..b651de2c 100644 --- a/R/set.up.plot.area.R +++ b/R/set.up.plot.area.R @@ -32,25 +32,30 @@ calculate.main.plot.size <- function( # Remove padding on the axis edge so the CCF axis grob sits flush # against the polygon tip. Non-cardinal angles have no defined axis side. - tol <- 1e-9; - pad.bottom <- 0 #if (abs(start.angle) < tol) 0 else padding; - pad.top <- 0 #if (abs(start.angle - pi) < tol) 0 else padding; - pad.right <- 0 #if (abs(start.angle - pi/2) < tol) 0 else padding; - pad.left <- 0 #if (abs(start.angle + pi/2) < tol) 0 else padding; - - xlims <- c(xmin - pad.left, xmax + pad.right); - ylims <- c(ymax + pad.bottom, ymin - pad.top); - - width <- (xmax - xmin + pad.left + pad.right) * scale1; - height <- (ymax - ymin + pad.bottom + pad.top) * scale1; - - if (!is.null(min.width) && width < min.width) { - expand <- (min.width - width) / (2 * scale1); - xlims[1] <- xlims[1] - expand; - xlims[2] <- xlims[2] + expand; - width <- min.width; - } - + # tol <- 1e-9; + # pad.bottom <- if (abs(start.angle) < tol) 0 else padding; + # pad.top <- if (abs(start.angle - pi) < tol) 0 else padding; + # pad.right <- if (abs(start.angle - pi/2) < tol) 0 else padding; + # pad.left <- if (abs(start.angle + pi/2) < tol) 0 else padding; + + # xlims <- c(xmin - pad.left, xmax + pad.right); + # ylims <- c(ymax + pad.bottom, ymin - pad.top); + + # width <- (xmax - xmin + pad.left + pad.right) * scale1; + # height <- (ymax - ymin + pad.bottom + pad.top) * scale1; + + xlims <- c(xmin, xmax); + ylims <- c(ymax, ymin); + + width <- (xmax - xmin) * scale1; + height <- (ymax - ymin) * scale1; + + # if (!is.null(min.width) && width < min.width) { + # expand <- (min.width - width) / (2 * scale1); + # xlims[1] <- xlims[1] - expand; + # xlims[2] <- xlims[2] + expand; + # width <- min.width; + # } clone.out$height <- height; clone.out$width <- width; clone.out$xlims <- xlims; @@ -100,13 +105,13 @@ add.axis.label <- function(axisGrob, axis.label, axis.position, axis.label.cex, just <- c('centre', 'top'); rot <- 0; x <- unit(0.5, 'npc'); - y <- (getGrob(axisGrob, 'labels')$y + getGrob(axisGrob, 'ticks')$y1) * 1.75; + y <- (getGrob(axisGrob, 'labels')$y + getGrob(axisGrob, 'ticks')$y1) * 1.5; } else if (axis.position == 'top') { d <- 'y'; just <- c('centre', 'bottom'); rot <- 0; x <- unit(0.5, 'npc'); - y <- (getGrob(axisGrob, 'labels')$y + getGrob(axisGrob, 'ticks')$y1) * 1.75; + y <- (getGrob(axisGrob, 'labels')$y + getGrob(axisGrob, 'ticks')$y1) * 1.5; } else { pushViewport(vp); @@ -338,8 +343,8 @@ add.xaxis <- function( gp = gpar(cex = axis.label.cex), main = (axis.position == 'left') ); - clone.out$ylims <- unit(clone.out$ylims * 1.5, 'native') - xaxis <- extend.axis(xaxis, unit(clone.out$ylims, 'native'), type = 'y'); + # clone.out$ylims <- unit(clone.out$ylims * 1.5, 'native') + xaxis <- extend.axis(xaxis, unit(clone.out$ylims * 1.5, 'native'), type = 'y'); } else { # For vertical plots, use xaxisGrob xaxis <- xaxisGrob( @@ -349,7 +354,7 @@ add.xaxis <- function( gp = gpar(cex = axis.label.cex), main = (axis.position == 'bottom') ); - xaxis <- extend.axis(xaxis, unit(clone.out$xlims, 'native'), type = 'x'); + xaxis <- extend.axis(xaxis, unit(clone.out$xlims * 1.5, 'native'), type = 'x'); } # Add the axis label xaxis.gTree <- add.axis.label( From 0596db077437f77ae42df2b2f1ce4f267b4c7e66 Mon Sep 17 00:00:00 2001 From: whelena Date: Tue, 12 May 2026 17:31:29 -0700 Subject: [PATCH 06/14] make sure no errors when yaxis is used --- R/set.up.plot.area.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/set.up.plot.area.R b/R/set.up.plot.area.R index b651de2c..b8bb7f4c 100644 --- a/R/set.up.plot.area.R +++ b/R/set.up.plot.area.R @@ -60,7 +60,7 @@ calculate.main.plot.size <- function( clone.out$width <- width; clone.out$xlims <- xlims; clone.out$ylims <- ylims; - # clone.out$ymax <- ymax; + clone.out$ymax <- ymax; clone.out$vp <- make.plot.viewport( clone.out, From 4bc935e1acc7c3998a3d63e814676e1aff4947a9 Mon Sep 17 00:00:00 2001 From: whelena Date: Tue, 12 May 2026 17:32:00 -0700 Subject: [PATCH 07/14] make sure normal node is centered after padding in calculate.main.plot.size is removed --- R/add.nodes.R | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/R/add.nodes.R b/R/add.nodes.R index c612de47..6944b1ab 100644 --- a/R/add.nodes.R +++ b/R/add.nodes.R @@ -3,7 +3,6 @@ add.node.ellipse <- function( node.radius, label.nodes = NULL, label.cex = NA, - add.normal = FALSE, scale1, ... ) { @@ -101,11 +100,11 @@ add.normal <- function(clone.out, node.radius, label.cex, normal.cex = 1) { vp = vpStack( make.plot.viewport(clone.out, clip = 'off'), viewport( - y = unit(1, 'npc') - unit(node.radius * normal.cex, 'inches'), + y = unit(0, 'native'), x = unit(0, 'native'), height = grobHeight(normal.box), width = grobWidth(normal.box), - just = c('centre', 'bottom') + just = c('centre', 'centre') ) ) ); From e0ddbce992a54b501caa17360f1096870318ac37 Mon Sep 17 00:00:00 2001 From: whelena Date: Tue, 12 May 2026 22:42:18 -0700 Subject: [PATCH 08/14] make text work in horizontal fishplot --- R/add.text.R | 143 ++++++++++++++++++++++++++------------ R/make.clone.tree.grobs.R | 3 +- 2 files changed, 99 insertions(+), 47 deletions(-) diff --git a/R/add.text.R b/R/add.text.R index 0ab1d86b..5659e50c 100644 --- a/R/add.text.R +++ b/R/add.text.R @@ -28,7 +28,7 @@ axis.overlap <- function( if (return.cex & !is.null(overlaps)) { new.cex <- cex; - while (!is.null(overlaps)) { + while (!is.null(overlaps) && new.cex > 0.05) { new.cex <- new.cex - 0.05; overlaps <- axis.overlap(xpos, node.text, line.dist, axis.type, new.cex, panel.width); } @@ -119,9 +119,12 @@ position.node.text <- function( split = FALSE, label.nodes = FALSE, adjust.axis.overlap = TRUE, - cex = cex + cex = cex, + plotting.direction = 'down' ) { + is.horizontal <- !is.numeric(plotting.direction) && plotting.direction %in% c('left', 'right'); + text.grob.list <- vector('list', length(unlist(node.list))); orig.cex <- cex; idx <- 1; @@ -209,10 +212,9 @@ position.node.text <- function( vjust <- 'center'; } else { ypos <- label.bottom + (g - 1) * spacing + heights - spacing; - #back computing the x position based on the intercept and the slope xpos <- ifelse( - is.infinite(slope), + is.infinite(slope) || is.horizontal, yes = tree.max.adjusted$x1[s], no = (ypos - intercept) / slope ); @@ -235,14 +237,25 @@ position.node.text <- function( no = sum(str.heights.left[c(1:(g - 1))]) ); - ypos <- label.bottom + (g - 1) * spacing + heights - spacing; - text.grob.list[[idx]] <- textGrob( - node.list[[s]][g], - x = unit(xpos - xline.dist, 'inches'), - y = unit(ypos,'inches'), - just = c('right', 'bottom'), - gp = gpar(col = node.text.col[[s]][g], cex = cex) - ); + + if (is.horizontal) { + text.grob.list[[idx]] <- textGrob( + node.list[[s]][g], + x = unit(ypos, 'inches'), + y = unit(xpos - xline.dist, 'inches'), + just = c('right', 'top'), + gp = gpar(col = node.text.col[[s]][g], cex = cex) + ); + } else { + ypos <- label.bottom + (g - 1) * spacing + heights - spacing; + text.grob.list[[idx]] <- textGrob( + node.list[[s]][g], + x = unit(xpos - xline.dist, 'inches'), + y = unit(ypos,'inches'), + just = c('right', 'bottom'), + gp = gpar(col = node.text.col[[s]][g], cex = cex) + ); + } } else { offset.left <- ceiling(length(node.text.col[[s]]) / 2); heights <- ifelse(( @@ -251,15 +264,25 @@ position.node.text <- function( no = sum(str.heights.right[c(1:(g - offset.left - 1))]) ); - ypos <- label.bottom + (g - offset.left - 1) * spacing + heights - spacing; - text.grob.list[[idx]] <- textGrob( - node.list[[s]][g], - x = unit(xpos + xline.dist, 'inches'), - y = unit(ypos, 'inches'), - just = c('left', 'bottom'), - gp = gpar(col = node.text.col[[s]][g], cex = cex) - ); + if (is.horizontal) { + text.grob.list[[idx]] <- textGrob( + node.list[[s]][g], + x = unit(xpos, 'inches'), + y = unit(ypos + xline.dist, 'inches'), + just = c('right', 'bottom'), + gp = gpar(col = node.text.col[[s]][g], cex = cex) + ); + } else { + ypos <- label.bottom + (g - offset.left - 1) * spacing + heights - spacing; + text.grob.list[[idx]] <- textGrob( + node.list[[s]][g], + x = unit(xpos + xline.dist, 'inches'), + y = unit(ypos, 'inches'), + just = c('left', 'bottom'), + gp = gpar(col = node.text.col[[s]][g], cex = cex) + ); + } } } else if (alternating) { # Alternate between placing the text to the left and to the right of the node @@ -271,15 +294,25 @@ position.node.text <- function( xline.dist.adj <- xline.dist; } - text.grob.list[[idx]] <- textGrob( - node.list[[s]][g], - x = unit(xpos + xline.dist.adj, 'inches'), - y = unit(ypos, 'inches'), - just = just, - gp = gpar(col = node.text.col[[s]][g], cex = cex) - ); + if (is.horizontal) { + text.grob.list[[idx]] <- textGrob( + node.list[[s]][g], + x = unit(xpos, 'inches'), + y = unit(ypos + xline.dist.adj, 'inches'), + just = c('center', ifelse(xline.dist.adj > 0, 'bottom', 'top')), + gp = gpar(col = node.text.col[[s]][g], cex = cex) + ); + } else { + text.grob.list[[idx]] <- textGrob( + node.list[[s]][g], + x = unit(xpos + xline.dist.adj, 'inches'), + y = unit(ypos, 'inches'), + just = just, + gp = gpar(col = node.text.col[[s]][g], cex = cex) + ); + } - if (adjust.axis.overlap) { + if (adjust.axis.overlap && !is.horizontal) { overlaps.axis <- axis.overlap( xpos, node.list[[s]][g], xline.dist.adj, @@ -304,7 +337,8 @@ position.node.text <- function( node.radius = node.radius, alternating = alternating, split = split, - label.nodes = label.nodes + label.nodes = label.nodes, + plotting.direction = plotting.direction ); return(text.grob.list); @@ -418,7 +452,7 @@ position.node.text <- function( } } - if (adjust.axis.overlap) { + if (adjust.axis.overlap && !is.horizontal) { overlaps.axis <- axis.overlap( xpos, node.list[[s]][g], @@ -444,7 +478,8 @@ position.node.text <- function( node.radius = node.radius, alternating = alternating, split = split, - label.nodes = label.nodes + label.nodes = label.nodes, + plotting.direction = plotting.direction ); return(text.grob.list); @@ -452,17 +487,33 @@ position.node.text <- function( } } - text.grob.list[[idx]] <- textGrob( - node.list[[s]][g], - x = unit(xpos + xline.dist, 'inches'), - y = unit(ypos, 'inches'), - just = c(hjust, vjust), - gp = gpar( - col = node.text.col[[s]][g], - fontface = node.text.fontface[[s]][g], - cex = cex - ) - ); + if (is.horizontal) { + offset.x <- ceiling(length(node.text.col[[s]]) / 2); + xpos <- tree.max.adjusted$x1[s] - ((tree.max.adjusted$x1[s] - tree.max.adjusted$x0[s]) * 0.5); + text.grob.list[[idx]] <- textGrob( + node.list[[s]][g], + x = unit(xpos, 'inches'), + y = unit(ypos + xline.dist, 'inches'), + just = c('center', ifelse(xline.dist > 0, 'bottom', 'top')), + gp = gpar( + col = node.text.col[[s]][g], + fontface = node.text.fontface[[s]][g], + cex = cex + ) + ); + } else { + text.grob.list[[idx]] <- textGrob( + node.list[[s]][g], + x = unit(xpos + xline.dist, 'inches'), + y = unit(ypos, 'inches'), + just = c(hjust, vjust), + gp = gpar( + col = node.text.col[[s]][g], + fontface = node.text.fontface[[s]][g], + cex = cex + ) + ); + } } idx <- idx + 1; @@ -490,13 +541,13 @@ add.text2 <- function( node.radius = NULL, alternating = TRUE, split = TRUE, - clone.out = NULL + clone.out = NULL, + plotting.direction = 'down' ) { # Radius in native units node.radius <- node.radius / scale; node.text <- node.text[node.text$node %in% tree$tip, ]; - node.list <- vector('list', nrow(tree)); node.text.col <- vector('list', nrow(tree)); node.text.fontface <- vector('list', nrow(tree)); @@ -591,7 +642,6 @@ add.text2 <- function( tree.max.adjusted$slope <- (tree.max.adjusted$y1 - tree.max.adjusted$y0) / (tree.max.adjusted$x1 - tree.max.adjusted$x0); tree.max.adjusted$intercept <- tree.max.adjusted$y1 - tree.max.adjusted$slope * tree.max.adjusted$x1; - text.grob.list <- position.node.text( tree.max.adjusted = tree.max.adjusted, node.list = node.list, @@ -606,7 +656,8 @@ add.text2 <- function( node.radius = node.radius, alternating = alternating, split = split, - label.nodes = label.nodes + label.nodes = label.nodes, + plotting.direction = plotting.direction ); text.grob.gList <- do.call(gList, text.grob.list); diff --git a/R/make.clone.tree.grobs.R b/R/make.clone.tree.grobs.R index 121e6ca8..aca57fa3 100644 --- a/R/make.clone.tree.grobs.R +++ b/R/make.clone.tree.grobs.R @@ -232,7 +232,8 @@ make.clone.tree.grobs <- function( node.radius = node.radius, scale = scale1, clone.out = clone.out, - alternating = FALSE + alternating = FALSE, + plotting.direction = plotting.direction ); clone.out$grobs <- c(clone.out$grobs, list(node.text.grobs)); From 71cdfc1a4882ee500ffe8c7fb0f20a1b47f1d203 Mon Sep 17 00:00:00 2001 From: whelena Date: Tue, 12 May 2026 23:42:32 -0700 Subject: [PATCH 09/14] fix axes label --- R/set.up.plot.area.R | 64 ++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/R/set.up.plot.area.R b/R/set.up.plot.area.R index b8bb7f4c..665138bf 100644 --- a/R/set.up.plot.area.R +++ b/R/set.up.plot.area.R @@ -101,38 +101,56 @@ extend.axis <- function(axisGrob, limits, type) { add.axis.label <- function(axisGrob, axis.label, axis.position, axis.label.cex, vp) { if (axis.position == 'bottom') { - d <- 'y'; + # d <- 'y'; just <- c('centre', 'top'); rot <- 0; x <- unit(0.5, 'npc'); y <- (getGrob(axisGrob, 'labels')$y + getGrob(axisGrob, 'ticks')$y1) * 1.5; } else if (axis.position == 'top') { - d <- 'y'; + # d <- 'y'; just <- c('centre', 'bottom'); rot <- 0; x <- unit(0.5, 'npc'); - y <- (getGrob(axisGrob, 'labels')$y + getGrob(axisGrob, 'ticks')$y1) * 1.5; + y <- (getGrob(axisGrob, 'ticks')$y0) * 1.4; + # y <- unit( + # # convertY(getGrob(axisGrob, 'labels')$y, 'mm', valueOnly = TRUE), + # convertY(getGrob(axisGrob, 'ticks')$y0 * axisGrob$gp$cex, 'mm', valueOnly = TRUE), + # # convertY(unit(1, 'lines') * axisGrob$gp$cex, 'mm', valueOnly = TRUE), + # 'mm' + # ); + # x <- unit( + # convertX(grobWidth(getGrob(axisGrob, 'labels')), 'mm', valueOnly = TRUE) * -(axisGrob$gp$cex) + + # convertX(unit(1, 'lines') * axisGrob$gp$cex, 'mm', valueOnly = TRUE) + + # convertX(getGrob(axisGrob, 'labels')$x * axisGrob$gp$cex, 'mm', valueOnly = TRUE), + # 'mm' + # ); + } else { pushViewport(vp); - tick.length <- unit( - diff(c( - as.numeric(getGrob(axisGrob, 'ticks')$x0), - as.numeric(getGrob(axisGrob, 'ticks')$x1) - )), - 'lines' - ); - - y <- convertY( - unit(max(as.numeric(getGrob(axisGrob, 'major')$y)) * 0.5, 'native'), - 'inches' - ); - + tick.length <- unit( 0.5, 'lines') * axisGrob$gp$cex; + # diff(c( + # (getGrob(axisGrob, 'ticks')$x0), + # (getGrob(axisGrob, 'ticks')$x1) + # )), + # 'lines' + # ); + # print((getGrob(axisGrob, 'ticks')$x0)) + # print((getGrob(axisGrob, 'ticks')$x1)) + # print(tick.length) + # y <- convertY( + # unit(max(as.numeric(getGrob(axisGrob, 'major')$y)), 'native'), + # 'inches' + # ); + y <- unit(mean(as.numeric(getGrob(axisGrob, 'major')$y)), 'native') + if (axis.position == 'left') { - d <- 'x'; + # d <- 'x'; just <- c('right', 'centre'); rot <- 90; - + + # x <- getGrob(axisGrob, 'labels')$x + (tick.length * 1.5); + # x <- (getGrob(axisGrob, 'labels')$x + tick.length) * 1.5; x <- unit( convertX(grobWidth(getGrob(axisGrob, 'labels')), 'mm', valueOnly = TRUE) * -(axisGrob$gp$cex) - convertX(unit(1, 'lines') * axisGrob$gp$cex, 'mm', valueOnly = TRUE) + @@ -140,9 +158,15 @@ add.axis.label <- function(axisGrob, axis.label, axis.position, axis.label.cex, 'mm' ); } else if (axis.position == 'right') { - d <- 'x'; + # d <- 'x'; just <- c('left', 'centre'); - x <- (getGrob(axisGrob, 'labels')$x + tick.length) * 1.5; + # x <- getGrob(axisGrob, 'labels')$x + (tick.length * 1.5); + x <- unit( + convertX(grobWidth(getGrob(axisGrob, 'labels')), 'mm', valueOnly = TRUE) * -(axisGrob$gp$cex) + + convertX(unit(1, 'lines') * axisGrob$gp$cex, 'mm', valueOnly = TRUE) + + convertX(getGrob(axisGrob, 'labels')$x * axisGrob$gp$cex, 'mm', valueOnly = TRUE), + 'mm' + ); rot <- 270; } From 58edd15ac514da72516ce33990ec45d746b2def1 Mon Sep 17 00:00:00 2001 From: whelena Date: Thu, 14 May 2026 14:25:58 -0700 Subject: [PATCH 10/14] clean up axis labels placing --- R/set.up.plot.area.R | 96 +++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 64 deletions(-) diff --git a/R/set.up.plot.area.R b/R/set.up.plot.area.R index 665138bf..35eae415 100644 --- a/R/set.up.plot.area.R +++ b/R/set.up.plot.area.R @@ -82,7 +82,6 @@ make.plot.viewport <- function( name = 'plot.vp', xscale = clone.out$xlims, yscale = clone.out$ylims, - # yscale = c(clone.out$ymax, 0), just = just, gp = gpar(fill = 'pink'), clip = clip @@ -100,79 +99,48 @@ extend.axis <- function(axisGrob, limits, type) { } add.axis.label <- function(axisGrob, axis.label, axis.position, axis.label.cex, vp) { + pushViewport(vp); + + label.grob <- getGrob(axisGrob, 'labels'); + ticks.grob <- getGrob(axisGrob, 'ticks'); + gap.mm <- convertX(unit(1.5, 'lines'), 'mm', valueOnly = TRUE); + if (axis.position == 'bottom') { - # d <- 'y'; - just <- c('centre', 'top'); - rot <- 0; - x <- unit(0.5, 'npc'); - y <- (getGrob(axisGrob, 'labels')$y + getGrob(axisGrob, 'ticks')$y1) * 1.5; + just <- c('centre', 'top'); + rot <- 0; + x <- unit(0.5, 'npc'); + label.y.mm <- convertY(label.grob$y, 'mm', valueOnly = TRUE); + label.h.mm <- convertY(grobHeight(label.grob), 'mm', valueOnly = TRUE); + # bottom axis: tick labels extend downward from label.y.mm; + # outer (bottom) edge = label.y.mm - label.h.mm; step down by gap + y <- unit(label.y.mm - label.h.mm - gap.mm, 'mm'); } else if (axis.position == 'top') { - # d <- 'y'; - just <- c('centre', 'bottom'); - rot <- 0; - x <- unit(0.5, 'npc'); - y <- (getGrob(axisGrob, 'ticks')$y0) * 1.4; - # y <- unit( - # # convertY(getGrob(axisGrob, 'labels')$y, 'mm', valueOnly = TRUE), - # convertY(getGrob(axisGrob, 'ticks')$y0 * axisGrob$gp$cex, 'mm', valueOnly = TRUE), - # # convertY(unit(1, 'lines') * axisGrob$gp$cex, 'mm', valueOnly = TRUE), - # 'mm' - # ); - # x <- unit( - # convertX(grobWidth(getGrob(axisGrob, 'labels')), 'mm', valueOnly = TRUE) * -(axisGrob$gp$cex) + - # convertX(unit(1, 'lines') * axisGrob$gp$cex, 'mm', valueOnly = TRUE) + - # convertX(getGrob(axisGrob, 'labels')$x * axisGrob$gp$cex, 'mm', valueOnly = TRUE), - # 'mm' - # ); - + just <- c('centre', 'bottom'); + rot <- 0; + x <- unit(0.5, 'npc'); + label.y.mm <- convertY(label.grob$y, 'mm', valueOnly = TRUE); + label.h.mm <- convertY(grobHeight(label.grob), 'mm', valueOnly = TRUE); + # top axis: tick labels extend upward from label.y.mm; + # outer (top) edge = label.y.mm + label.h.mm; step up by gap + y <- unit(label.y.mm + label.h.mm + gap.mm, 'mm'); } else { - pushViewport(vp); - - tick.length <- unit( 0.5, 'lines') * axisGrob$gp$cex; - # diff(c( - # (getGrob(axisGrob, 'ticks')$x0), - # (getGrob(axisGrob, 'ticks')$x1) - # )), - # 'lines' - # ); - # print((getGrob(axisGrob, 'ticks')$x0)) - # print((getGrob(axisGrob, 'ticks')$x1)) - # print(tick.length) - # y <- convertY( - # unit(max(as.numeric(getGrob(axisGrob, 'major')$y)), 'native'), - # 'inches' - # ); - y <- unit(mean(as.numeric(getGrob(axisGrob, 'major')$y)), 'native') - + label.x.mm <- convertX(label.grob$x, 'mm', valueOnly = TRUE); + label.w.mm <- convertX(grobWidth(label.grob), 'mm', valueOnly = TRUE); + y <- unit(mean(as.numeric(getGrob(axisGrob, 'major')$y)), 'native'); + if (axis.position == 'left') { - # d <- 'x'; just <- c('right', 'centre'); - rot <- 90; - - # x <- getGrob(axisGrob, 'labels')$x + (tick.length * 1.5); - # x <- (getGrob(axisGrob, 'labels')$x + tick.length) * 1.5; - x <- unit( - convertX(grobWidth(getGrob(axisGrob, 'labels')), 'mm', valueOnly = TRUE) * -(axisGrob$gp$cex) - - convertX(unit(1, 'lines') * axisGrob$gp$cex, 'mm', valueOnly = TRUE) + - convertX(getGrob(axisGrob, 'labels')$x * axisGrob$gp$cex, 'mm', valueOnly = TRUE), - 'mm' - ); + rot <- 90; + x <- unit(label.x.mm - label.w.mm - gap.mm, 'mm'); } else if (axis.position == 'right') { - # d <- 'x'; just <- c('left', 'centre'); - # x <- getGrob(axisGrob, 'labels')$x + (tick.length * 1.5); - x <- unit( - convertX(grobWidth(getGrob(axisGrob, 'labels')), 'mm', valueOnly = TRUE) * -(axisGrob$gp$cex) + - convertX(unit(1, 'lines') * axisGrob$gp$cex, 'mm', valueOnly = TRUE) + - convertX(getGrob(axisGrob, 'labels')$x * axisGrob$gp$cex, 'mm', valueOnly = TRUE), - 'mm' - ); - rot <- 270; + rot <- 270; + x <- unit(label.x.mm + label.w.mm + gap.mm, 'mm'); } - - popViewport() } + popViewport(); + axis.lab <- textGrob( name = 'axis.label', axis.label, From ab0e9ffcd0a83e2da2e15d1b3465149fc82d0a2a Mon Sep 17 00:00:00 2001 From: whelena Date: Thu, 14 May 2026 14:54:15 -0700 Subject: [PATCH 11/14] add gurdrails to iterative loops --- R/add.text.R | 10 ++++++++-- R/set.up.plot.area.R | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/R/add.text.R b/R/add.text.R index 5659e50c..552375c5 100644 --- a/R/add.text.R +++ b/R/add.text.R @@ -194,6 +194,10 @@ position.node.text <- function( (!label.nodes && (label.bottom + str.heightsum) > (tree.max.adjusted$y0[s] + node.radius * 0.5)) ) { cex <- cex - 0.05; + if (cex < 0.01) { + cex <- 0.01; + break; + } } } @@ -462,8 +466,10 @@ position.node.text <- function( return.cex = TRUE ); - # Shrink the text if they overlap - if (!is.null(overlaps.axis)) { + # Shrink the text if they overlap; only recurse when + # axis.overlap found a strictly smaller cex, otherwise + # we would loop infinitely at the minimum cex value. + if (!is.null(overlaps.axis) && overlaps.axis < cex) { text.grob.list <- position.node.text( tree.max.adjusted = tree.max.adjusted, node.list = node.list, diff --git a/R/set.up.plot.area.R b/R/set.up.plot.area.R index f7ec0258..03747167 100644 --- a/R/set.up.plot.area.R +++ b/R/set.up.plot.area.R @@ -44,6 +44,12 @@ calculate.main.plot.size <- function( # width <- (xmax - xmin + pad.left + pad.right) * scale1; # height <- (ymax - ymin + pad.bottom + pad.top) * scale1; + # Guard against degenerate scales (e.g. all nodes at x=0 when polygons are disabled) + if (xmax == xmin) { + xmin <- xmin - 0.5; + xmax <- xmax + 0.5; + } + xlims <- c(xmin, xmax); ylims <- c(ymax, ymin); From 0855ceb869485b3858a0f7cfda0c52d27d4d5fcb Mon Sep 17 00:00:00 2001 From: whelena Date: Thu, 14 May 2026 14:54:47 -0700 Subject: [PATCH 12/14] add script to update .Rda files for tests --- .../data/branching.dendrogram.plots.Rda | Bin 5129 -> 5165 bytes tests/testthat/data/branching.fixed.plots.Rda | Bin 9034 -> 9004 bytes .../testthat/data/branching.radial.plots.Rda | Bin 16193 -> 16580 bytes tests/testthat/data/complex.plots.Rda | Bin 17203 -> 17216 bytes tests/testthat/data/fish.plots.Rda | Bin 14689 -> 15396 bytes tests/testthat/data/linear.plots.Rda | Bin 13080 -> 12969 bytes tests/update-snapshots.R | 181 ++++++++++++++++++ 7 files changed, 181 insertions(+) create mode 100644 tests/update-snapshots.R diff --git a/tests/testthat/data/branching.dendrogram.plots.Rda b/tests/testthat/data/branching.dendrogram.plots.Rda index 38f25e0d4ee535dc07d7ffc3cab36023c6f627b6..5ffcae215f737d6654e0394c8572628372161726 100644 GIT binary patch literal 5165 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 BQ04#t literal 5129 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 literal 9034 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 diff --git a/tests/testthat/data/branching.radial.plots.Rda b/tests/testthat/data/branching.radial.plots.Rda index 1addead47ba11e420cc4ed8cafdc53814df9a43e..a42ad71fe3714f25da6fffa3bc22b62a0ab5a70f 100644 GIT binary patch literal 16580 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 R?1g8$s)=g3eVBse{{d>M$z}im diff --git a/tests/testthat/data/complex.plots.Rda b/tests/testthat/data/complex.plots.Rda index 2399db92a268978fbe1ef1906fa854eb0f8eb894..7b122ca7ca18062e353ea1cc52b43ae565b906a6 100644 GIT binary patch literal 17216 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¬)FHhqyjY&wZZCDg)X@Bw2 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 diff --git a/tests/testthat/data/fish.plots.Rda b/tests/testthat/data/fish.plots.Rda index fb4524b897ef6006b0189a9962b7c499359a0e52..a0d641cce6ddd353ba9546b19b734838d9c38187 100644 GIT binary patch literal 15396 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 diff --git a/tests/testthat/data/linear.plots.Rda b/tests/testthat/data/linear.plots.Rda index a1ec3d0af67641a3531c6666212ce04c0ebfbb22..86c5a8d203e77e8ed7a9f23884cec8cbbb2add76 100644 GIT binary patch literal 12969 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 Dcxddf literal 13080 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 ho=E4w*bWHoKfR2v<@QSpEX*fd-B Date: Thu, 14 May 2026 15:04:14 -0700 Subject: [PATCH 13/14] remove comments --- R/set.up.plot.area.R | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/R/set.up.plot.area.R b/R/set.up.plot.area.R index 03747167..2973a251 100644 --- a/R/set.up.plot.area.R +++ b/R/set.up.plot.area.R @@ -30,20 +30,6 @@ calculate.main.plot.size <- function( ymin <- min(all.y); ymax <- max(all.y); - # Remove padding on the axis edge so the CCF axis grob sits flush - # against the polygon tip. Non-cardinal angles have no defined axis side. - # tol <- 1e-9; - # pad.bottom <- if (abs(start.angle) < tol) 0 else padding; - # pad.top <- if (abs(start.angle - pi) < tol) 0 else padding; - # pad.right <- if (abs(start.angle - pi/2) < tol) 0 else padding; - # pad.left <- if (abs(start.angle + pi/2) < tol) 0 else padding; - - # xlims <- c(xmin - pad.left, xmax + pad.right); - # ylims <- c(ymax + pad.bottom, ymin - pad.top); - - # width <- (xmax - xmin + pad.left + pad.right) * scale1; - # height <- (ymax - ymin + pad.bottom + pad.top) * scale1; - # Guard against degenerate scales (e.g. all nodes at x=0 when polygons are disabled) if (xmax == xmin) { xmin <- xmin - 0.5; @@ -56,12 +42,6 @@ calculate.main.plot.size <- function( width <- (xmax - xmin) * scale1; height <- (ymax - ymin) * scale1; - # if (!is.null(min.width) && width < min.width) { - # expand <- (min.width - width) / (2 * scale1); - # xlims[1] <- xlims[1] - expand; - # xlims[2] <- xlims[2] + expand; - # width <- min.width; - # } clone.out$height <- height; clone.out$width <- width; clone.out$xlims <- xlims; From 98f31a29037ffb32f7ce04e3c86ac4a3036e1ad5 Mon Sep 17 00:00:00 2001 From: whelena Date: Thu, 14 May 2026 17:06:24 -0700 Subject: [PATCH 14/14] fix lintr --- R/add.text.R | 2 -- tests/update-snapshots.R | 14 +++++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/R/add.text.R b/R/add.text.R index 552375c5..df05d38b 100644 --- a/R/add.text.R +++ b/R/add.text.R @@ -241,7 +241,6 @@ position.node.text <- function( no = sum(str.heights.left[c(1:(g - 1))]) ); - if (is.horizontal) { text.grob.list[[idx]] <- textGrob( node.list[[s]][g], @@ -268,7 +267,6 @@ position.node.text <- function( no = sum(str.heights.right[c(1:(g - offset.left - 1))]) ); - if (is.horizontal) { text.grob.list[[idx]] <- textGrob( node.list[[s]][g], diff --git a/tests/update-snapshots.R b/tests/update-snapshots.R index 55079384..81a9999e 100644 --- a/tests/update-snapshots.R +++ b/tests/update-snapshots.R @@ -26,7 +26,7 @@ data.dir <- file.path(pkg.root, 'tests', 'testthat', 'data') # Helper # --------------------------------------------------------------------------- -update_rda <- function(filename, ...) { +update.rda <- function(filename, ...) { path <- file.path(data.dir, filename) vars <- list(...) list2env(vars, envir = environment()) @@ -49,7 +49,7 @@ local({ plotting.direction = 30 ) - update_rda( + update.rda( 'branching.fixed.plots.Rda', branching.fixed.example = branching.fixed.example, branching.fixed.30deg.example = branching.fixed.30deg.example @@ -76,7 +76,7 @@ local({ plotting.direction = 30 ) - update_rda( + update.rda( 'branching.radial.plots.Rda', branching.radial.example = branching.radial.example, branching.radial.right.example = branching.radial.right.example, @@ -94,7 +94,7 @@ local({ branching.dendrogram.example <- SRCGrob(branching.dendrogram.test.data$tree) - update_rda( + update.rda( 'branching.dendrogram.plots.Rda', branching.dendrogram.example = branching.dendrogram.example ) @@ -113,7 +113,7 @@ local({ polygon.colour.scheme = fish.test.data$colour.scheme ) - update_rda( + update.rda( 'fish.plots.Rda', fish.example = fish.example ) @@ -149,7 +149,7 @@ local({ plotting.direction = 30 ) - update_rda( + update.rda( 'linear.plots.Rda', linear.example = linear.example, linear.30deg.example = linear.30deg.example @@ -171,7 +171,7 @@ local({ plotting.direction = 30 ) - update_rda( + update.rda( 'complex.plots.Rda', spread.example = spread.example, spread.30deg.example = spread.30deg.example