3

I read the whole documentation on profile face heatmap generation but I could not find any way to add labels to the heatmap produced by ete3. For example in the following code, the 7 columns of the heatmap have names 'Marker1' to 'Marker7'. Is there any way these names to be added to the heatmap produced by ete3, something like the 'labels' option available for 'BarChartFace'? or the only way is to port the tree to matplotlib and add the labels over there?

from ete3 import Tree, TextFace, NodeStyle, TreeStyle, faces, AttrFace, ClusterTree, ProfileFace
PhenoDict={'a':1,'b':0,'c':1}
matrix = """
#Names\tmarker1\tmarker2\tmarker3\tmarker4\tmarker5\tmarker6\tmarker7
a\t1\t-1\t1\t-1\t-1\t-1\t1
b\t-1\t-1\t1\t1\t-1\t-1\t1
c\t1\t1\t1\t-1\t1\t1\t1
"""

t=ClusterTree( "((a,b),c);" , text_array=matrix)

#Defining a function to generate textFace for each node

def ColorCodedNode (node):
    if node.is_leaf():
        ColorCode=PhenoDict[node.name]

        if ColorCode == 0:
            faces.add_face_to_node(AttrFace('name',fsize=20,fgcolor='blue'), node, column=0,aligned=True)
column=1,position='aligned')
            faces.add_face_to_node(ProfileFace(1, -1, 0, width=200, height=40, style='heatmap', colorscheme=2),node,column=1,position='aligned')
        elif ColorCode == 1:
            faces.add_face_to_node(AttrFace("name",fsize=20,fgcolor='red'), node, column=0,aligned=True)
            faces.add_face_to_node(ProfileFace(1, -1, 0, width=200, height=40, style='heatmap', colorscheme=2),node,column=1,position='aligned')


ts = TreeStyle()
ts.layout_fn= ColorCodedNode
ts.show_scale = False
ts.show_leaf_name = False
ts.draw_guiding_lines=True
t.show(tree_style=ts)

Now it produces a tree like this, but I need to add labels to each column of heatmap. enter image description here

Masih
  • 920
  • 2
  • 19
  • 36
  • Using this code:https://gist.github.com/fransua/da703c3d2ba121903c0de5e976838b71 you might be able to draw your ete3 tree using matplotlib directly. – fransua Nov 24 '18 at 17:25

1 Answers1

1

Partial answer:

I could not find a way to do it, however you may be interested in the aligned_header and aligned_foot attributes of TreeStyle:

Say you managed to create an axis as a face, named axisface. I consider my answer partial because my solution to create this face is an imperfect workaround based on BarChartFace:

from ete3 import BarChartFace

labels = matrix.split('\n')[1].split('\t')[1:]
axisface = BarChartFace([0]*len(labels), width=200, height=0, labels=labels, max_value=1, scale_fsize=1) # Can't get rid of the Y axis tick labels though

You can then add it to the foot/header:

ts.aligned_foot.add_face(axisface, 1)


Alternatively to a single face, you could create one RectFace for each label:

from ete3 import RectFace

for i, lab in enumerate(labels):
    labface = RectFace(50, 200/len(labels), '#fff', '#eee', label={'text':lab, 'fontsize':8, 'color': 'black'})
    labface.rotation = -90
    ts.aligned_foot.add_face(labface, 1+i)

But the rectangles don't align properly with each of the heatmap column.

PlasmaBinturong
  • 2,122
  • 20
  • 24