phylojunction.data package
Submodules
phylojunction.data.attribute_transition module
- class phylojunction.data.attribute_transition.AttributeTransition(attr_label: str, subtending_node_label: str, global_time: float, from_state: int, to_state: int, age: float | None = None, to_state2: int | None = None, at_speciation: bool = False)
Bases:
object- age: float
- at_speciation: bool | None
- attr_label: str
- from_state: int
- global_time: float
- prep_str_representation() None
- str_representation: str
- subtending_or_speciating_node_label: str
- to_state: int
- to_state2: int
- update_daughter_members(daughter_node_label: str, daughter_node_time: float) None
phylojunction.data.sampled_ancestor module
- class phylojunction.data.sampled_ancestor.SampledAncestor(label: str, lineage_node_label: str, global_time: float, age: float | None = None, state: int = 0, time_to_lineage_node: float = -1.0)
Bases:
object- age: float
- global_time: float
- label: str
- lineage_node_label: str
- state: int
- str_representation: str
- time_to_lineage_node: float
phylojunction.data.tree module
- class phylojunction.data.tree.AnnotatedTree(a_tree: Tree, total_state_count: int, start_at_origin: bool = False, alternative_root_label: str = '', condition_on_obs_both_sides_root: bool = False, max_age: float | None = None, slice_t_ends: List[float] | None = None, slice_age_ends: List[float] | None = None, sa_lineage_dict: Dict[str, List[SampledAncestor]] | None = None, at_dict: Dict[str, List[AttributeTransition]] | None = None, clado_at_dict: Dict[str, AttributeTransition] | None = None, tree_died: bool | None = None, tree_invalid: bool | None = None, read_as_newick_string: bool = False, epsilon: float = 1e-12)
Bases:
TreeTree annotated with discrete states.
- Parameters:
tree (dendropy.Tree) – Main class member, holding the full tree.
tree_reconstructed (dendropy.Tree) – Reconstructed tree produced by pruning the full tree from non-observed phylogenetic paths.
origin_node (dendropy.Node) – Origin node. It is ‘None’ if no origin node.
root_node (dendropy.Node) – Root node. It is ‘None’ if no root node.
rec_tr_root_node (dendropy.Node, optional) – Root node of reconstructed tree. It is ‘None’ if ‘extract_reconstructed_tree’ method is not called.
brosc_node (dendropy.Node) – Node that occurs before the root node when tree starts from origin node. The brosc_node can be a terminal or internal node, and is replaced by the root node if a speciation event happens.
alternative_root_label (str) – An AnnotatedTree may be read in with a constant function rather than be simulated by discrete_sse(). In this case, the root node is named ‘root’ so that AnnotatedTree is initialized properly, but we want to keep track of an alternative label for the root node, which may appear in a stochastic map table, or in a table with tip states. Defaults to ‘’.
with_origin (bool) – Flag indicating that tree starts at origin node. Upon instantiation of class, defaults to ‘False’.
tree_read_as_newick (bool) – Flag indicating that tree was not simulated in PJ, but read as a Newick string instead. Upon instantiation of class, defaults to ‘False’.
condition_on_obs_both_sides_root (bool) – Flag indicating if root node, when simulation starts from it (!), has at least one living on either side. If not specified by user upon instantiation of class, defaults to ‘False’.
tree_died (bool) – Flag indicating if full tree went extinct before reaching the specified age stopping condition (i.e., the reconstructed tree should be empty).
tree_invalid (bool) – Flag indicating (if tree was simulated) that rejection sampling deemed the tree invalid. If not specified upon class instantiation, tree is assumed to have been read as a string, and flag is assigned ‘True’.
seed_age (float) – Age of seed node (either origin or root).
max_age (float) – Maximum age of the tree when it was simulated with an age stopping condition. If not provided by user upon class instantiation, it is ‘None’.
origin_age (float) – Age of origin node, if there is one, otherwise ‘None’.
origin_edge_length (float) – Length of the branch connecting the origin node to its single child (brosc or root) or to the present. If there is a root, this length does not care about intervening direct (sampled) ancestor between the origin and the root. Will be 0.0 if no origin node.
root_age (float) – Age of root node, if there is one, otherwise 0.0.
rec_tr_root_age (float) – Age of root node of reconstructed tree.
node_heights_dict (dict) – Dictionary that holds the heights of all nodes in the tree. Keys are node labels, values are floats.
rec_tr_node_heights_dict (dict) – Dictionary that holds the heights of all nodes in the reconstructed tree. Keys are node labels, values are floats.
node_ages_dict (dict) – Dictionary that holds the ages of all nodes in the tree. Keys are node labels, values are floats.
rec_tr_node_ages_dict (dict) – Dictionary that holds the ages of all nodes in the reconstructed tree. Keys are node labels, values are floats.
slice_t_ends (float) – List of floats with the end times for specified time slices (epochs). If not provided by user Upon instantiation of class, will be ‘None’.
slice_age_ends (dict) – List of floats with the end ages for specified time slices (epochs). If not provided by user Upon instantiation of class, will be ‘None’.
state_count (int) – How many states there are.
state_count_dict (dict) – Dictionary tabulating how many terminal nodes in the full tree are in each state. Keys are integers representing states and values are their counts.
extant_terminal_state_count_dict (dict) – Dictionary tabulating how many living (terminal) nodes are in each state. Keys are integers representing states and values are their counts.
extant_sampled_terminal_state_count_dict (dict) – Dictionary tabulating how many living (terminal) and sampled nodes are in each state. Keys are integers representing states and values are their counts.
extinct_sampled_state_count_dict (dict) – Dictionary tabulating how many extinct (terminal) nodes are in each state. Keys are integers representing states and values are their counts.
sa_node_state_count_dict (dict) – Dictionary tabulating how many direct (sampled) ancestor nodes are in each state. Keys are integers representing states and values are their counts.
node_attr_dict (dict) – Nested dictionaries. Keys of the outer dictionary are node labels, values are inner dictionaries. Inner dictionary’s key are attribute names (str) and values are the attribute’s values (Any).
n_extant_terminal_nodes (int) – Count of living terminal nodes.
n_extinct_terminal_nodes (int) – Count of dead terminal nodes.
n_extant_sampled_terminal_nodes (int) – Count of living and sampled terminal nodes.
n_sa_nodes (int) – Count of direct (sampled) ancestors. These are nodes that are both sampled and observed by definition.
sa_lineage_dict (dict)
at_dict (dict, optional) – Dictionary holding a list of AttributeTransition instances for each branch (subtending an internal node) along which state transitions happened. When a cladogenetic event change states, it is recorded as the first (oldest) state transition of its children.
rec_tr_at_dict (dict, optional) – Same as ‘at_dict’, but applies to reconstructed tree. Defaults to ‘None’.
have_updated_rec_tr_at_dict (bool) – Flag keeping track of the status of ‘rec_tr_at_dict’. If ‘extract_reconstructed_tree’ updated it, then this flag will be set to True. Defaults to ‘False’.
clado_at_dict (dict) – Dictionary holding an AttributeTransition instance for internal nodes that underwent speciation where at least one child’s state differs from the parent’s. Keys are strings, values are AttributeTransitions. Defaults to ‘None’.
rec_tr_clado_at_dict (dict) – Same as ‘clado_at_dict’, but applies to reconstructed tree.
have_updated_rec_tr_at_dict – Flag keeping track of the status of ‘rec_tr_clado_at_dict’. If ‘extract_reconstructed_tree’ updated it, then this flag will be set to True. Defaults to ‘False’.
epsilon (float) – Float threshold to determine if a tiny decimal number is to be considered 0.0 or not. In other words, if the difference between a tiny value ‘x’ and 0.0 is smaller than epsilon, then ‘x’ is set to 0.0. If not provided by user upon initialization of class, defaults to 1e-12.
- alternative_root_label: str
- at_dict: Dict[str, List[AttributeTransition]] | None
- brosc_node: Node | None
- clado_at_dict: Dict[str, AttributeTransition] | None
- condition_on_obs_both_sides_root: bool
- epsilon: float
- extant_sampled_terminal_nodes_labels: Tuple[str, ...]
- extant_terminal_nodes_labels: Tuple[str, ...]
- extant_terminal_sampled_state_count_dict: Dict[int, int]
- extant_terminal_state_count_dict: Dict[int, int]
- extinct_sampled_terminal_nodes_labels: Tuple[str, ...]
- extinct_terminal_nodes_labels: Tuple[str, ...]
- extinct_terminal_state_count_dict: Dict[int, int]
- extract_reconstructed_tree(plotting_overhead: bool = False, require_obs_both_sides: bool | None = None) Tree
Extract reconstructed tree from complete tree.
This method was designed to be called outside of AnnotatedTree’s initialization, and instead be prompted by rejection sampling (when conditioning on both sides of the root), and summarization and printing functions should the user ask for it. This is to save running time.
The method deep-copies self.tree, which is of type dendropy.Tree, populates it appropriately and then returns it. One important step is the update of the reconstructed tree’s ‘rec_tr_at_dict’ and ‘rec_sa_lineage_dict’ members, which will be different from the complete tree’s. These updates are carried out by ‘update_rec_tr_at_dict’ and ‘update_rec_tr_sa_lineage_dict’.
When populating the reconstructed tree, this method effectively prunes extinct taxa, and re-roots the resulting tree at the MRCA of the sampled (observed) taxa. This includes all taxa sampled at the present and direct ancestors.
- Side-effect on the complete tree’s AnnotatedTree object:
Populates self.rec_tr_root_node
Populates self.rec_tr_at_dict
Populates self.rec_tr_sa_lineage_dict
- Parameters:
require_obs_both_sides (bool, optional) – Flag specifying if sampled (observed) taxa are required on both sides of the root.
- Returns:
- A tree instance containing the
reconstructed tree extracted from AnnotatedTree’s instance owning the method call.
- Return type:
(dendropy.Tree)
- get_stats_dict() Dict[str, int | float]
Get dictionary with AnnotatedTree’s summary stats.
This method is required whenever the user asks for a DAG node to be summarized.
A tree whose ‘self.clock_model_attr_name’ is set was annotated by a clock model (e.g., ‘gamma_spike_clock’) – such a node exists to represent its reconstructed topology (its phylogram), not the complete tree, so its stats summarize ‘self.tree_reconstructed’ itself. ‘clock_model_attr_name’ is set generically by ‘calculation.clock_model.ClockModel.generate()’ for every clock model, regardless of which attribute name (e.g., “mutation_rate”, “morph_rate”) that particular model’s caller chose – see that attribute’s own docstring. This is the same detection ‘pgm.DeterministicNodeDAG.plot_node’ uses to decide whether to draw the (monochromatic) phylogram instead of the complete chronogram.
- Returns:
Dictionary with summary statistic names as keys and their values as values.
- Return type:
(dict)
- get_taxon_states_str(nexus: bool = False, bit_format: bool = False) str
Get states for all nodes in tree as single string.
- Parameters:
nexus (bool) – Flag specifying whether states are being collected for Nexus printing (‘True’ if so). Defaults to ‘False’.
bit_format (bool) – Flag specifying if states are to be represented as bit patterns (e.g., ‘A’ -> ‘10’, ‘B’ -> ‘01’, ‘AB’ -> ‘11’). Defaults to ‘False’.
- Returns:
String containing the states of all nodes in tree.
- Return type:
(str)
- have_updated_rec_tr_at_dict: bool
- have_updated_rec_tr_clado_at_dict: bool
- is_extant_or_sa_on_both_sides_complete_tr_root(a_node: Node) bool
Verify one or more sampled nodes exist on both root sides.
This method is called by extract_reconstructed_tree(), and verifies that there is at least one sampled node (direct sampled ancestor, or sampled extant) on both sides of the root of the complete tree. A root node labeled ‘root’ should be guaranteed to exist by this function’s caller.
- Parameters:
a_node (dendropy.Node) – Node from which to start recurring so as to find if there are sampled taxa on both sides of root. E.g., the origin node.
- Returns:
Whether there is at least one or more sampled (observed) taxon on both sides of the complete tree’s root node.
- Return type:
(bool)
- max_age: float | None
- n_extant_sampled_terminal_nodes: int
- n_extant_terminal_nodes: int
- n_extinct_sampled_terminal_nodes: int
- n_extinct_terminal_nodes: int
- n_rec_branches() int
Return the number of real branches in the reconstructed tree.
Counts every node of ‘self.tree_reconstructed’ whose incoming edge is a real branch (see ‘is_real_branch’, module-level, for exactly which ones that excludes – notably, a lineage bisected by a sampled ancestor contributes two real branches, not one, as long as both segments have non-zero length).
Always operates on the reconstructed tree (extracting it first, if not already done) – unlike the complete tree, the reconstructed tree is what every per-branch, clock-model-style quantity in PhyloJunction (stub counts, Gamma-spike rates) is defined over, so “number of branches” is tied to the same tree for consistency.
- Returns:
Number of real branches in the reconstructed tree.
- Return type:
(int)
- n_sa_nodes: int
- node_ages_dict: Dict[str, float]
- node_attr_dict: Dict[str, Dict[str, Any]]
- node_heights_dict: Dict[str, float]
- origin_age: float | None
- origin_edge_length: float
- origin_node: Node | None
- plot_node(axes: Axes, node_attr: str = 'state', draw_reconstructed: bool | None = False, **kwargs) None
Draw tree on provided Axes instance.
This method is required whenever the user asks for a DAG node to be drawn.
- Parameters:
axes (matplotlib.pyplot.Axes) – Axes object where we are drawing the tree.
node_attr (str) – Name of the attribute according to which one wants to color the AnnotatedTree’s branches with. Defaults to ‘state’.
draw_reconstructed (bool, optional) – Whether we are drawing the reconstructed tree instead of the complete tree. Defaults to ‘False’.
- plot_node_continuous_attr(axes: Axes, node_attr: str = 'mutation_rate', use_age: bool = False, cmap_name: str = 'inferno', draw_reconstructed: bool = False) None
Draw tree on provided Axes, colored by a continuous attribute.
This is the ‘colored chronogram’ visualization (branch lengths remain in time units; see ‘plot_ann_tree_continuous_attr’ for details). Not currently PhyloJunction’s GUI default for a clock-model-annotated tree node (see ‘plot_node_phylogram’ below, and ‘pgm.DeterministicNodeDAG.plot_node’); still available for direct use.
- Parameters:
axes (matplotlib.pyplot.Axes) – Axes object where we are drawing the tree.
node_attr (str) – Name of the per-branch attribute to color branches by. Defaults to ‘mutation_rate’ (currently the only such attribute; letting the user choose among several is future work).
use_age (bool) – Flag specifying if age or time is being used. Defaults to ‘False’.
cmap_name (str) – Name of a Matplotlib sequential colormap. Defaults to ‘inferno’.
draw_reconstructed (bool, optional) – Whether we are drawing the reconstructed tree instead of the complete tree. Defaults to ‘False’.
- plot_node_phylogram(axes: Axes, node_attr: str = 'mutation_rate', draw_reconstructed: bool = False, color: str = 'black') None
Draw tree on provided Axes as a monochromatic phylogram.
Branch lengths are rescaled by ‘node_attr’ instead of being in time units; see ‘plot_ann_tree_phylogram’ for details. This is the default way PhyloJunction’s GUI draws a deterministic tree node whose branches carry a continuous, clock-model-populated attribute (see ‘pgm.DeterministicNodeDAG.plot_node’).
- Parameters:
axes (matplotlib.pyplot.Axes) – Axes object where we are drawing the tree.
node_attr (str) – Name of the per-branch attribute to scale branch lengths by. Defaults to ‘mutation_rate’.
draw_reconstructed (bool, optional) – Whether we are drawing the reconstructed tree instead of the complete tree. Defaults to ‘False’.
color (str) – Color every branch is drawn in. Defaults to ‘black’.
- populate_n_stubs_on_branches_of_rec_tr() None
Populate n_stub for branches of the reconstructed tree.
This method is not called upon initialization of class, but rather when information about branches’ stubs is required, e.g., when a Gamma-spike clock model is used somewhere in the DAG.
The reconstructed tree’s root/seed node always ends up with ‘n_stub == 0’ here – not as a special case, but because the root has no reconstructed parent for the accumulation loop below to walk up from in the first place (see ‘is_real_branch’, module-level, for the full reasoning on why this is structural, not a convention, and why it holds even when the root is reached via a chain of direct ancestors above it).
There is no return and only a side-effect (each node in the reconstructed tree has a member ‘n_stub’ initialized and populated.
- populate_nd_attr_dict(attrs_of_interest_list: List[str], attr_dict_added_separately_from_tree: bool = False) None
Populate member nested dictionary with node attributes.
This method is not called upon initialization of class, but rather when information about nodes’ states is required, e.g., when get_taxon_states_str() is called. The method takes the attribute values (for one or more attributes) stored in a DendroPy.Tree, and copies them into the member dictionary node_attr_dict.
There is no return and only a side-effect.
- Parameters:
attrs_of_interest_list (str) – List of attribute names to store in member dictionary.
attr_dict_added_separately_from_tree (bool) – Flag specifying whether method is being called outside tree initialization (i.e., to a tree that already exists), or during tree initialization.
- rec_str() str
- rec_tr_at_dict: Dict[str, List[AttributeTransition]] | None
- rec_tr_clado_at_dict: Dict[str, AttributeTransition] | None
- rec_tr_node_ages_dict: Dict[str, float]
- rec_tr_node_heights_dict: Dict[str, float]
- rec_tr_root_age: float
- rec_tr_root_node: Node | None
- rec_tr_sa_lineage_dict: Dict[str, List[SampledAncestor]] | None
- root_age: float
- root_node: Node | None
- sa_lineage_dict: Dict[str, List[SampledAncestor]] | None
- sa_obs_nodes_labels: Tuple[str, ...]
- seed_age: float
- slice_age_ends: List[float] | None
- slice_t_ends: List[float] | None
- state_count: int
- state_count_dict: Dict[int, int]
- tree: Tree
- tree_died: bool | None
- tree_invalid: bool | None
- tree_read_as_newick: bool
- tree_reconstructed: Tree
- update_rec_tr_at_dict(rec_tree_root_nd: Node) None
Update ‘rec_tr_at_dict’ and ‘rec_clado_at_dict’ members.
The ‘at_dict’ member of the AnnotatedTree, when defined, will by default host the state transitions of every node of the complete tree. This method initializes ‘rec_tr_at_dict’ so that it reflects the reconstructed tree – it is only called when necessary, by the ‘extract_reconstructed_tree’ method.
Member ‘rec_tr_clado_at_dict’ is also updated. Internal nodes undergoing cladogenetic changes that are in the complete tree but not in the reconstructed tree are removed.
- update_rec_tr_sa_lineage_dict() None
Update ‘rec_tr_sa_lineage_dict’ member.
The ‘rec_tr_sa_lineage_dict’ member of the AnnotatedTree, when initialized, will be identical to the complete tree’s ‘sa_lineage_dict’. But with the pruning of the complete tree into the reconstructed tree, some of the internal nodes whose names are keys inside ‘sa_lineage_dict’ are pruned (because one of their children lineages dies off). Their SampledAncestor’s associated instances must then be passed down to their surviving lineages (which then must also be annotated with ‘is_sa_lineage == True’).
- Parameters:
rec_tree_root_nd (DendroPy.Node) – Node that roots the reconstructed tree.
- with_origin: bool
- phylojunction.data.tree.clear_trait_colorbar(axes: Axes) None
Remove ‘axes’s own colorbar (if any), restoring its position.
PhyloJunction’s GUI reuses a single Figure/Axes pair across node selections and re-draws. ‘plot_ann_tree_continuous_attr’ (below) draws its colorbar directly onto ‘axes’ (via ‘fig.colorbar(…, ax=axes, …)’), which carves the space for it out of ‘axes’ itself – a resize that is part of ‘axes’s own position state, so it survives ‘axes.cla()’ (which only clears drawn content, not geometry). Calling that again (e.g., every time the GUI’s ‘Re-draw’ button is clicked) would otherwise shrink an already-shrunk ‘axes’ further each time, and a colorbar is never removed just because a later plot does not itself add one. That “later plot” is not limited to tree-plotting functions: a completely different, non-tree DAG node (e.g., a scalar like an origin-age node, rendered through ‘pgm.plot_node_histogram’/’pgm.plot_blank’) can be selected right after a colored-chronogram one, reusing the very same Axes/Figure, so this function is called from there too (not only from every ‘plot_ann_tree*’ function below) – otherwise a colorbar added for a previous tree would be left behind indefinitely, since nothing about plotting a histogram or a blank Axes would ever remove it on its own.
The colorbar and ‘axes’s pre-colorbar position are tracked via ‘_pj_trait_colorbar’/’_pj_trait_position’, two attributes stashed directly on ‘axes’ itself (set by ‘plot_ann_tree_continuous_attr’ right before it draws the colorbar) – there is nothing to do here if neither was ever set (no colorbar has been drawn on this Axes yet).
- phylojunction.data.tree.get_color_map(n_states: int) Dict[int, str]
Create and return a map from discrete state to color.
This method uses a palette of very contrasting colors if the number of states is lesser or equal to 20. If greater than 20 and lesser or equal to 120, the method switches to another palette and carries out some truncation to avoid colors that are almost white. If the number of states is greater than 120, it switches to yet another palette, truncating it again. The choice of palette and truncation is arbitrary, and was informed by an experiment in plotting.pj_seeing_colors.py.
- Parameters:
n_states (int) – Number of states.
- Returns:
- A dictionary with an integer representing a
discrete state, and a string containing the hex code of a color.
- Return type:
(dict)
- phylojunction.data.tree.get_node_name(nd: Node) str
Return node name.
Get name of node that may be stored in a DendroPy.Node as either its label, taxon, or taxon.label members. It tries them all to make sure a node name is found and returned. If none is found, an exception is raised.
- Parameters:
nd (dendropy.Node) – Node whose name one wants to collect.
- Returns:
Name of the node.
- Return type:
(str)
- phylojunction.data.tree.get_x_coord_from_attr_product(ann_tr: AnnotatedTree, attr_of_interest: str = 'mutation_rate', draw_reconstructed: bool = False) Dict[str, float]
Return x-coordinates for a phylogram (genetic-distance) layout.
Unlike ‘get_x_coord_from_nd_heights’ (branch length = time), here each node’s x-coordinate is the cumulative sum, from the root (or origin), of ‘branch_length * getattr(node, attr_of_interest)’ along its ancestral path – i.e., distance in units of expected character change, not time. A branch whose ‘attr_of_interest’ value is ‘None’ (e.g., the root, or a sampled-ancestor branch; see ‘calculation.gamma_spike_clock_model.populate_gamma_spike_mol_rates_on_rec_tr_branches’) contributes 0.0 (i.e., it is drawn with zero length).
Note that a clock model currently only populates ‘attr_of_interest’ on a tree’s reconstructed topology (not its complete one; see the clock model’s own documentation for why), so calling this with ‘draw_reconstructed=False’ on a tree whose complete topology was never annotated returns every node at x-coordinate 0.0 (not an error, just an uninformative layout).
- Parameters:
ann_tr (AnnotatedTree) – Instance of AnnotatedTree that we are drawing.
attr_of_interest (str) – Name of the (per-branch, constant) node attribute whose product with branch length gives each branch’s contribution to the x-axis. Defaults to ‘mutation_rate’.
draw_reconstructed (bool, optional) – Whether we are drawing the reconstructed tree instead of the complete tree. Defaults to ‘False’.
- Returns:
- Dictionary with node labels (str) as keys and
cumulative genetic-distance x-coordinates (float) as values.
- Return type:
(dict)
- phylojunction.data.tree.get_x_coord_from_nd_heights(ann_tr: AnnotatedTree, use_age: bool = False, unit_branch_lengths: bool = False, draw_reconstructed: bool = False) Dict[str, float]
Return x-coordinates for all nodes in tree.
This method returns a dictionary of node labels as keys, node x_coords (time) as values.
- Parameters:
ann_tr (AnnotatedTree) – Instance of AnnotatedTree that we are drawing.
use_age (bool) – Flag specifying if to use node age or not. Defaults to ‘False’.
unit_branch_lengths (bool, optional) – If branch lengths are all 1.0 (currently not used). Defaults to ‘False’.
draw_reconstructed (bool, optional) – Whether we are drawing the reconstructed tree instead of the complete tree. Defaults to ‘False’.
- phylojunction.data.tree.get_y_coord_from_n_obs_nodes(ann_tr: AnnotatedTree, start_at_origin: bool = False, sa_along_branches: bool = True, draw_reconstructed: bool = False) Dict[str, float]
Return y-coordinates for all nodes in tree.
This method returns a dictionary of node labels as keys, y-coords as values. Y-coords here are integers that go from 1 to the total number of observable nodes. Every observable node will be 1 y-unit away from each other.
- Parameters:
ann_tr (AnnotatedTree) – Instance of AnnotatedTree that we are drawing.
start_at_origin (bool) – Flag specifying if tree starts at the origin node. Defaults to ‘False’.
sa_along_branches (bool) – Flag specifying if direct (sampled) ancestors should be placed along a branch. Defaults to ‘True’.
draw_reconstructed (bool, optional) – Flag specifying if tree being drawn is the reconstructed tree or complete tree. Defaults to ‘False’.
- phylojunction.data.tree.is_real_branch(nd: Node, epsilon: float) bool
Return whether ‘nd’s incoming edge is a ‘real’ branch.
A branch is not “real” (and so is excluded from things like per-branch rate draws or branch counts) if it has no parent (the root/seed node has no incoming edge at all), or if its length is ‘None’ or effectively zero (e.g., a sampled-ancestor’s own zero-length edge). A lineage bisected by a sampled ancestor is represented as two separate edges in the reconstructed tree (the dummy parent’s incoming edge, and the ‘is_sa_lineage’ edge continuing past it) – both count as separate real branches here, as long as each has non-zero length, since each really is a distinct branch of the tree.
On the root/seed node specifically: this exclusion is not a special case bolted on for convenience, nor a statement that the root “has zero stubs” or “gets no baseline spike” as some kind of assumption – it falls out structurally from what the root is. The reconstructed tree’s root is, by construction, the oldest point for which there is any retained evidence at all (the MRCA of every sampled/retained node) – so it has no reconstructed parent, and therefore no incoming branch for a stub count or a clock-model rate to even be defined along, regardless of whether earlier, unobserved branching events might have happened further back in the complete tree. (If an earlier branching event did have retained descendants on both sides, that event – not the current one – would itself be the root; if only one side was retained, that event is unifurcation-suppressed away during reconstruction and never becomes a distinguishable “stub on the root’s own branch”, precisely because the root does not have one.) This matches Douglas et al. (2025)’s own treatment: their eqn (2.8) explicitly excludes “nodes with branch length zero… i.e. sampled ancestors and the root” from the saltative-branching proportion, for the same reason – neither has a real, time- bearing branch of its own for a rate or a spike to apply to. This holds regardless of whether the root happens to be reached via a chain of direct ancestors above it (see ‘calculation.gamma_spike_clock_model’ for why a node that is both ‘is_sa_lineage’ and a genuine bifurcation, e.g. such a root, still correctly gets no baseline “+1” spike on its own incoming branch either – same underlying reason, one level down).
This is shared by every piece of code that needs to agree on exactly which branches count (e.g., ‘calculation.gamma_spike_clock_model.populate_gamma_spike_mol_rates_on_rec_tr_branches’ and ‘AnnotatedTree.n_rec_branches’, below) so they can never drift apart from one another.
- Parameters:
nd (dendropy.Node) – Node whose incoming edge is being checked.
epsilon (float) – Threshold below which a branch length is considered effectively zero (see ‘AnnotatedTree.epsilon’).
- Returns:
Whether ‘nd’s incoming edge counts as a real branch.
- Return type:
(bool)
- phylojunction.data.tree.pj_get_name_mrca_obs_terminals(nd: Node, nd_label_list: List[str]) str
Get name of the MRCA of specified observed terminal nodes.
This method recursively finds the most recent common ancestor of the terminal nodes whose names are specified as input. These nodes must be observed, i.e., be either direct (sampled) ancestors, or sampled extant terminal nodes.
- Parameters:
nd (dendropy.Node) – Node to recur and grab the name of.
nd_label_list (str) – List of node names whose MRCA’s name is being searched.
- Returns:
Name of MRCA node
- Return type:
(str)
- phylojunction.data.tree.plot_ann_tree(ann_tr: AnnotatedTree, axes: Axes, use_age: bool = False, start_at_origin: bool = False, attr_of_interest: str = 'state', sa_along_branches: bool = True, draw_reconstructed: bool = False) Tuple[Dict[str, float]]
Plot instance of AnnotatedTree on provided Axes instance.
Plotting is a side-effect.
- Parameters:
ann_tr (AnnotatedTree) – Instance of AnnotatedTree that we are drawing.
axes (matplotlib.pyplot.Axes) – Axes object where we are drawing the tree.
use_age (bool) – Flag specifying if age or time is being used.
start_at_origin (bool) – Flag specifying if drawing starts at the origin node. Defaults to ‘False’.
attr_of_interest (str) – Name of the attribute according to which states we are coloring tree branches. Defaults to ‘state’.
sa_along_branches (bool) – Flag specifying if direct (sampled) ancestors should be placed along a branch. Defaults to ‘True’.
draw_reconstructed (bool) – Flag specifying if reconstructed tree is meant to be drawn instead of complete tree. Defaults to ‘False’.
- Returns:
Tuple with two dictionary. This return is used for unit testing purposes only. Keys are node names, values are either x- or y-coordinates.
- Return type:
(tuple)
- phylojunction.data.tree.plot_ann_tree_continuous_attr(ann_tr: AnnotatedTree, axes: Axes, attr_of_interest: str = 'mutation_rate', use_age: bool = False, cmap_name: str = 'inferno', draw_reconstructed: bool = False) Tuple[Dict[str, float], Dict[str, float]]
Plot a chronogram with branches colored by a continuous attribute.
This is the ‘colored chronogram’ visualization: branch lengths remain in units of time (same x-coordinates as ‘plot_ann_tree’), and each branch is colored along a sequential (‘cold’ to ‘hot’) colormap according to its (constant) value for ‘attr_of_interest’ (e.g., ‘mutation_rate’, as populated by a ‘calculation.clock_model.ClockModel’).
Plotting is a side-effect. A colorbar reflecting the attribute’s (min, max) range is added alongside the tree.
- Parameters:
ann_tr (AnnotatedTree) – Instance of AnnotatedTree that we are drawing.
axes (matplotlib.pyplot.Axes) – Axes object where we are drawing the tree.
attr_of_interest (str) – Name of the per-branch attribute to color branches by. Defaults to ‘mutation_rate’ (currently the only continuous, clock-model-populated attribute; letting the user choose among several is future work).
use_age (bool) – Flag specifying if age or time is being used. Defaults to ‘False’.
cmap_name (str) – Name of a Matplotlib sequential colormap. Defaults to ‘inferno’.
draw_reconstructed (bool) – Flag specifying if the reconstructed tree is meant to be drawn instead of the complete tree. Defaults to ‘False’.
- Returns:
- Tuple with two dictionaries (node name -> x- or
y-coordinate). This return is used for unit testing purposes only.
- Return type:
(tuple)
- phylojunction.data.tree.plot_ann_tree_phylogram(ann_tr: AnnotatedTree, axes: Axes, attr_of_interest: str = 'mutation_rate', draw_reconstructed: bool = False, color: str = 'black') Tuple[Dict[str, float], Dict[str, float]]
Plot a monochromatic phylogram (branches scaled by an attribute).
This is the ‘phylogram’ visualization: unlike ‘plot_ann_tree’ and ‘plot_ann_tree_continuous_attr’ (both of which place branches by time), here each branch’s length is rescaled by its (constant) value for ‘attr_of_interest’ (e.g., ‘mutation_rate’) – i.e., the x-axis becomes a genetic-distance (expected character change) axis instead of a time axis. Branches are drawn in a single, neutral color, since the rescaled length already encodes the attribute.
This is PhyloJunction’s GUI default for a deterministic tree node whose branches carry a continuous, clock-model-populated attribute (see ‘pgm.DeterministicNodeDAG.plot_node’). A manual chronogram/phylogram toggle (letting the user switch back to ‘plot_ann_tree_continuous_attr’ for the same node) is future work.
Plotting is a side-effect.
- Parameters:
ann_tr (AnnotatedTree) – Instance of AnnotatedTree that we are drawing.
axes (matplotlib.pyplot.Axes) – Axes object where we are drawing the tree.
attr_of_interest (str) – Name of the per-branch attribute to scale branch lengths by. Defaults to ‘mutation_rate’.
draw_reconstructed (bool) – Flag specifying if the reconstructed tree is meant to be drawn instead of the complete tree. Defaults to ‘False’.
color (str) – Color every branch is drawn in. Defaults to ‘black’.
- Returns:
- Tuple with two dictionaries (node name -> x- or
y-coordinate). This return is used for unit testing purposes only.
- Return type:
(tuple)