From fc6b3ac522e569bae8f5027241812eb27002a797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matin=20G=C3=BChmann?= Date: Wed, 2 Jun 2021 21:51:11 +0100 Subject: [PATCH 1/2] Add a float-right position to face object for rectagle tree layouts This option will place the face right to all other faces Since it is floating it does not mess up the layout if it were added as aligned to the last column --- ete3/coretype/tree.py | 2 +- ete3/tools/common.py | 1 + ete3/treeview/main.py | 5 +++-- ete3/treeview/qt4_render.py | 26 ++++++++++++++++---------- sdoc/tutorial/tutorial_drawing.rst | 3 ++- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/ete3/coretype/tree.py b/ete3/coretype/tree.py index d0d3e93cd..a7114e561 100644 --- a/ete3/coretype/tree.py +++ b/ete3/coretype/tree.py @@ -2471,7 +2471,7 @@ def add_face(self, face, column, position="branch-right"): :argument column: An integer number starting from 0 :argument "branch-right" position: Posible values are: "branch-right", "branch-top", "branch-bottom", "float", - "aligned" + "aligned", "float-behind", "float-right" """ if not hasattr(self, "_faces"): diff --git a/ete3/tools/common.py b/ete3/tools/common.py index eb75766b9..e736519f1 100644 --- a/ete3/tools/common.py +++ b/ete3/tools/common.py @@ -124,6 +124,7 @@ def _re(q, exp): "b-bottom":"branch-bottom", "float":"float", "float-behind":"float-behind", + "float-right":"float-right", "aligned":"aligned", } diff --git a/ete3/treeview/main.py b/ete3/treeview/main.py index 1c930fa97..b811c1140 100644 --- a/ete3/treeview/main.py +++ b/ete3/treeview/main.py @@ -66,7 +66,7 @@ def a_wrapper_accepting_arguments(*args, **kargs): _NODE_TYPE_CHECKER = lambda x: x in ["sphere", "circle", "square"] _BOOL_CHECKER = lambda x: isinstance(x, bool) or x in (0,1) -FACE_POSITIONS = set(["branch-right", "branch-top", "branch-bottom", "float", "float-behind", "aligned"]) +FACE_POSITIONS = set(["branch-right", "branch-top", "branch-bottom", "float", "float-behind", "float-right", "aligned"]) __all__ = ["NodeStyle", "TreeStyle", "FaceContainer", "_leaf", "add_face_to_node", "COLOR_SCHEMES"] @@ -601,7 +601,8 @@ def add_face_to_node(face, node, column, aligned=False, position="branch-right") :argument node: a tree node instance (:class:`Tree`, :class:`PhyloTree`, etc.) :argument column: An integer number starting from 0 :argument "branch-right" position: Possible values are - "branch-right", "branch-top", "branch-bottom", "float", "float-behind" and "aligned". + "branch-right", "branch-top", "branch-bottom", "float", "float-behind", + "float-right" and "aligned". """ ## ADD HERE SOME TYPE CHECK FOR node and face diff --git a/ete3/treeview/qt4_render.py b/ete3/treeview/qt4_render.py index 10f30aed5..a41cad086 100644 --- a/ete3/treeview/qt4_render.py +++ b/ete3/treeview/qt4_render.py @@ -315,9 +315,10 @@ def render(root_node, img, hide_root=False): # Add extra layers: aligned faces, floating faces, node # backgrounds, etc. The order by which the following methods are # called IS IMPORTANT - render_floatings(n2i, n2f, img, parent.float_layer, parent.float_behind_layer) - aligned_region_width = render_aligned_faces(img, mainRect, parent.tree_layer, n2i, n2f) + aligned_region_width, tree_end_x = render_aligned_faces(img, mainRect, parent.tree_layer, n2i, n2f) + + render_floatings(n2i, n2f, img, parent.float_layer, parent.float_behind_layer, aligned_region_width, tree_end_x) render_backgrounds(img, mainRect, parent.bg_layer, n2i, n2f) @@ -776,14 +777,15 @@ def set_style(n, layout_func): for func in layout_func: func(n) -def render_floatings(n2i, n2f, img, float_layer, float_behind_layer): +def render_floatings(n2i, n2f, img, float_layer, float_behind_layer, extra_width, tree_end_x): #floating_faces = [ [node, fb["float"]] for node, fb in n2f.iteritems() if "float" in fb] for node, faces in six.iteritems(n2f): - face_set = [ [float_layer, faces.get("float", None)], - [float_behind_layer, faces.get("float-behind",None)]] + face_set = [ [float_layer, faces.get("float", None), False], + [float_behind_layer, faces.get("float-behind",None), False], + [float_layer, faces.get("float-right",None), True]] - for parent_layer,fb in face_set: + for parent_layer,fb, isRight in face_set: if not fb: continue @@ -802,8 +804,12 @@ def render_floatings(n2i, n2f, img, float_layer, float_behind_layer): #crender.rotate_and_displace(fb, item.rotation, fb.h, item.radius - item.nodeRegion.width()) elif img.mode == "r": - start = item.branch_length + xtra - fb.w #if fb.w < item.branch_length else 0.0 - fb.setPos(item.content.mapToScene(start, item.center - (fb.h/2.0))) + if isRight: + start = extra_width + tree_end_x # This puts it to the right of the column + fb.setPos(start, item.content.mapToScene(start, item.center - (fb.h/2.0)).y()) + else: + start = item.branch_length + xtra - fb.w #if fb.w < item.branch_length else 0.0 + fb.setPos(item.content.mapToScene(start, item.center - (fb.h/2.0))) z = item.zValue() if not img.children_faces_on_top: @@ -821,7 +827,7 @@ def render_aligned_faces(img, mainRect, parent, n2i, n2f): # If no aligned faces, just return an offset of 0 pixels if not aligned_faces: - return 0 + return 0, 0 # Load header and footer if img.mode == "r": @@ -911,7 +917,7 @@ def render_aligned_faces(img, mainRect, parent, n2i, n2f): mainRect.adjust(-extra_width, -extra_width, extra_width, extra_width) else: mainRect.adjust(0, 0, extra_width, 0) - return extra_width + return extra_width, tree_end_x def get_tree_img_map(n2i, x_scale=1, y_scale=1): MOTIF_ITEMS = set([faces.QGraphicsTriangleItem, diff --git a/sdoc/tutorial/tutorial_drawing.rst b/sdoc/tutorial/tutorial_drawing.rst index 4b76b7b84..da7f5b805 100644 --- a/sdoc/tutorial/tutorial_drawing.rst +++ b/sdoc/tutorial/tutorial_drawing.rst @@ -330,7 +330,8 @@ Faces position ^^^^^^^^^^^^^^^^ Faces can be added to different areas around the node, namely -**branch-right**, **branch-top**, **branch-bottom** or **aligned**. +**branch-right**, **branch-top**, **branch-bottom**, **float**, +**float-behind**, **float-right**, or **aligned**. Each area represents a table in which faces can be added through the :func:`TreeNode.add_face` method. For instance, if two text labels want to be drawn bellow the branch line of a given node, a pair of From 7b6ef8dc2ee06e1919616b7b961281e2cb75fe21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matin=20G=C3=BChmann?= Date: Wed, 2 Jun 2021 22:17:57 +0100 Subject: [PATCH 2/2] Make float-right position for faces also for circular trees --- ete3/treeview/qt4_render.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ete3/treeview/qt4_render.py b/ete3/treeview/qt4_render.py index a41cad086..ff1d54472 100644 --- a/ete3/treeview/qt4_render.py +++ b/ete3/treeview/qt4_render.py @@ -798,16 +798,22 @@ def render_floatings(n2i, n2f, img, float_layer, float_behind_layer, extra_width xtra = 0 if img.mode == "c": - # Floatings are positioned over branches - crender.rotate_and_displace(fb, item.rotation, fb.h, item.radius - item.nodeRegion.width() + xtra) - # Floatings are positioned starting from the node circle - #crender.rotate_and_displace(fb, item.rotation, fb.h, item.radius - item.nodeRegion.width()) + if isRight: + # Floatings are positioned right to all other aligned faces + crender.rotate_and_displace(fb, item.rotation, fb.h, extra_width + tree_end_x) + else: + # Floatings are positioned over branches + crender.rotate_and_displace(fb, item.rotation, fb.h, item.radius - item.nodeRegion.width() + xtra) + # Floatings are positioned starting from the node circle + #crender.rotate_and_displace(fb, item.rotation, fb.h, item.radius - item.nodeRegion.width()) elif img.mode == "r": if isRight: + # Floatings are positioned right to all other aligned faces start = extra_width + tree_end_x # This puts it to the right of the column fb.setPos(start, item.content.mapToScene(start, item.center - (fb.h/2.0)).y()) else: + # Floatings are positioned over branches start = item.branch_length + xtra - fb.w #if fb.w < item.branch_length else 0.0 fb.setPos(item.content.mapToScene(start, item.center - (fb.h/2.0)))