|
| 1 | +#!/usr/bin/env Rscript |
| 2 | +# |
| 3 | +# Midpoint-root a phylogeny and plot tip labels as circles with clade colors. |
| 4 | +# Writes rooted.tree and tree_figure.pdf in the same directory as the input tree. |
| 5 | +# |
| 6 | +# Usage: Rscript root_tree_figure.R [treefile] |
| 7 | +# Default: alignment.treefile (when run from phylogeny dir) |
| 8 | +# |
| 9 | +# Requires: ape, phytools, ggtree, ggplot2. |
| 10 | + |
| 11 | +args <- commandArgs(trailingOnly = TRUE) |
| 12 | +tree_path <- if (length(args) >= 1) args[1] else "alignment.treefile" |
| 13 | +out_dir <- dirname(tree_path) |
| 14 | +if (out_dir == "") out_dir <- "." |
| 15 | + |
| 16 | +if (!file.exists(tree_path)) { |
| 17 | + stop("Tree file not found: ", tree_path) |
| 18 | +} |
| 19 | + |
| 20 | +suppressPackageStartupMessages({ |
| 21 | + library(ape) |
| 22 | + library(phytools) |
| 23 | + library(ggtree) |
| 24 | + library(ggplot2) |
| 25 | +}) |
| 26 | +old_warn <- getOption("warn") |
| 27 | +on.exit(options(warn = old_warn), add = TRUE) |
| 28 | +options(warn = -1) |
| 29 | + |
| 30 | +tr <- read.tree(tree_path) |
| 31 | +tr <- phytools::midpoint.root(tr) |
| 32 | +rooted_path <- file.path(out_dir, "rooted.tree") |
| 33 | +write.tree(tr, rooted_path) |
| 34 | + |
| 35 | +labels <- tr$tip.label |
| 36 | +type <- ifelse(grepl("_tracts", labels, fixed = TRUE), "recombinant", "reference") |
| 37 | +clade <- rep("Ia", length(labels)) |
| 38 | +clade[type == "recombinant"] <- "Recombinant" |
| 39 | +clade[grepl("sh2024Ib", labels, fixed = TRUE)] <- "sh2024Ib" |
| 40 | +clade[grepl("sh2023Ib", labels, fixed = TRUE)] <- "sh2024Ib" |
| 41 | +clade[grepl("sh2024[iI]a", labels)] <- "sh2024Ia" |
| 42 | +clade[grepl("sh2017IIb", labels, fixed = TRUE)] <- "sh2017IIb" |
| 43 | +clade[grepl("_IIa_", labels, fixed = TRUE)] <- "IIa" |
| 44 | +clade[grepl("^IIa_", labels)] <- "IIa" |
| 45 | +tip_data <- data.frame(label = labels, type = type, clade = clade, stringsAsFactors = FALSE) |
| 46 | +tip_data$plot_clade <- ifelse(tip_data$clade == "sh2024Ib", "sh2023Ib", tip_data$clade) |
| 47 | + |
| 48 | +p <- ggtree(tr, linewidth = 0.65) |
| 49 | +clade_colors <- c( |
| 50 | + Recombinant = "#FF6B9D", |
| 51 | + Ia = "#1e5f72", |
| 52 | + sh2024Ia = "#b83c28", |
| 53 | + sh2023Ib = "#2d7a4a", |
| 54 | + sh2017IIb = "#c97a08", |
| 55 | + IIa = "#5c2270" |
| 56 | +) |
| 57 | +tip_size <- 4.2 |
| 58 | +legend_order <- c("sh2023Ib", "sh2024Ia", "Ia", "sh2017IIb", "IIa", "Recombinant") |
| 59 | +legend_labels <- c( |
| 60 | + sh2023Ib = "Ib (sh2023Ib)", |
| 61 | + sh2024Ia = "Ia (sh2024Ia)", |
| 62 | + Ia = "Ia (non-sh2024Ia)", |
| 63 | + sh2017IIb = "IIb (sh2017IIb)", |
| 64 | + IIa = "IIa", |
| 65 | + Recombinant = "Potential recombinant" |
| 66 | +) |
| 67 | + |
| 68 | +p <- p %<+% tip_data + |
| 69 | + geom_tippoint(aes(fill = plot_clade), size = tip_size, shape = 21, color = "black", stroke = 0.5) + |
| 70 | + scale_fill_manual( |
| 71 | + values = clade_colors, |
| 72 | + breaks = legend_order, |
| 73 | + labels = legend_labels, |
| 74 | + na.value = "grey70", |
| 75 | + name = "Clade", |
| 76 | + drop = FALSE |
| 77 | + ) + |
| 78 | + theme( |
| 79 | + legend.position = c(0.18, 0.97), |
| 80 | + legend.justification = c(0.5, 1), |
| 81 | + legend.background = element_rect(fill = "white", colour = "black", linewidth = 0.4), |
| 82 | + legend.margin = margin(5, 5, 5, 5), |
| 83 | + legend.spacing.y = unit(4.5, "mm"), |
| 84 | + legend.key.size = unit(6.75, "mm"), |
| 85 | + legend.title = element_text(face = "bold", size = 15), |
| 86 | + legend.text = element_text(size = 13.5), |
| 87 | + text = element_text(family = "sans") |
| 88 | + ) |
| 89 | + |
| 90 | +tree_depth <- max(ape::node.depth.edgelength(tr)) |
| 91 | +p <- p + |
| 92 | + geom_tiplab(aes(label = label), size = 2.4, hjust = -0.04, align = TRUE, linesize = 0.2) + |
| 93 | + xlim_tree(tree_depth * 1.25) |
| 94 | +p <- p + geom_treescale(x = 0, y = -1, width = 0.002, fontsize = 2.8, linesize = 0.4) |
| 95 | + |
| 96 | +fig_height <- max(8, length(tr$tip.label) * 0.15) |
| 97 | +pdf_path <- file.path(out_dir, "tree_figure.pdf") |
| 98 | +ggsave(pdf_path, p, width = 12, height = fig_height, limitsize = FALSE) |
| 99 | +# Use base R SVG device (no svglite package required) |
| 100 | +svg_path <- file.path(out_dir, "tree_figure.svg") |
| 101 | +ggsave(svg_path, p, width = 12, height = fig_height, limitsize = FALSE, device = grDevices::svg) |
0 commit comments