Skip to content

Allotaxonograph

The two-panel matplotlib rank-rank map.

keyflux.viz.allotaxonograph.allotaxonograph(list1, list2, *, alpha=1.0 / 3.0, labels=None, top=30, bins=24, figsize=(12.0, 6.0), cmap='viridis')

Draw a two-panel allotaxonograph of two ranked lists.

Parameters:

Name Type Description Default
list1 RankedList

The first ranked list.

required
list2 RankedList

The second ranked list.

required
alpha float

Rank-turbulence-divergence tuning parameter; annotated on the figure and used for the contribution panel.

1.0 / 3.0
labels tuple[str, str] | None

(label1, label2) for the two systems; falls back to each list's own label, then to generic names.

None
top int

Number of top contributors to show in the right panel.

30
bins int

Number of bins per axis in the rank-rank histogram.

24
figsize tuple[float, float]

Figure size in inches.

(12.0, 6.0)
cmap str

Matplotlib colormap name for the histogram.

'viridis'

Returns:

Name Type Description
A Figure

class:matplotlib.figure.Figure with two axes. The function never

Figure

calls show(), so it displays inline in Jupyter and saves with

Figure

fig.savefig(...).

Raises:

Type Description
ValueError

If either list is empty (propagated from :func:rtd).

Contract
  • Returns a Figure with exactly two axes.
  • Inputs are never mutated.
  • The histogram and the contribution bars come from the same rtd call, so the two panels are always consistent.

Examples:

>>> from keyflux.datasets import load_jkbren_example
>>> r1, r2 = load_jkbren_example()
>>> fig = allotaxonograph(r1, r2, alpha=1.0, labels=("A", "B"))
>>> type(fig).__name__
'Figure'
>>> len(fig.axes)
2
Source code in keyflux/viz/allotaxonograph.py
def allotaxonograph(
    list1: RankedList,
    list2: RankedList,
    *,
    alpha: float = 1.0 / 3.0,
    labels: tuple[str, str] | None = None,
    top: int = 30,
    bins: int = 24,
    figsize: tuple[float, float] = (12.0, 6.0),
    cmap: str = "viridis",
) -> Figure:
    """Draw a two-panel allotaxonograph of two ranked lists.

    Args:
        list1: The first ranked list.
        list2: The second ranked list.
        alpha: Rank-turbulence-divergence tuning parameter; annotated on the
            figure and used for the contribution panel.
        labels: ``(label1, label2)`` for the two systems; falls back to each
            list's own label, then to generic names.
        top: Number of top contributors to show in the right panel.
        bins: Number of bins per axis in the rank-rank histogram.
        figsize: Figure size in inches.
        cmap: Matplotlib colormap name for the histogram.

    Returns:
        A :class:`matplotlib.figure.Figure` with two axes. The function never
        calls ``show()``, so it displays inline in Jupyter and saves with
        ``fig.savefig(...)``.

    Raises:
        ValueError: If either list is empty (propagated from :func:`rtd`).

    Contract:
        - Returns a Figure with exactly two axes.
        - Inputs are never mutated.
        - The histogram and the contribution bars come from the same ``rtd``
          call, so the two panels are always consistent.

    Examples:
        >>> from keyflux.datasets import load_jkbren_example
        >>> r1, r2 = load_jkbren_example()
        >>> fig = allotaxonograph(r1, r2, alpha=1.0, labels=("A", "B"))
        >>> type(fig).__name__
        'Figure'
        >>> len(fig.axes)
        2
    """
    if labels is None:
        labels = (list1.label or "system 1", list2.label or "system 2")

    result = rtd(list1, list2, alpha=alpha)
    _types, ranks1, ranks2 = list1.aligned(list2)

    fig = Figure(figsize=figsize)
    ax_hist, ax_bars = fig.subplots(1, 2)
    _diamond_histogram(ax_hist, ranks1, ranks2, labels, bins=bins, cmap=cmap)
    _balance_bars(ax_bars, result, labels, top=top)
    fig.suptitle(
        f"Allotaxonograph  (alpha = {alpha:g},  divergence = {result.divergence:.3f})"
    )
    fig.tight_layout()
    return fig