diff --git a/docs/python-api.md b/docs/python-api.md
index 73eab4d096..79a44c05cc 100644
--- a/docs/python-api.md
+++ b/docs/python-api.md
@@ -546,6 +546,16 @@ Functions and static methods
Tree.kc_distance
```
+(sec_python_api_trees_balance)=
+
+#### Balance/imbalance indices
+
+```{eval-rst}
+.. autosummary::
+ Tree.colless_index
+ Tree.sackin_index
+ Tree.b1_index
+```
(sec_python_api_trees_sites_mutations)=
diff --git a/python/CHANGELOG.rst b/python/CHANGELOG.rst
index 004f516ac9..00a4aaf916 100644
--- a/python/CHANGELOG.rst
+++ b/python/CHANGELOG.rst
@@ -47,10 +47,22 @@
- Add support for missing data to ``write_vcf``, and add the ``isolated_as_missing``
argument. (:user:`jeromekelleher`, :pr:`2329`, :issue:`447`).
-- Add ``Tree.num_children_array`` and ``Tree.num_children``. Returns the counts of
- the number of child nodes for each or a single node in the tree respectively.
+- Add ``Tree.num_children_array`` and ``Tree.num_children``. Returns the counts of
+ the number of child nodes for each or a single node in the tree respectively.
(:user:`GertjanBisschop`, :issue:`2318`, :issue:`2319`, :pr:`2332`)
+- Add ``Tree.path_length``.
+ (:user:`jeremyguez`, :issue:`2249`, :pr:`2259`).
+
+- Add B1 tree balance index.
+ (:user:`jeremyguez`, :user:`jeromekelleher`, :issue:`2251`, :pr:`2281`, :pr:`2346`).
+
+- Add Sackin tree imbalance index.
+ (:user:`jeremyguez`, :user:`jeromekelleher`, :pr:`2246`, :pr:`2258`).
+
+- Add Colless tree imbalance index.
+ (:user:`jeremyguez`, :user:`jeromekelleher`, :issue:`2250`, :pr:`2266`, :pr:`2344`).
+
**Breaking Changes**
- The JSON metadata codec now interprets the empty string as an empty object. This means
diff --git a/python/tskit/trees.py b/python/tskit/trees.py
index d6e7f6f596..77571c9a1c 100644
--- a/python/tskit/trees.py
+++ b/python/tskit/trees.py
@@ -2783,9 +2783,10 @@ def path_length(self, u, v):
def b1_index(self):
"""
- Returns the B1 balance index for this tree.
- This is defined as the inverse of the sum of all longest paths
- to leaves for each node besides roots.
+ Returns the
+ `B1 balance index `_
+ for this tree. This is defined as the inverse of the sum of all
+ longest paths to leaves for each node besides roots.
.. seealso:: See `Shao and Sokal (1990)
`_ for details.
@@ -2797,12 +2798,13 @@ def b1_index(self):
def colless_index(self):
"""
- Returns the Colless imbalance index for this tree.
- This is defined as the sum of all differences between number of
- leaves subtended by the left and right child of each node.
- The Colless index is undefined for non-binary trees and trees
- with multiple roots. This method will raise a LibraryError if the
- tree is not singly-rooted and binary.
+ Returns the
+ `Colless imbalance index `_
+ for this tree. This is defined as the sum of all differences between
+ number of leaves subtended by the left and right child of each node.
+ The Colless index is undefined for non-binary trees and trees with
+ multiple roots. This method will raise a LibraryError if the tree is
+ not singly-rooted and binary.
.. seealso:: See `Shao and Sokal (1990)
`_ for details.
@@ -2814,9 +2816,11 @@ def colless_index(self):
def sackin_index(self):
"""
- Returns the Sackin imbalance index for this tree. This is defined
- as the sum of the depths of all leaves in the tree.
- Equivalent to ``sum(tree.depth(u) for u in tree.leaves())``
+ Returns the
+ `Sackin imbalance index `_
+ for this tree. This is defined as the sum of the depths of all leaves
+ in the tree. Equivalent to ``sum(tree.depth(u) for u in
+ tree.leaves())``
.. seealso:: See `Shao and Sokal (1990)
`_ for details.