Getting started
plot the tree
using CairoMakie, BasicTreePlots
tree = ((:a, :b), (:c, (:d, :e)))
treeplot(tree)
Because most nested collections in julia have AbstractTrees.children defined they can be plotted with treeplot.
We might want to just look at the tree rather than the axis
fig = Figure()
ax = Axis(fig[1, 1])
hidedecorations!(ax)
hidespines!(ax)
treeplot!(tree)
fig
Rather than the square branches we can use straight branches
fig = Figure()
ax = Axis(fig[1, 1])
hidedecorations!(ax)
hidespines!(ax)
treeplot!(tree; branchstyle = :straight)
fig
We can plot onto a Polar axis for a circular layout
fig = Figure()
ax = PolarAxis(fig[1, 1])
hidedecorations!(ax)
hidespines!(ax)
treeplot!(tree)
fig
Labeling tips
We can add tip labels
fig = Figure()
ax = PolarAxis(fig[1, 1], rautolimitmargin = (0.0, 0.1))
hidedecorations!(ax)
hidespines!(ax)
tp = treeplot!(tree)
treelabels!(tp)
fig
We can increase the tip label fontsize.
fig = Figure()
ax = PolarAxis(fig[1, 1], rautolimitmargin = (0.0, 0.2))
hidedecorations!(ax)
hidespines!(ax)
tp = treeplot!(tree)
treelabels!(tp; fontsize = 40)
fig
Adjusting branch appearence
We can change the color of the branches
fig = Figure()
ax = PolarAxis(fig[1, 1], rautolimitmargin = (0.0, 0.1))
hidedecorations!(ax)
hidespines!(ax)
tp = treeplot!(tree; branchcolor = :orange)
treelabels!(tp; fontsize = 20)
fig
We can change the line color based on info in the tree
branchcolors = map(PreOrderDFS(tree)) do node
hash(node)
end
fig = Figure()
ax = PolarAxis(fig[1, 1], rautolimitmargin = (0.0, 0.1))
hidedecorations!(ax)
hidespines!(ax)
tp = treeplot!(tree; branchcolor = branchcolors)
treelabels!(tp; fontsize = 20)
fig
For instance if we have external data about each node in the tree
tree_data =
Dict(node => (; support = rand(), favorite_number = rand(1:5)) for node in PreOrderDFS(tree))Dict{Any, @NamedTuple{support::Float64, favorite_number::Int64}} with 9 entries:
:a => (support = 0.391602, favorite_number = 4)
:b => (support = 0.459686, favorite_number = 4)
(:a, :b) => (support = 0.315346, favorite_number = 5)
(:c, (:d, :e)) => (support = 0.472252, favorite_number = 3)
:d => (support = 0.554905, favorite_number = 3)
:e => (support = 0.554149, favorite_number = 2)
:c => (support = 0.683826, favorite_number = 5)
(:d, :e) => (support = 0.755764, favorite_number = 2)
((:a, :b), (:c, (:d, :e))) => (support = 0.0235308, favorite_number = 1)then we can plot support as the color and the favorite number as the line width.
branchcolors = map(PreOrderDFS(tree)) do node
tree_data[node].support
end
branchwidths = map(PreOrderDFS(tree)) do node
tree_data[node].favorite_number
end
fig = Figure()
ax = PolarAxis(fig[1, 1], rautolimitmargin = (0.0, 0.1))
hidedecorations!(ax)
hidespines!(ax)
p = treeplot!(tree; branchcolor = branchcolors, branchwidth = branchwidths)
treelabels!(tp; fontsize = 20)
Colorbar(fig[1, 2][3, 1], p)
fig
Markers for each node
We can employ markers in the nodes to showcase the tree's information
fig = Figure()
ax = PolarAxis(fig[1, 1], rautolimitmargin = (0.0, 0.2))
hidedecorations!(ax)
hidespines!(ax)
tp=treeplot!(tree;)
treelabels!(tp; fontsize = 20, labeloffset = (0.0, 10))
treescatter!(tp; color = branchcolors, markersize = 15)
fig
treescatter(tp) is equivalent to scatter(tp.orderedpoints) so all the keyword arguments for scatter should work. The points are ordered according to the result of PreOrderDFS(tree), attributes can be assocated by matching that order.
Other adjustments of style
For a PolarAxis, We can also control the span across which the tree is plotted. with the openangle parameter
fig = Figure()
ax = PolarAxis(fig[1, 1], rautolimitmargin = (0.0, 0.1))
hidedecorations!(ax)
hidespines!(ax)
p = treeplot!(
tree;
branchcolor = branchcolors,
branchwidth = branchwidths,
openangle = deg2rad(140),
)
Colorbar(fig[1, 2][3, 1], p)
fig