You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中堆叠带演化区系着色的系统发育树(类ggdensitree)

解决方案:实现带演化区系颜色的堆叠系统发育树

可以通过提取simmap树的区系分支信息,结合ggtree或ggplot2实现堆叠树的区系着色效果,以下是两种可行方案:

方案1:基于ggplot2的灵活自定义绘制

核心思路是提取每棵树的分支坐标、区系信息,统一整合后用ggplot2绘制层叠树,完全自定义布局:

library(tidyverse)
library(ggtree)
library(phytools)
library(ape)

# 1. 批量提取所有树的分支数据(含区系、坐标)
tree_data_list <- lapply(seq_along(trees_with_regimes), function(i) {
  tree <- trees_with_regimes[[i]]
  
  # 拆分分支的区系-长度映射
  map_df <- tree$maps %>% 
    enframe(name = "edge", value = "regime_length") %>% 
    unnest(regime_length) %>% 
    mutate(regime = names(regime_length), length = as.numeric(regime_length)) %>% 
    select(-regime_length)
  
  # 提取分支的节点连接关系
  edge_df <- as.data.frame(tree$edge) %>% 
    rename(from = V1, to = V2) %>% 
    mutate(edge = row_number())
  
  # 合并分支关系与区系信息
  full_df <- left_join(edge_df, map_df, by = "edge") %>% 
    group_by(edge) %>% 
    mutate(cum_len = cumsum(length),
           seg_start = tree$edge.length[edge] - cum_len + length,
           seg_end = tree$edge.length[edge] - cum_len + length + length) %>% 
    ungroup() %>% 
    mutate(tree_id = i)
  
  # 获取ggtree的节点坐标布局
  layout <- ggtree(tree) %>% ggplot_build() %>% pluck("data", 1) %>% select(node, x, y)
  
  # 合并坐标到分支数据,计算区系片段的x轴起止点
  full_df <- full_df %>% 
    left_join(layout, by = c("from" = "node")) %>% rename(x_from = x, y_from = y) %>% 
    left_join(layout, by = c("to" = "node")) %>% rename(x_to = x, y_to = y) %>% 
    mutate(x_start = x_from + seg_start, x_end = x_from + seg_end)
  
  return(full_df)
})

all_tree_data <- bind_rows(tree_data_list)

# 2. 绘制堆叠树
tree_spacing <- 1.2 # 树之间的垂直间距

ggplot() +
  # 绘制带区系颜色的分支片段
  geom_segment(data = all_tree_data,
               aes(x = x_start, xend = x_end,
                   y = y_from + tree_id * tree_spacing,
                   yend = y_to + tree_id * tree_spacing,
                   color = regime),
               linewidth = 1) +
  # 绘制节点(可选)
  geom_point(data = all_tree_data %>% 
               distinct(tree_id, node = from, x = x_from, y = y_from) %>% 
               bind_rows(all_tree_data %>% distinct(tree_id, node = to, x = x_to, y = y_to)),
             aes(x = x, y = y + tree_id * tree_spacing),
             size = 1, color = "black") +
  # 自定义区系颜色
  scale_color_manual(values = c("A" = "#2196F3", "B" = "#F44336")) +
  theme_tree() +
  labs(color = "演化区系") +
  ylab("树样本")

方案2:基于ggtree的简洁分面绘制

利用phytools::splitEdge()拆分多区系分支为单一区系短分支,再用ggtree的分面功能实现堆叠:

# 1. 预处理每棵树:拆分多区系分支为单区系分支
trees_processed <- lapply(trees_with_regimes, function(tree) {
  tree_split <- splitEdge(tree) # 拆分分支
  tree_split$edge_regime <- sapply(tree_split$maps, names) # 给分支添加区系属性
  return(tree_split)
})

# 2. 用ggtree绘制分面堆叠树
ggtree(trees_processed, aes(color = edge_regime)) +
  facet_wrap(~.id, ncol = 1, strip.position = "right") +
  scale_color_manual(values = c("A" = "#2196F3", "B" = "#F44336")) +
  theme_tree2() +
  labs(color = "演化区系") +
  theme(strip.text.y = element_text(angle = 0))

关键说明

  • splitEdge()是phytools的内置函数,能将带有多个演化区系的分支拆分为多个单一区系的短分支,让ggtree可以正确识别每个分支的颜色属性。
  • 两种方案都能实现和plotSimmap一致的区系着色效果,方案1适合高度自定义布局,方案2更符合ggtree的使用习惯。
  • 颜色可通过scale_color_manual自由替换,匹配你的需求。

内容的提问来源于stack exchange,提问作者Carlo Meloni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:33:17