PBDBMakie — Makie tree visualization

PaleobiologyDB.PBDBMakie is a package extension that renders TaxonomyTree objects as rectangular dendrograms in Makie figures. It activates when a Makie backend is loaded and is accessed through the PaleobiologyDB.PBDBMakie submodule.

Installation

pkg> add CairoMakie PhyloPicMakie

Activation

using CairoMakie   # or GLMakie, WGLMakie, …
using PaleobiologyDB
using PaleobiologyDB.Taxonomy
using PaleobiologyDB.PBDBMakie: taxonomytreeplot, taxonomytreeplot!, set_rank_axis_ticks!, augment_leaf_phylopic!

Quick start — basic dendrogram

Build a subtree with taxon_subtree then pass it to taxonomytreeplot:

using CairoMakie
using PaleobiologyDB
using PaleobiologyDB.Taxonomy
using PaleobiologyDB.PBDBMakie: taxonomytreeplot

tree = taxon_subtree("Carnivora"; leaf_rank = "family")

fig, ax, plt = taxonomytreeplot(tree; show_leaf_labels = true)
display(fig)

taxonomytreeplot returns a Makie.FigureAxisPlot object containing the figure, axis, and plot object accessible via .figure, .axis, and .plot. The x-axis is automatically labelled with rank names at their dendrogram depth positions.

Coloring by rank

Set color_by_rank = true to assign each branch and node a colour based on its taxonomic rank:

fig, ax, plt = taxonomytreeplot(tree;
    color_by_rank = true,
    show_leaf_labels = true,
)
display(fig)

A custom palette can be supplied as a Dict{String, Any} mapping rank names to any Makie-compatible colour:

palette = Dict(
    "order"  => :steelblue,
    "family" => :darkorange,
    "genus"  => :seagreen,
)

fig, ax, plt = taxonomytreeplot(tree;
    color_by_rank = true,
    rank_palette  = palette,
    show_leaf_labels = true,
)

Ladderized layout

ladderize = true sorts children of each node by ascending subtree leaf count before the depth-first traversal. Smaller subtrees appear at the top of the plot, giving a cleaner, more asymmetric appearance for trees with unequal branching:

fig, ax, plt = taxonomytreeplot(tree;
    ladderize = true,
    show_leaf_labels = true,
)

Showing internal node labels

Internal nodes (non-leaf taxa) can be labelled with their taxon names:

fig, ax, plt = taxonomytreeplot(tree;
    showinternal      = true,
    internal_fontsize = 7,
    internal_color    = :gray50,
    show_leaf_labels  = true,
)

Adding to an existing Makie axis

taxonomytreeplot! adds a dendrogram to an axis you have already created, allowing composition with other Makie plots or multi-panel figures:

using CairoMakie
using PaleobiologyDB
using PaleobiologyDB.Taxonomy
using PaleobiologyDB.PBDBMakie: taxonomytreeplot!, set_rank_axis_ticks!

tree = taxon_subtree("Canidae"; leaf_rank = "genus")

fig = Figure(size = (1000, 700))
ax  = Axis(fig[1, 1]; title = "Canidae genera")

taxonomytreeplot!(ax, tree; show_leaf_labels = true, ladderize = true)
set_rank_axis_ticks!(ax, tree)

display(fig)

set_rank_axis_ticks! configures the x-axis ticks with rank names. When using the standalone taxonomytreeplot, this is called automatically unless show_rank_ticks = false is passed.

Multi-panel figure combining trees

using CairoMakie
using PaleobiologyDB
using PaleobiologyDB.Taxonomy
using PaleobiologyDB.PBDBMakie: taxonomytreeplot!, set_rank_axis_ticks!

t_fam = taxon_subtree("Carnivora"; leaf_rank = "family")
t_gen = taxon_subtree("Canidae";   leaf_rank = "genus")

fig = Figure(size = (1400, 600))

ax1 = Axis(fig[1, 1]; title = "Carnivora — families")
taxonomytreeplot!(ax1, t_fam; show_leaf_labels = true, color_by_rank = true)
set_rank_axis_ticks!(ax1, t_fam)

ax2 = Axis(fig[1, 2]; title = "Canidae — genera")
taxonomytreeplot!(ax2, t_gen; show_leaf_labels = true, ladderize = true)
set_rank_axis_ticks!(ax2, t_gen)

display(fig)

PhyloPic silhouettes beside leaf labels

taxonomytreeplot can overlay PhyloPic silhouette images to the right of each leaf label. The default thumbnail-backed render path works once a Makie backend and PaleobiologyDB.PBDBMakie are loaded:

using CairoMakie
using PaleobiologyDB
using PaleobiologyDB.PBDBMakie: taxonomytreeplot

The default phylopic_image_rendering = :thumbnail path uses PNG thumbnails through the hard dependency PhyloPicMakie. SVG-backed :vector or :source_file cases still require an SVG-capable FileIO plugin in the active environment.

Inline mode (default)

Each silhouette appears immediately to the right of its taxon-name label. The horizontal gap is controlled by phylopic_xoffset (in data units):

tree = taxon_subtree("Carnivora"; leaf_rank = "family")

fig, ax, plt = taxonomytreeplot(tree;
    show_leaf_labels = true,
    show_phylopic    = true,
    phylopic_xoffset = 0.25,
)
display(fig)

The result looks like:

────* Felidae     [IMG]
────* Canidae  [IMG]

Aligned mode

Set phylopic_align = true to place all silhouettes in a single right-hand column, regardless of label length. Increase phylopic_xoffset to control the column's distance from the deepest rank:

fig, ax, plt = taxonomytreeplot(tree;
    show_leaf_labels = true,
    show_phylopic    = true,
    phylopic_align   = true,
    phylopic_xoffset = 2.0,
)
display(fig)

The result looks like:

────* Felidae                    [IMG]
────* Canidae                    [IMG]
────* Ursidae                    [IMG]

Controlling glyph size and aspect ratio

phylopic_glyph_size sets the half-height of each silhouette in data units (total height = 2 × phylopic_glyph_size). The default 1.0 works well for trees where leaves are spaced 2 units apart (the default row_spacing). Set phylopic_aspect = :stretch to force square glyphs instead of preserving the original image proportions:

fig, ax, plt = taxonomytreeplot(tree;
    show_leaf_labels     = true,
    show_phylopic        = true,
    phylopic_glyph_size  = 0.35,
    phylopic_aspect      = :preserve,   # default — maintains original proportions
)

Handling missing images

Some taxa lack PhyloPic images. The phylopic_on_missing attribute controls what happens:

ValueBehaviour
:skip (default)Silently omit the glyph
:placeholderDraw a placeholder glyph image in place of the missing silhouette
:errorThrow an ErrorException
fig, ax, plt = taxonomytreeplot(tree;
    show_phylopic       = true,
    phylopic_on_missing = :placeholder,
)

Note on reactivity

PhyloPic images are loaded once when the plot is created. Toggling p[:show_phylopic][] = false after creation hides/shows the existing images without re-downloading. After creation, resize and relimit changes keep the glyphs visibly sized and anchored to the intended label policy through the shared overlay substrate. Changing phylopic_glyph_size, phylopic_align, or the tree itself still requires recreating the plot with taxonomytreeplot.

Note on extension activation

show_phylopic = true requires the PBDBMakie extension to be active, which happens automatically when a Makie backend is loaded alongside PaleobiologyDB. Bring the extension exports into scope with using PaleobiologyDB.PBDBMakie or call them through the PaleobiologyDB.PBDBMakie submodule. PhyloPicMakie is a hard dependency of PaleobiologyDB and is always available once the package is installed.

Saving figures

Makie's standard save function works with any output format:

fig, ax, plt = taxonomytreeplot(tree; show_leaf_labels = true)

save("carnivora_families.png", fig)
save("carnivora_families.svg", fig)
save("carnivora_families.pdf", fig)

Example scripts

examples/src/taxonomytree.jl is the direct happy-path tree example. It enables PaleobiologyDB.set_autocaching!(true), renders an Elephantidae genus tree through the public show_phylopic = true path, saves taxonomytree.png in the current working directory by default, and prints the output path. Pass a custom output path as the first argument if you want the PNG somewhere else. Run it from a development checkout with:

julia --project=examples examples/src/taxonomytree.jl

examples/src/phylopicgallery.jl is the companion gallery example. It enables caching, builds a small multi-taxon PhyloPic gallery with pbdb_phylopic_grid, saves phylopicgallery.png in the current working directory by default, and prints the output path:

julia --project=examples examples/src/phylopicgallery.jl

Custom figure and axis options

Pass figure_kwargs and axis_kwargs (named tuples) to control the underlying Figure and Axis:

fig, ax, plt = taxonomytreeplot(tree;
    figure_kwargs = (; size = (1200, 900), backgroundcolor = :white),
    axis_kwargs   = (;
        title           = "Carnivora — family-level tree",
        titlesize       = 18,
        xlabel          = "Rank depth",
        xticklabelsize  = 11,
    ),
    show_leaf_labels = true,
    color_by_rank = true,
)

Attribute reference

All attributes can be passed as keyword arguments to taxonomytreeplot or taxonomytreeplot!.

AttributeDefaultDescription
ladderizefalseSort children of each node by ascending subtree leaf count
branch_color:blackBranch line colour (used when color_by_rank = false)
branch_linewidth1.5Branch line width in points
show_nodestrueDraw a circular marker at every vertex
node_color:blackNode marker colour (used when color_by_rank = false)
node_size5Node marker size in points
color_by_rankfalseColour branches and nodes by taxonomic rank
rank_palettenothingDict{String,Any} mapping rank → colour; nothing uses the built-in cycle
show_leaf_labelstrueShow leaf taxon-name labels
leaf_label_fontsize9Leaf label font size in points
leaf_label_color:blackLeaf label colour
leaf_label_xoffset0.1Rightward offset for leaf labels in data units
leaf_label_yoffset0.0Vertical offset for leaf labels in data units (positive = upward)
showinternalfalseShow internal node name labels
internal_fontsize7Internal label font size in points
internal_color:gray40Internal label colour
row_spacing2.0Vertical gap between consecutive leaf rows in data units
show_phylopicfalseDraw a PhyloPic silhouette to the right of each leaf label
phylopic_glyph_size1.0Half-height of each silhouette in data units
phylopic_alignfalsePlace all silhouettes in a single right-hand column
phylopic_xoffset0.65Rightward gap in data units beyond the leaf-label origin
phylopic_yoffset0.3Vertical offset for PhyloPic silhouettes in data units (positive = upward)
phylopic_image_rendering:thumbnailImage URL to fetch: :thumbnail, :raster, :og_image, :vector, or :source_file
phylopic_on_missing:skipPolicy when no image is found: :skip, :placeholder (placeholder glyph image), :error
phylopic_aspect:preserve:preserve (original proportions) or :stretch (square)

The following keywords are consumed by taxonomytreeplot (standalone) and are not passed to the recipe:

KeywordDefaultDescription
show_rank_tickstrueCall set_rank_axis_ticks! automatically
figure_kwargs(;)Forwarded to Makie.Figure(; ...)
axis_kwargs(;)Forwarded to Makie.Axis(; ...)