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, spacing: int = 0, 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
spacing
class-attribute
instance-attribute
¶
spacing: Annotated[int, 'Pixels of blank space between the tree panel and the chart panel. Default 0, which butts the two together. Distinct from `shift_tree_loc`, which moves the tree within its own panel by resizing the label strip; `spacing` sets the gap between the panels and applies whether or not `connect_leader_to_label` is on.'] = 0
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, by resizing the label strip inside the tree panel. Default 0. Has no effect when connect_leader_to_label is off; to set the gap between the tree and chart panels use `spacing`.'] = 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, spacing: Annotated[int, 'Pixels of blank space between the tree panel and the chart panel. Default 0, which butts the two together. Distinct from `shift_tree_loc`, which moves the tree within its own panel by resizing the label strip; `spacing` sets the gap between the panels and applies whether or not `connect_leader_to_label` is on.'] = 0, 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, by resizing the label strip inside the tree panel. Default 0. Has no effect when connect_leader_to_label is off; to set the gap between the tree and chart panels use `spacing`.'] = 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.