Yesterday, a phytools user & phytools blog reader
commented
the following about the phytools function for co-phylogenetic plotting,
`cophylo`

(e.g.,
1,
2):

*I've been looking for a way to compare two trees while minimizing
overlap, so I was glad to see this! I successfully used the cophylo
function with two non-ultrametric trees, but when plotting it continues
to plot only the horizontal branches of the left tree and then give me
this:*

Error in xy.coords(x, y) : 'x' and 'y' lengths differ

*The two trees are made from the same strains so they are identical in tip
labels and number of tips (84 tips, 82 nodes). I'm not really sure why it's
giving me the error, any idea what might be causing it?*

My one idea is that it is because one of the two trees has polytomies. I can tell this because the number of nodes (82) is fewer than one less than the number of tips (84). In fact, simulating trees with polytomies does in fact duplicate the error exactly.

So, for instance:

```
library(phytools)
t1<-rtree(n=40)
t2<-rtree(n=40)
ii<-which(t2$edge[,2]>Ntip(t2))
t2$edge.length[sample(ii,4)]<-0
t2<-di2multi(t2)
obj<-cophylo(t1,t2)
```

```
## Rotating nodes to optimize matching...
## Done.
```

```
plot(obj)
```

```
## Error in xy.coords(x, y): 'x' and 'y' lengths differ
```

The simplest work-around is to simply resolve the polytomous tree, in this
case `t2`

, randomly using branches of zero length:

```
obj<-cophylo(t1,multi2di(t2))
```

```
## Rotating nodes to optimize matching...
## Done.
```

```
plot(obj)
```

Though this works, of course, it does not allow, for example, descendant edges to be spaced properly from a polytomous node.

The solution, however, was super simple. All that is required was that I change:

## plot vertical relationships for(i in 1:tree$Nnode+n) lines(d*X[which(cw$edge[,1]==i),1], range(y[cw$edge[which(cw$edge[,1]==i),2]]),lwd=lwd,lend=2)

to:

## plot vertical relationships for(i in 1:tree$Nnode+n) lines(d*X[which(cw$edge[,1]==i),1], sort(y[cw$edge[which(cw$edge[,1]==i),2]]),lwd=lwd,lend=2)

This is because when there is more than one edge descending from
`cw$edge[,1]==i`

(our current node), then
`X[which(cw$edge[,1]==i),1]`

is a vector containing the *x*
containing a number of elements equal to the number of descendants, whereas
`range(y[cw$edge[which(cw$edge[,1]==i),2]])`

can *only*
contain two values: the range, which are the vertical start & end points
of the vertical lines we want to draw. By changing it to:
`sort(y[cw$edge[which(cw$edge[,1]==i),2]])`

I now just have the
*y*-coordinates, in a line, of all edges arising from that node.

The modified code is here and it will be in the next version of phytools.

```
load("http://www.phytools.org/cophylo/v0.6/cophylo.R")
```

```
## Warning in readChar(con, 5L, useBytes = TRUE): cannot open compressed file
## 'http://www.phytools.org/cophylo/v0.6/cophylo.R', probable reason 'Invalid
## argument'
```

```
## Error in readChar(con, 5L, useBytes = TRUE): cannot open the connection
```

```
obj<-cophylo(tr1,tr2)
```

```
## Error in inherits(tr1, "phylo"): object 'tr1' not found
```

```
plot(obj)
```

It works!

Worked perfectly this time, thanks for the help!

ReplyDeleteRachel

Hi Liam,

ReplyDeleteThis is excellent. One quick questions because my R skills are admittedly weak - is there a way to maintain support values in the co-plotted trees? I don't see any easy way to do this in the source for cophylo.R.

This might address this question: http://blog.phytools.org/2015/10/node-edge-tip-labels-for-plotted.html.

DeleteLet me know. Liam