Wolfram Computation Meets Knowledge

Trees Continue to Grow 🌱🌳

Last year we released Version 13.0 of the Wolfram Language. Here are the updates in trees since then, including the latest features in 13.1.

 

Trees Continue to Grow 🌱🌳

In Version 12.3 we introduced Tree as a new fundamental construct in the Wolfram Language. In Version 13.0 we added a variety of styling options for trees, and in Version 13.1 we’re adding more styling as well as a variety of new fundamental features.

An important update to the fundamental Tree construct in Version 13.1 is the ability to name branches at each node, by giving them in an association:

Tree
&#10005


All tree functions now include support for associations:

NestTree
&#10005


In many uses of trees the labels of nodes are crucial. But particularly in more abstract applications one often wants to deal with unlabeled trees. In Version 13.1 the function UnlabeledTree (roughly analogously to UndirectedGraph) takes a labeled tree, and basically removes all visible labels. Here is a standard labeled tree

RandomTree
&#10005


and here’s the unlabeled analog:

UnlabeledTree
&#10005


In Version 12.3 we introduced ExpressionTree for deriving trees from general symbolic expressions. Our plan is to have a wide range of “special trees” appropriate for representing different specific kinds of symbolic expressions. We’re beginning this process in Version 13.1 by, for example, having the concept of “Dataset trees”. Here’s ExpressionTree converting a dataset to a tree:

ExpressionTree
&#10005


And now here’s TreeExpression “inverting” that, and producing a dataset:

TreeExpression
&#10005


(Remember the convention that *Tree functions return a tree; while Tree* functions take a tree and return something else.)

Here’s a “graph rendering” of a more complicated dataset tree:

TreeGraph
&#10005


The new function TreeLeafCount lets you count the total number of leaf nodes on a tree (basically the analog of LeafCount for a general symbolic expression):

TreeLeafCount
&#10005


Another new function in Version 13.1 that’s often useful in getting a sense of the structure of a tree without inspecting every node is RootTree. Here’s a random tree:

tree = RandomTree
&#10005


RootTree can get a subtree that’s “close to the root”:

RootTree
&#10005


It can also get a subtree that’s “far from the leaves”, in this case going down to elements that are at level –2 in the tree:

RootTree
&#10005


In some ways the styling of trees is like the styling of graphs—though there are some significant differences as a result of the hierarchical nature of trees. By default, options inserted into a particular tree element affect only that tree element:

Tree
&#10005


But you can give rules that specify how elements in the subtree below that element are affected:

Tree
&#10005


In Version 13.1 there is now detailed control available for styling both nodes and edges in the tree. Here’s an example that gives styling for parent edges of nodes:

Tree
&#10005


Options like TreeElementStyle determine styling from the positions of elements. TreeElementStyleFunction, on the other hand, determines styling by applying a function to the data at each node:

Tree
&#10005


This uses both data and position information for each node:

Tree
&#10005


In analogy with VertexShapeFunction for graphs, TreeElementShapeFunction provides a general mechanism to specify how nodes of a tree should be rendered. This named setting for TreeElementShapeFunction makes every node be displayed as a circle:

Tree
&#10005


Comments

Join the discussion

!Please enter your comment (at least 5 characters).

!Please enter your name.

!Please enter a valid email address.