Python API¶
tree_annotated_plot.plot¶
plot ¶
plot(tree: str | Path | dict | TreeNode, chart: ChartInput, *, chart_strain_field: str, tree_strain_field: str, branch_length: Literal['div', 'num_date'], tree_size: int = 100, tree_location: TreeLocation | None = None, tree_line_width: float = 2.0, tree_node_size: float = 45, leader_line_width: float = 1.0, scale_bar: bool = False, branch_length_units: str | None = None, prune_tree_to_chart: bool = False, prune_chart_to_tree: bool = False, strict_version: bool = True, connect_leader_to_label: bool = False, strain_label_font_size: float = 10.0, strain_label_font_weight: Literal['normal', 'bold'] = 'normal', shift_tree_loc: int = 0, color_tree_by: str | None = None, tree_color_scale: dict[str, str] | None = None, tree_color_legend_format: dict[str, Any] | None = None, tree_color_legend_show: bool = True, scale_bar_font_size: float = 10.0) -> alt.HConcatChart | alt.VConcatChart
Return an Altair chart with a phylogenetic tree drawn alongside chart.
PlotConfig¶
The single source of truth for plot-parameter descriptions. The
tree-annotated-plot CLI generates its options from this dataclass
(see Command line), and the tree_annotated_plot.plot function accepts the
same keyword arguments.
PlotConfig
dataclass
¶
Configuration for tree_annotated_plot.plot.
Each field's type annotation is Annotated[T, "<description>"]. The
description is the canonical text that appears in the function's
docstring, the click --help text, and the rendered Python API page.
chart_strain_field
instance-attribute
¶
chart_strain_field: Annotated[str, 'Required. The data-column name the chart\'s strain axis encodes (e.g. "strain" or "axis_label").']
tree_strain_field
instance-attribute
¶
tree_strain_field: Annotated[str, 'Required. Where on each tree tip to find the strain identifier. The literal string "name" selects the top-level Auspice node `name` field; any other value X selects node_attrs[X] (auto-unwrapping the Auspice {"value": ...} convention). Dotted paths are not accepted.']
branch_length
instance-attribute
¶
branch_length: Annotated[Literal['div', 'num_date'], 'Required. Which Auspice node attribute supplies branch lengths. "div" means divergence branch lengths; "num_date" means calendar dates.']
tree_size
class-attribute
instance-attribute
¶
tree_size: Annotated[int, "Size in pixels of tree depth. For vertical layout (chart strain on `y`) this is the tree panel's *width*; for horizontal layout (chart strain on `x`) this is the tree panel's *height*."] = 100
tree_location
class-attribute
instance-attribute
¶
tree_location: Annotated[TreeLocation | None, 'Which side of the chart to draw the tree on. Defaults to the side with the strain-axis labels ("left" for y-encoded strain, "bottom" for x-encoded). Other valid values: "right" (y-encoded), "top" (x-encoded).'] = None
tree_line_width
class-attribute
instance-attribute
¶
tree_line_width: Annotated[float, "Stroke width (px) for the tree's branch lines. Default 2."] = 2.0
tree_node_size
class-attribute
instance-attribute
¶
tree_node_size: Annotated[float, 'Area (px²) of the small filled circles drawn at each tip. Default 45. Setting tree_node_size=0 disables the tip-circle layer entirely.'] = 45
leader_line_width
class-attribute
instance-attribute
¶
leader_line_width: Annotated[float, "Stroke width (px) for the dashed leader lines that connect each tip's branch endpoint to the strain row when the branch doesn't extend all the way to branch_max. Default 1.0. Setting leader_line_width=0 disables the leader-line layer entirely."] = 1.0
scale_bar
class-attribute
instance-attribute
¶
scale_bar: Annotated[bool, 'Off by default. When on, adds a small bar in the tree panel showing the branch-length scale. Tip-row alignment with the chart is preserved.'] = False
branch_length_units
class-attribute
instance-attribute
¶
branch_length_units: Annotated[str | None, 'Used only when scale_bar is on and branch_length="div": the unit string pasted after the bar\'s numeric length (e.g. "substitutions/site"). None renders unitless. For branch_length="num_date" the label is always in years/months and this argument is ignored.'] = None
prune_tree_to_chart
class-attribute
instance-attribute
¶
prune_tree_to_chart: Annotated[bool, "When off (default), tree tips not present in the chart's strain set are a fatal error. When on, those tips (and any internal nodes whose subtrees become empty) are dropped before drawing, with single-child internals collapsed into their kept child."] = False
prune_chart_to_tree
class-attribute
instance-attribute
¶
prune_chart_to_tree: Annotated[bool, "When off (default), chart strains not present in the tree are a fatal error. When on, chart rows whose `chart_strain_field` value isn't a tree tip are filtered out before drawing."] = False
strict_version
class-attribute
instance-attribute
¶
strict_version: Annotated[bool, 'When on (default), known-stale specs raise: Vega-Lite 5 or earlier, and Auspice JSON whose `version` is not v2. When off, those become warnings and parsing proceeds.'] = True
connect_leader_to_label
class-attribute
instance-attribute
¶
connect_leader_to_label: Annotated[bool, "Off (default): the chart's strain-axis labels are kept as the user wrote them and dashed leader lines stop at the tree panel's chart-facing edge. On: leaders extend all the way to the labels — which requires moving the labels off the chart's strain axis and into the tree panel, so the chart's strain-axis labels, ticks, axis line, and title are SUPPRESSED (any user-supplied `axis=...` is overridden) and replacement labels are rendered alongside the tree. Label widths are estimated; for crowded charts tune `strain_label_font_size` or `shift_tree_loc`."] = False
strain_label_font_size
class-attribute
instance-attribute
¶
strain_label_font_size: Annotated[float, 'Font size (px) for the strain text labels rendered in the tree panel when `connect_leader_to_label` is on.'] = 10.0
strain_label_font_weight
class-attribute
instance-attribute
¶
strain_label_font_weight: Annotated[Literal['normal', 'bold'], 'Font weight for the strain text labels rendered in the tree panel when `connect_leader_to_label` is on.'] = 'normal'
shift_tree_loc
class-attribute
instance-attribute
¶
shift_tree_loc: Annotated[int, 'Pixels by which to shift the tree toward (positive) or away from (negative) the chart. Default 0. Has no effect when connect_leader_to_label is off.'] = 0
color_tree_by
class-attribute
instance-attribute
¶
color_tree_by: Annotated[str | None, 'Color the tree by an Auspice attribute. Pass a node_attrs key (e.g. "subclade"), or "genotype:<GENE>:<SITE>" / "genotype:<GENE>:<SITE1>,<SITE2>,..." (e.g. "genotype:HA1:158" or "genotype:HA1:158,189") to color by the inferred genotype state at a site or haplotype across sites. A categorical legend is drawn below the plot; missing values are gray. None (default) leaves the tree black.'] = None
tree_color_scale
class-attribute
instance-attribute
¶
tree_color_scale: Annotated[dict[str, str] | None, 'Hardcoded color scale that overrides the default coloring. Keys are category labels, values are colors (any Vega-Lite-compatible string — e.g. hex codes). The legend order follows the order keys appear here. The keys must match the tree\'s categories one-to-one (extra or missing keys are an error). "unknown" is always gray and must not be specified. For genotype/haplotype colorings, the category strings include the site number (e.g. "K158" or "K158/E189"); a mismatch error lists the actual tree categories. CLI form: "value1=#hex1,value2=#hex2,...".'] = None
tree_color_legend_format
class-attribute
instance-attribute
¶
tree_color_legend_format: Annotated[dict[str, Any] | None, 'Vega-Lite Legend properties to apply to the tree-coloring legend. Pass any subset of the keys at https://vega.github.io/vega-lite/docs/legend.html#properties as a Python dict (e.g. `{"orient": "left", "labelFontSize": 13, "titleFontSize": 13}`). Common keys: "orient" (default "bottom"), "direction", "columns", "padding", "offset", "labelFontSize", "titleFontSize". Smart default: when "orient" is "left" or "right" and you have not set "columns" or "direction", "columns" is forced to 1 so entries stack vertically. None (default) leaves Vega-Lite\'s defaults. Has no effect when `color_tree_by` is None. CLI form: a JSON object string (quote the whole argument), e.g. \'{"orient":"left","labelFontSize":13}\'.'] = None
tree_color_legend_show
class-attribute
instance-attribute
¶
tree_color_legend_show: Annotated[bool, 'Whether to render the tree-coloring legend. On (default) shows it. Off hides the legend entirely while keeping the tree colored. Has no effect when `color_tree_by` is None.'] = True
scale_bar_font_size
class-attribute
instance-attribute
¶
scale_bar_font_size: Annotated[float, "Font size (px) for the tree's scale bar label. Default 10. Has no effect when `scale_bar` is off."] = 10.0
__init__ ¶
__init__(*, chart_strain_field: Annotated[str, 'Required. The data-column name the chart\'s strain axis encodes (e.g. "strain" or "axis_label").'], tree_strain_field: Annotated[str, 'Required. Where on each tree tip to find the strain identifier. The literal string "name" selects the top-level Auspice node `name` field; any other value X selects node_attrs[X] (auto-unwrapping the Auspice {"value": ...} convention). Dotted paths are not accepted.'], branch_length: Annotated[Literal['div', 'num_date'], 'Required. Which Auspice node attribute supplies branch lengths. "div" means divergence branch lengths; "num_date" means calendar dates.'], tree_size: Annotated[int, "Size in pixels of tree depth. For vertical layout (chart strain on `y`) this is the tree panel's *width*; for horizontal layout (chart strain on `x`) this is the tree panel's *height*."] = 100, tree_location: Annotated[TreeLocation | None, 'Which side of the chart to draw the tree on. Defaults to the side with the strain-axis labels ("left" for y-encoded strain, "bottom" for x-encoded). Other valid values: "right" (y-encoded), "top" (x-encoded).'] = None, tree_line_width: Annotated[float, "Stroke width (px) for the tree's branch lines. Default 2."] = 2.0, tree_node_size: Annotated[float, 'Area (px²) of the small filled circles drawn at each tip. Default 45. Setting tree_node_size=0 disables the tip-circle layer entirely.'] = 45, leader_line_width: Annotated[float, "Stroke width (px) for the dashed leader lines that connect each tip's branch endpoint to the strain row when the branch doesn't extend all the way to branch_max. Default 1.0. Setting leader_line_width=0 disables the leader-line layer entirely."] = 1.0, scale_bar: Annotated[bool, 'Off by default. When on, adds a small bar in the tree panel showing the branch-length scale. Tip-row alignment with the chart is preserved.'] = False, branch_length_units: Annotated[str | None, 'Used only when scale_bar is on and branch_length="div": the unit string pasted after the bar\'s numeric length (e.g. "substitutions/site"). None renders unitless. For branch_length="num_date" the label is always in years/months and this argument is ignored.'] = None, prune_tree_to_chart: Annotated[bool, "When off (default), tree tips not present in the chart's strain set are a fatal error. When on, those tips (and any internal nodes whose subtrees become empty) are dropped before drawing, with single-child internals collapsed into their kept child."] = False, prune_chart_to_tree: Annotated[bool, "When off (default), chart strains not present in the tree are a fatal error. When on, chart rows whose `chart_strain_field` value isn't a tree tip are filtered out before drawing."] = False, strict_version: Annotated[bool, 'When on (default), known-stale specs raise: Vega-Lite 5 or earlier, and Auspice JSON whose `version` is not v2. When off, those become warnings and parsing proceeds.'] = True, connect_leader_to_label: Annotated[bool, "Off (default): the chart's strain-axis labels are kept as the user wrote them and dashed leader lines stop at the tree panel's chart-facing edge. On: leaders extend all the way to the labels — which requires moving the labels off the chart's strain axis and into the tree panel, so the chart's strain-axis labels, ticks, axis line, and title are SUPPRESSED (any user-supplied `axis=...` is overridden) and replacement labels are rendered alongside the tree. Label widths are estimated; for crowded charts tune `strain_label_font_size` or `shift_tree_loc`."] = False, strain_label_font_size: Annotated[float, 'Font size (px) for the strain text labels rendered in the tree panel when `connect_leader_to_label` is on.'] = 10.0, strain_label_font_weight: Annotated[Literal['normal', 'bold'], 'Font weight for the strain text labels rendered in the tree panel when `connect_leader_to_label` is on.'] = 'normal', shift_tree_loc: Annotated[int, 'Pixels by which to shift the tree toward (positive) or away from (negative) the chart. Default 0. Has no effect when connect_leader_to_label is off.'] = 0, color_tree_by: Annotated[str | None, 'Color the tree by an Auspice attribute. Pass a node_attrs key (e.g. "subclade"), or "genotype:<GENE>:<SITE>" / "genotype:<GENE>:<SITE1>,<SITE2>,..." (e.g. "genotype:HA1:158" or "genotype:HA1:158,189") to color by the inferred genotype state at a site or haplotype across sites. A categorical legend is drawn below the plot; missing values are gray. None (default) leaves the tree black.'] = None, tree_color_scale: Annotated[dict[str, str] | None, 'Hardcoded color scale that overrides the default coloring. Keys are category labels, values are colors (any Vega-Lite-compatible string — e.g. hex codes). The legend order follows the order keys appear here. The keys must match the tree\'s categories one-to-one (extra or missing keys are an error). "unknown" is always gray and must not be specified. For genotype/haplotype colorings, the category strings include the site number (e.g. "K158" or "K158/E189"); a mismatch error lists the actual tree categories. CLI form: "value1=#hex1,value2=#hex2,...".'] = None, tree_color_legend_format: Annotated[dict[str, Any] | None, 'Vega-Lite Legend properties to apply to the tree-coloring legend. Pass any subset of the keys at https://vega.github.io/vega-lite/docs/legend.html#properties as a Python dict (e.g. `{"orient": "left", "labelFontSize": 13, "titleFontSize": 13}`). Common keys: "orient" (default "bottom"), "direction", "columns", "padding", "offset", "labelFontSize", "titleFontSize". Smart default: when "orient" is "left" or "right" and you have not set "columns" or "direction", "columns" is forced to 1 so entries stack vertically. None (default) leaves Vega-Lite\'s defaults. Has no effect when `color_tree_by` is None. CLI form: a JSON object string (quote the whole argument), e.g. \'{"orient":"left","labelFontSize":13}\'.'] = None, tree_color_legend_show: Annotated[bool, 'Whether to render the tree-coloring legend. On (default) shows it. Off hides the legend entirely while keeping the tree colored. Has no effect when `color_tree_by` is None.'] = True, scale_bar_font_size: Annotated[float, "Font size (px) for the tree's scale bar label. Default 10. Has no effect when `scale_bar` is off."] = 10.0) -> None
Tree loading¶
load_auspice ¶
load_auspice(source: str | Path | dict, *, tree_strain_field: str, branch_length: str = 'div', strict_version: bool = True) -> TreeNode
Load an Auspice JSON tree from a path or dict.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str | Path | dict
|
Path to an Auspice JSON file, or an already-parsed dict. |
required |
tree_strain_field
|
str
|
Where on each tip to find the strain identifier. The literal string
|
required |
branch_length
|
str
|
Which Auspice node attribute supplies branch lengths. |
'div'
|
strict_version
|
bool
|
When True (default), raise |
True
|
TreeNode
dataclass
¶
A node in a phylogenetic tree.
name carries the resolved strain identifier for tips (the value at
tree_strain_field). For internal nodes, name is the Auspice top-level
name field — internal-node identity isn't used for chart-strain matching.
x is divergence from the root (read from node_attrs.div).
y is set by :func:layout and is the integer index of the node's tip
(for tips) or the midpoint of its descendants' tip indices (for internal
nodes).
node_attrs and branch_attrs carry the raw Auspice JSON dicts unchanged
so downstream code (e.g. _color) can read them directly. node_attrs.div
has already been consumed by _resolve_branch_length; node_attrs[X] is
where things like subclade live; branch_attrs.mutations[<gene>] is
where mutation strings like "N158K" live.