def _draw_host_handle(fig: plot_tools.FigureWrapper, root: tree.Node): """ Draw edge leading to root of host tree. :param fig: Figure object that visualizes trees using MatplotLib :param root: The root node of a tree object """ fig.line((0, root.layout.y), (root.layout.x, root.layout.y), render_settings.HOST_EDGE_COLOR)
def _render_curved_line_to(node_pos: plot_tools.Position, other_pos: plot_tools.Position, fig: plot_tools.FigureWrapper): """ Renders a curved line from one point to another :param node_pos: x and y position of a node :param other_pos: x and y position of another node :param fig: Figure object that visualizes trees using MatplotLib """ mid_pos = plot_tools.Position(node_pos.x, other_pos.y) fig.line(node_pos, mid_pos, render_settings.PARASITE_EDGE_COLOR) fig.line(mid_pos, other_pos, render_settings.PARASITE_EDGE_COLOR)
def _connect_child_to_parent(node: tree.Node, child_node: tree.Node, host_lookup: dict, recon_obj: recon.Reconciliation, fig: plot_tools.FigureWrapper, stop_row: float = None): """ Connects a child node to its parent node :param node: Node object representing a parasite event :param child_node: The child node object of a given node :param host_lookup: Dictionary with host node names as the key and host node objects as the values :param recon_obj: Reconciliation object that represents an edge-to-edge mapping from a parasite tree to a host tree :param fig: Figure object that visualizes trees using MatplotLib :param stop_row: row number to stop line drawing on """ mapping_node = recon_obj.mapping_of(child_node.name) host_node = host_lookup[mapping_node.host] if stop_row == None: stop_row = node.layout.row current_pos = plot_tools.Position(child_node.layout.x, child_node.layout.y) while host_node.layout.row != stop_row and host_node.parent_node: parent_node = host_node.parent_node if parent_node.layout.row < host_node.layout.row: v_track = parent_node.get_and_update_track( tree.Track.UPPER_VERTICAL) else: v_track = parent_node.get_and_update_track( tree.Track.LOWER_VERTICAL) while v_track < parent_node.layout.upper_v_track: v_track = parent_node.get_and_update_track( tree.Track.LOWER_VERTICAL) h_track = parent_node.get_and_update_track(tree.Track.HORIZONTAL) offset = parent_node.layout.offset sub_parent_pos = plot_tools.Position(parent_node.layout.x - (offset * v_track), \ parent_node.layout.y + (offset * h_track)) _render_loss_branch(sub_parent_pos, current_pos, fig) host_node = parent_node current_pos = sub_parent_pos node_pos = plot_tools.Position(node.layout.x, node.layout.y) mid_pos = plot_tools.Position(node_pos.x, current_pos.y) fig.line(node_pos, mid_pos, render_settings.PARASITE_EDGE_COLOR) fig.line(mid_pos, current_pos, render_settings.PARASITE_EDGE_COLOR)
def _render_loss_branch(node_pos: plot_tools.Position, next_pos: plot_tools.Position, fig: plot_tools.FigureWrapper): """ Renders a loss branch given a two positions :param node_pos: x and y position of a node :param next_pos: x and y position of another node :param fig: Figure object that visualizes trees using MatplotLib """ # Create vertical line to next node mid_pos = plot_tools.Position(node_pos.x, next_pos.y) fig.line(node_pos, mid_pos, render_settings.LOSS_EDGE_COLOR, linestyle='--') fig.line(mid_pos, next_pos, render_settings.PARASITE_EDGE_COLOR)
def _render_host_helper(fig: plot_tools.FigureWrapper, node: tree.Node, show_internal_labels: bool, font_size: float, host_tree: tree.Tree): """ Helper function for rendering the host tree. :param fig: Figure object that visualizes trees using MatplotLib :param node: Host Node object that will be rendered :param show_internal_labels: Boolean that determines whether or not the internal labels are shown :param font_size: Font size for the text of the tips and internal nodes of the tree :param host_tree: Tree object representing a Host Tree """ host_tree.pos_dict[(node.layout.row, node.layout.col)] = node node_pos = plot_tools.Position(node.layout.x, node.layout.y) if node.is_leaf(): text_offset = (node_pos.x + render_settings.TIP_TEXT_OFFSET_X, node_pos.y) if node.layout.node_count == 0: fig.text_v2(text_offset, node.name, render_settings.HOST_NODE_COLOR, size=font_size, vertical_alignment=render_settings.TIP_ALIGNMENT) else: fig.text_v2(text_offset, node.name, render_settings.HOST_NODE_COLOR, size=font_size, vertical_alignment=render_settings.TIP_ALIGNMENT) else: fig.dot(node_pos, col=render_settings.HOST_NODE_COLOR) # Render host node if show_internal_labels: color = plot_tools.transparent_color( render_settings.HOST_NODE_COLOR, render_settings.INTERNAL_NODE_ALPHA) text_xy = (node_pos.x, node_pos.y) fig.text_v2(text_xy, node.name, color, size=font_size, border_col=render_settings.HOST_NODE_BORDER_COLOR) left_x, left_y = node.left_node.layout.x, node.left_node.layout.y right_x, right_y = node.right_node.layout.x, node.right_node.layout.y fig.line(node_pos, (node_pos.x, left_y), render_settings.HOST_EDGE_COLOR) fig.line(node_pos, (node_pos.x, right_y), render_settings.HOST_EDGE_COLOR) fig.line((node_pos.x, left_y), (left_x, left_y), render_settings.HOST_EDGE_COLOR) fig.line((node_pos.x, right_y), (right_x, right_y), render_settings.HOST_EDGE_COLOR) _render_host_helper(fig, node.left_node, show_internal_labels, font_size, host_tree) _render_host_helper(fig, node.right_node, show_internal_labels, font_size, host_tree)
def _render_transfer_branch(node_pos: plot_tools.Position, right_pos: plot_tools.Position, fig: plot_tools.FigureWrapper, node: tree.Node, host_lookup: dict, recon_obj: recon.Reconciliation, right_node: tree.Node): """ Renders a transfer branch :param node_xy: x and y position of a node :param right_pos: x and y position of the right child of a node :param fig: Figure object that visualizes trees using MatplotLib :param node: Node object representing the parasite event being rendered :param host_lookup: Dictionary with host node names as the key and host node objects as the values :param recon_obj: Reconciliation object that represents an edge-to-edge mapping from a parasite tree to a host tree :param right_node: The right node object of node """ child_mapping_node = recon_obj.mapping_of(right_node.name) child_host_node = host_lookup[child_mapping_node.host] # Check temporal consistency of transfer event if child_host_node.parent_node.layout.col < node.layout.col: # Draw right node, which is transfered mid_pos = plot_tools.Position(node_pos.x, right_pos.y) # xy coords of midpoint y_midpoint = abs( mid_pos.y + node_pos.y) / 2 # value of midpoint between mid_xy and parent node # Determine if transfer is upwards or downwards, and draw triangle accordingly is_upwards = True if y_midpoint < mid_pos.y else False arrow_pos = plot_tools.Position(node_pos.x, y_midpoint) if is_upwards: fig.triangle(arrow_pos, render_settings.PARASITE_EDGE_COLOR) else: fig.triangle(arrow_pos, render_settings.PARASITE_EDGE_COLOR, rotation=render_settings.DOWN_ARROW_ROTATION) # Draw branch to midpoint, then draw branch to child fig.line(node_pos, mid_pos, render_settings.PARASITE_EDGE_COLOR) fig.line(mid_pos, right_pos, render_settings.PARASITE_EDGE_COLOR) else: transfer_edge_color = plot_tools.transparent_color( render_settings.PARASITE_EDGE_COLOR, render_settings.TRANSFER_TRANSPARENCY) fig.arrow_segment(node_pos, right_pos, transfer_edge_color) fig.line(node_pos, right_pos, transfer_edge_color)