eaton-lab / toytree

A minimalist tree plotting library using toyplot graphs
http://eaton-lab.org/toytree
BSD 3-Clause "New" or "Revised" License
169 stars 28 forks source link

Setting node "dist" #55

Closed StuntsPT closed 2 years ago

StuntsPT commented 2 years ago

Dear @dereneaton , I'm using toytree to plot phylogenetic trees in an automated pipeline (and what a wonderful tool this is!). I'm however, having some trouble manipulating branch lengths (which is useful when the outgroup is relatively distant from the ingroup). I can get each node's distance value by accessing it with tre.get_node_values("dist"), but whenever I try to input modified values (or any values at all, for that matter), using tre.set_node_values("dist", my_modified_distances) I always get the following error:

Traceback (most recent call last):
  File "/home/francisco/my_toytree_minimal_test.py", line 6, in <module>
    tre = tre.set_node_values("dist", tre.get_node_values("dist"))
  File "/home/francisco/.local/lib/python3.10/site-packages/toytree/Toytree.py", line 583, in set_node_values
    if values:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Below I have attached a very minimal code to reproduce the issue:

import toytree

tre = toytree.tree("https://eaton-lab.org/data/Cyathophora.tre")
tre = tre.set_node_values("dist", tre.get_node_values("dist"))  # I know this does not change anything, but it triggers the error. =-)

Am I doing something obviously wrong here? Or if not, is there any way to work around this issue? I already tried to recast the "values" variable as a list and as a dict (with numbered keys), but I just ended up triggering different errors. Thank you very much in advance for any help you may provide!

StuntsPT commented 2 years ago

Ok, so after some code-diving, I found this

In order to use set_node_values(), the second argument should be either a single, default value or a dictionary of {index: value} pairs!

This minimal example, thus, works!

import toytree

tre = toytree.tree("https://eaton-lab.org/data/Cyathophora.tre")
dists = [x for x in tre.get_node_values("dist", False, False) if x != ""]
idxes = [x for x in tre.get_node_values("idx", False, False) if x != ""]

d = {int(k): v for k, v in zip(idxes, dists)}

tre = tre.set_node_values("dist", d)

I'll be closing the issue now. Thank you!