0

亲爱的堆栈溢出社区,

我想请你帮忙解决我的问题。我正在使用包 ggtree 来绘制系统发育树,我想在这些图上显示更多信息,因为这在论文中很常见。我对拥有一棵带有彩色分支(具有混合渐变)的树特别感兴趣,该树显示出连续性状的一些变化,而分支末端的某个点则用颜色(或形状)表示离散性状。虽然我可以分别做这两件事,但我完全没有尝试在一个情节中绘制这两件事。你能帮忙吗?

在这里,我为您提供了可重现的示例。让这棵随机树(tree.1)有九个物种和一些随机分支长度,以及关于这些物种的随机数据表(data1):

###STACK EXAMPLE

source("https://bioconductor.org/biocLite.R")
biocLite("ggtree")
library(ggtree)

tree.1<-read.tree(text="(spec1:2.2,((spec2:1.8,(spec9:1.4,(spec3:1.3,spec5:1.3):0.1):0.4):0.2,(spec8:1.7,(spec6:1.5,(spec7:1,spec4:1):0.5):0.2):0.3):0.2);")

data1<-data.frame(row.names = c("spec1","spec2","spec3","spec4","spec5","spec6","spec7","spec8","spec9"),
                  "tip" = c("spec1","spec2","spec3","spec4","spec5","spec6","spec7","spec8","spec9"),
                  "colour" = c("red", "red", "blue", "red", "red", "blue", "blue", "red", "blue"),
                  "fylo.signal" = c(0.1, 1.0, 0.3, 0.6, 0.2, 0.8, 0.7, 0.3, 0.6))

如果您查看数据,颜色列是我的离散变量,而 fylo.signal 是随机连续变量。

为了制作这些图表,我遵循了两个示例(这个用于分支的渐变颜色,而我的旧问题用于分支末端点的颜色)。

我可以从颜色渐变分支开始。在绘制数据之前,我有一点黑匣子,但我想我至少了解了它的作用。首先,我只提取连续变量 (b) 并为我的树 (a) 计算“节点”,然后为我的树中的所有“非尖端”节点计算我的连续变量,即不仅仅是结束。然后我将数据合并在一起。

b <- as.matrix(data1)[,3]
a <- data.frame(node = nodeid(tree.1, names(b)),
                signal = b)
fit2 <- phytools::fastAnc(tree.1,b,vars=TRUE,CI=TRUE)
c <- data.frame(node = names(fit2$ace), signal = fit2$ace)
d.1 <- rbind(a, c)
d.1$node <- as.numeric(d.1$node)
d.1$signal <- as.numeric(d.1$signal)

之后,我还插入了离散变量(并且我使内部节点对于这个“颜色”具有“NA”):

colour.vector <- c(data1$colour, rep(NA, nrow(d.1)-nrow(data1)))
d.2 <- cbind(d.1, colour.vector)
d.2

...然后我将这些数据插入系统发育树本身:

tree.2 <- dplyr::full_join(tree.1, d.2, by = 'node')

现在进行绘图。我可以使分支的渐变颜色代表我的连续变量。以下代码生成此图

## example1 (SEPARATE TREES)

t1 <- ggtree(tree.2, aes(color=signal), layout = 'circular', 
             ladderize = FALSE, continuous = TRUE, size=2) +
  ggplot2::scale_color_gradientn(colours=c('red', 'orange', 'green', 'cyan', 'blue')) +
  geom_tiplab(hjust = -.1, offset=.1) + 
  theme(legend.position = c(.05, .85))
t1

...当我尝试将我的离散变量绘制为分支末端不同颜色的点时,这张图像(请注意,即使颜色是反转的,它实际上也遵循我使用的数据集):

t2 <- ggtree(tree.2, layout = 'circular') + geom_tiplab(hjust = -.1, offset=.1) 
t2 <- t2 %<+% data1 + geom_tippoint(pch=16, size=4, aes(col=colour))
t2

但是当我尝试将这两者结合起来时,会产生错误:

## example 1.5 (ERROR)

t3 <- t1 %<+% data1 + geom_tippoint(pch=16, size=4, aes(col=colour))
t3 ## Error: Discrete value supplied to continuous scale

我猜当制作树时使用函数“aes”时,它不能被情节的子部分覆盖?我不明白。我最好的镜头是以下代码:

## example 2 (WRONG ORDER OF COLOURS)
t4 <- ggtree(tree.2, aes(color=signal), layout = 'circular', 
             ladderize = FALSE, continuous = TRUE, size=2) +
  ggplot2::scale_color_gradientn(colours=c('red', 'orange', 'green', 'cyan', 'blue')) +
  geom_tiplab(hjust = -.1, offset=.1) + 
  theme(legend.position = c(.05, .85)) +
  geom_tippoint(pch=16, size=4, color=as.factor(colour.vector[1:9]))
t4

...这实际上使这张错误的照片。分支末端的点是彩色的,但与原始数据集中的不同。它们遵循数据集中的顺序,但未分配给正确的“物种”。根据来自“spec1”的数据集逆时针方向对物种进行着色。我不能让 ggtree 实际上遵循“物种”,就像我在上面的第二个情节中使用相同的代码一样。

任何人都可以帮忙,好吗?

4

2 回答 2

0

(我之前给出的答案,现已删除,确实不是您要求的。)

首先,快速修复d.1没有 NA 的生产:

d.1 <- rbind(
    mutate(a, signal = as.numeric(signal)),
    c
)

...并且可以像这样确保提示标签的正确顺序。

cols <- sapply( # colour.vector, but with names of colours
    colour.vector,
    function(val)
        if (is.na(val))    NA
        else if (val == 1) 'blue'
        else               'red'
)
tiplabel_order <- as.numeric(gsub('spec', '', tree.2@phylo$tip.label))

t4 <- ggtree(tree.2, aes(color = signal), layout = 'circular', 
             ladderize = FALSE, continuous = TRUE, size = 2) +
  ggplot2::scale_color_gradientn(colours=c('red', 'orange', 'green', 'cyan', 'blue')) +
  geom_tiplab(hjust = -.1, offset=.1) + 
  theme(legend.position = c(.05, .85)) +
  geom_tippoint(pch=16, size=4, color=as.factor(cols[tiplabel_order]))
t4
于 2020-08-19T21:11:51.270 回答
0

所以我想我找到了解决办法。我只是丢弃包ggtree并改用phytools。更少的代码,更多的优雅。如果有人感兴趣,就在这里(我只是将原始数据集的“颜色”换成了“breeding.range”和适当的值,顺序是一样的):

library(phytools)

tree.1<-read.tree(text="(spec1:2.2,((spec2:1.8,(spec9:1.4,(spec3:1.3,spec5:1.3):0.1):0.4):0.2,(spec8:1.7,(spec6:1.5,(spec7:1,spec4:1):0.5):0.2):0.3):0.2);")

data1<-data.frame(row.names = c("spec1","spec2","spec3","spec4","spec5","spec6","spec7","spec8","spec9"),
                  "breeding.range" = c("tropical", "tropical", "temperate", "tropical", "tropical", "temperate", "temperate", "tropical", "temperate"),
                  "fylo.signal" = c(0.1, 1.0, 0.3, 0.6, 0.2, 0.8, 0.7, 0.3, 0.6))

var.cont<-setNames(data1[,2],rownames(data1))
var.disc<-setNames(data1[,1],rownames(data1))
var.disc<-as.factor(var.disc)
matrix.disc<-to.matrix(var.disc,levels(var.disc))
matrix.disc<-matrix.disc[tree.1$tip.label,]

obj<-contMap(tree.1,var.cont,plot=FALSE)

plotTree(tree.1,type="fan",ftype="i",offset=2,fsize=0.9)

plot(obj$tree,colors=obj$cols,type="fan",add=TRUE,ftype="off",lwd=3,
     xlim=get("last_plot.phylo",envir=.PlotPhyloEnv)$x.lim,
     ylim=get("last_plot.phylo",envir=.PlotPhyloEnv)$y.lim)

tiplabels(pie=matrix.disc,piecol=palette()[c(4,2)],cex=0.4)
于 2020-08-19T16:20:32.533 回答