Skip to content

Instantly share code, notes, and snippets.

@loukesio
Last active March 15, 2026 21:56
Show Gist options
  • Select an option

  • Save loukesio/dd393494f23499ca1313148fdc662abe to your computer and use it in GitHub Desktop.

Select an option

Save loukesio/dd393494f23499ca1313148fdc662abe to your computer and use it in GitHub Desktop.
# ============================================================
# ggtree Layout Gallery
# Figure 1: Base Layouts
# Figure 2: Derived Layouts (scale & coordinate transforms)
# ============================================================
library(ggplot2)
library(ggtree)
library(ape)
library(patchwork)
library(ggplotify)
# --- Reproducible tree -------------------------------------------------------
set.seed(2017-02-16)
tree <- rtree(50)
# --- Shared theme ------------------------------------------------------------
clean <- theme_void() +
theme(
plot.title = element_text(size = 10, face = "bold", hjust = 0.5,
margin = margin(t = 2, b = 4)),
plot.margin = margin(6, 6, 6, 6)
)
# ============================================================
# FIGURE 1: Base Layouts (12 panels, 4x3)
# ============================================================
p1 <- ggtree(tree) + ggtitle("A") + clean
p2 <- ggtree(tree, layout = "roundrect") + ggtitle("B") + clean
p3 <- ggtree(tree, layout = "slanted") + ggtitle("C") + clean
p4 <- ggtree(tree, layout = "ellipse") + ggtitle("D") + clean
p5 <- ggtree(tree, layout = "circular") + ggtitle("E") + clean
p6 <- ggtree(tree, layout = "fan", open.angle = 120) + ggtitle("F") + clean
p7 <- ggtree(tree, layout = "equal_angle") + ggtitle("G") + clean
p8 <- ggtree(tree, layout = "daylight") + ggtitle("H") + clean
p9 <- ggtree(tree, branch.length = "none") + ggtitle("I") + clean
p10 <- ggtree(tree, layout = "ellipse", branch.length = "none") + ggtitle("J") + clean
p11 <- ggtree(tree, branch.length = "none", layout = "circular") + ggtitle("K") + clean
p12 <- ggtree(tree, layout = "daylight", branch.length = "none") + ggtitle("L") + clean
fig1 <- p1 + p2 + p3 + p4 +
p5 + p6 + p7 + p8 +
p9 + p10 + p11 + p12 +
plot_layout(ncol = 4) +
plot_annotation(
title = "ggtree Base Layouts",
subtitle = paste0(
"The same 50-tip random tree rendered across twelve layout variants.\n",
"Top row: rectangular and geometric layouts with branch lengths.\n",
"Middle row: circular, fan, and unrooted layouts. Bottom row: cladograms (branch.length = 'none')."
),
caption = paste(
"(A) Rectangular,",
"(B) roundrect,",
"(C) slanted,",
"(D) ellipse,",
"(E) circular,",
"(F) fan (open.angle = 120),\n",
"(G) equal_angle,",
"(H) daylight,",
"(I) rectangular cladogram,",
"(J) ellipse cladogram,",
"(K) circular cladogram,",
"(L) daylight cladogram."
),
theme = theme(
plot.title = element_text(size = 16, face = "bold", hjust = 0.5,
margin = margin(b = 4)),
plot.subtitle = element_text(size = 9, hjust = 0.5, color = "grey30",
lineheight = 1.4, margin = margin(b = 10)),
plot.caption = element_text(size = 8, hjust = 0, color = "grey40",
lineheight = 1.5, margin = margin(t = 10)),
plot.margin = margin(15, 15, 15, 15)
)
)
suppressWarnings(
ggsave("ggtree_base_layouts.png", plot = fig1,
width = 16, height = 14, dpi = 300, bg = "white")
)
fig1
# ============================================================
# FIGURE 2: Derived Layouts (9 panels, 3x3)
# ============================================================
d_a <- ggtree(tree) + scale_x_reverse() + ggtitle("A") + clean
d_b <- ggtree(tree) + coord_flip() + ggtitle("B") + clean
d_c <- ggtree(tree) + layout_dendrogram() + ggtitle("C") + clean
d_d <- suppressWarnings(
as.ggplot(ggtree(tree), angle = -30, scale = 0.9)
) + ggtitle("D") + clean
d_e <- ggtree(tree, layout = "slanted") + coord_flip() + ggtitle("E") + clean
d_f <- ggtree(tree, layout = "slanted", branch.length = "none") +
layout_dendrogram() + ggtitle("F") + clean
d_g <- ggtree(tree, layout = "circular") + xlim(-10, NA) + ggtitle("G") + clean
d_h <- ggtree(tree) + layout_inward_circular() + ggtitle("H") + clean
d_i <- ggtree(tree) + layout_inward_circular(xlim = 15) + ggtitle("I") + clean
fig2 <- d_a + d_b + d_c +
d_d + d_e + d_f +
d_g + d_h + d_i +
plot_layout(ncol = 3) +
plot_annotation(
title = "ggtree Derived Layouts",
subtitle = paste0(
"The same 50-tip tree transformed via scale, coordinate, and layout functions.\n",
"These build on base layouts by flipping, rotating, or wrapping the tree."
),
caption = paste(
"(A) Right-to-left rectangular via scale_x_reverse(),",
"(B) bottom-up rectangular via coord_flip(),",
"(C) top-down dendrogram via layout_dendrogram(),\n",
"(D) rotated rectangular via ggplotify::as.ggplot(angle = -30),",
"(E) bottom-up slanted via coord_flip(),",
"(F) top-down cladogram via layout_dendrogram(),\n",
"(G) circular with expanded xlim,",
"(H) inward circular via layout_inward_circular(),",
"(I) inward circular with xlim = 15."
),
theme = theme(
plot.title = element_text(size = 16, face = "bold", hjust = 0.5,
margin = margin(b = 4)),
plot.subtitle = element_text(size = 9, hjust = 0.5, color = "grey30",
lineheight = 1.4, margin = margin(b = 10)),
plot.caption = element_text(size = 8, hjust = 0, color = "grey40",
lineheight = 1.5, margin = margin(t = 10)),
plot.margin = margin(15, 15, 15, 15)
)
)
fig2
suppressWarnings(
ggsave("ggtree_derived_layouts.png", plot = fig2,
width = 14, height = 16, dpi = 300, bg = "white")
)
# ============================================================
# FIGURE 3: Branch Styling (6 panels, 3x2)
# ============================================================
library(ltc)
alger <- ltc("alger", 6, "continuous")
# Use a smaller tree for readability with labels
set.seed(2017-02-16)
stree <- rtree(15)
s_a <- ggtree(stree) +
ggtitle("A") + clean
s_b <- ggtree(stree, color = alger[1], linewidth = 1.2) +
ggtitle("B") + clean
s_c <- ggtree(stree, color = alger[3], linetype = "dotted", linewidth = 1) +
ggtitle("C") + clean
s_d <- ggtree(stree, color = alger[5], linewidth = 2) +
ggtitle("D") + clean
s_e <- ggtree(stree, layout = "circular", color = alger[2], linewidth = 1) +
ggtitle("E") + clean
s_f <- ggtree(stree, layout = "slanted", color = alger[6], linewidth = 1.5) +
ggtitle("F") + clean
fig3 <- s_a + s_b + s_c +
s_d + s_e + s_f +
plot_layout(ncol = 3) +
plot_annotation(
title = "Branch Styling in ggtree",
subtitle = paste0(
"Customizing tree appearance with color, linewidth, and linetype."
),
caption = paste(
"(A) Default rectangular,",
"(B) colored branches (alger[1]),",
"(C) dotted branches (alger[3]),\n",
"(D) thick branches (alger[5]),",
"(E) circular colored (alger[2]),",
"(F) slanted colored (alger[6])."
),
theme = theme(
plot.title = element_text(size = 16, face = "bold", hjust = 0.5,
margin = margin(b = 4)),
plot.subtitle = element_text(size = 9, hjust = 0.5, color = "grey30",
lineheight = 1.4, margin = margin(b = 10)),
plot.caption = element_text(size = 8, hjust = 0.5, color = "grey40",
lineheight = 1.5, margin = margin(t = 10)),
plot.margin = margin(15, 15, 15, 15)
)
)
fig3
suppressWarnings(
ggsave("ggtree_branch_styling.png", plot = fig3,
width = 14, height = 10, dpi = 300, bg = "white")
)
# ============================================================
# FIGURE 4: Tips & Labels (6 panels, 3x2)
# ============================================================
t_a <- ggtree(stree) +
geom_tippoint(color = alger[1], size = 3) +
ggtitle("A") + clean
t_b <- ggtree(stree) +
geom_point(aes(shape = isTip, color = isTip), size = 3) +
scale_color_manual(values = c("TRUE" = alger[2], "FALSE" = alger[5])) +
theme(legend.position = "none") +
ggtitle("B") + clean
t_c <- ggtree(stree) +
geom_nodepoint(color = alger[4], alpha = 0.4, size = 8) +
geom_tippoint(color = alger[1], shape = 8, size = 3) +
ggtitle("C") + clean
t_d <- ggtree(stree) +
geom_tiplab(size = 3, color = alger[3]) +
ggtitle("D") + clean
t_e <- ggtree(stree, layout = "circular") +
geom_tiplab(aes(angle = angle), size = 3, color = alger[6]) +
ggtitle("E") + clean
t_f <- ggtree(stree) +
geom_tiplab(as_ylab = TRUE, color = alger[2]) +
ggtitle("F") + clean
fig4 <- t_a + t_b + t_c +
t_d + t_e + t_f +
plot_layout(ncol = 3) +
plot_annotation(
title = "Tips & Labels in ggtree",
subtitle = paste0(
"Adding tip points, node points, and tip labels to trees."
),
caption = paste(
"(A) Tip points via geom_tippoint(),",
"(B) tip vs node shape/color via geom_point(aes(isTip)),",
"(C) node + tip points combined,\n",
"(D) tip labels via geom_tiplab(),",
"(E) circular tip labels with angle adjustment,",
"(F) tip labels as y-axis via as_ylab = TRUE."
),
theme = theme(
plot.title = element_text(size = 16, face = "bold", hjust = 0.5,
margin = margin(b = 4)),
plot.subtitle = element_text(size = 9, hjust = 0.5, color = "grey30",
lineheight = 1.4, margin = margin(b = 10)),
plot.caption = element_text(size = 8, hjust = 0.5, color = "grey40",
lineheight = 1.5, margin = margin(t = 10)),
plot.margin = margin(15, 15, 15, 15)
)
)
fig4
suppressWarnings(
ggsave("ggtree_tips_labels.png", plot = fig4,
width = 14, height = 10, dpi = 300, bg = "white")
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment