How can I draw simple trees in LaTeX?

While I'd normally second Will Robertson's comment, since TikZ is fantastic and worth learning, I think TikZ's overkill for this situation. I personally find its tree specification syntax bulkier than necessary. My preferred tool for the job is the qtree package (which is on CTAN, too, and is apparently included in both TeX Live and MikTeX). The package is really simple to use. Consider the following TeX:

\Tree[.IP [.NP [.Det \textit{the} ]
               [.N\1 [.N \textit{package} ]]]
          [.I\1 [.I \textsc{3sg.Pres} ]
                [.VP [.V\1 [.V \textit{is} ]
                           [.AP [.Deg \textit{really} ]
                                [.A\1 [.A \textit{simple} ]
                                      \qroof{\textit{to use}}.CP ]]]]]]

This produces the following tree:

Sample X-bar theory parse tree.

That's all it takes! And what's great about it is that the TeX description reads like the tree. I can glance at the TeX, and I instantly know what the created tree is going to look like. The basic syntax is simply [.node-name subtrees... ]; \qroof, which draws the triangle, requires its node name at the end, instead. The \1 is just a shortcut for a math-mode prime. In addition, qtree will always render _ and ^ as sub- and super-scripts, too. (Unless you turn this off.)

In general, you can provide node names at the beginning ([.+ 1 [.* 2 3 ]]) or the end ([ 1 [ 2 3 ].* ].+); you can even provide node names in both places, but then they must match (unsurprisingly). This, incidentally, is why \qroof takes its node name the way it does. You can even leave the node name off entirely to get a node with a smooth join. If any of this is unclear, check out the manual.

Now, qtree as-is has one downside, which is that it is designed for simple trees. It does offer limited support for changing inter-node spacing, framing parts of trees, and things like that, but it's not capable of doing anything incredibly fancy. But luckily, if you want that, you can still get it: enter tikz-qtree. This package allows you to leverage the full power of TikZ to draw your trees. The two obvious features are: (a) instead of text, the labels in a tree can be arbitrary \nodes; and (b) you can redefine how it draws the edges to get arrows, dashed lines, curving edges, and so on. But it's more powerful than just this: if you embed a \Tree into a TikZ picture, you can do whatever you want with the nodes, such as circle them, draw arrows between them for a transformation, etc.

Maybe you don't need this power now, but the take-home message is that using qtree won't lock you in to the simple trees. If you decide that you want the more powerful trees, all you need to do is change one import; everything will keep working the way it did, but you get more power, too. I'm not sure if tikz-qtree this actually uses qtree under the hood or not, but either way, all the syntax for qtree still works, and the output is identical, at least as far as I can tell.


(PS: Linguists, please excuse/correct any errors in the above tree; it's been a year or two since my syntax course.)


I am going to put in a plea on behalf of forest. Although forest is extremely flexible and powerful, it can also be used very simply. Like qtree, it uses a simple, concise syntax which 'reads like a tree' but I found forest's syntax a bit easier to learn. (However, this may be because I learnt qtree first.) Like tikz-qtree, it gives you all the power of TikZ but, unlike qtree, you do not have to change packages in order to use that power as forest is already using TikZ underneath. Moreover, in addition to all the power of TikZ, you have all the power of forest itself. And that is very significant: powerful, specialised support for drawing trees of all kinds, manually, automatically and/or dynamically. Take a look at examples on this site for a sense of the possibilities.

For simple trees, however, forest is very simple.

This answer consists of two parts. The first part applies to the current version of forest (version 2). The second, which consists of my original answer, applies to the earlier version of forest (version 1). The changes are not great but, if you are new to the package, you will find it easier to follow if you read the section which applies to the version you are using without modifications.


Current forest: version 2


Here is a forest version of the code for the tree posted in Antal S-Z's answer.

\documentclass[tikz,border=10pt]{standalone}
\usepackage[linguistics]{forest}
\begin{document}
\begin{forest}
  [IP
    [NP
     [Det
       [\textit{the}]
     ]
     [N$'$
       [N
         [\textit{package}]
       ]
     ]
    ]
    [I$'$
      [I
        [\textsc{3sg.Pres}
        ]
      ]
      [VP
        [V$'$
          [V
            [\textit{is}]
          ]
          [AP
            [Deg
              [\textit{extremely}]
            ]
            [A$'$
              [A
                [\textit{straightforward}]
              ]
              [CP
                [\textit{to wield}, roof]
              ]
            ]
          ]
        ]
      ]
    ]
  ]
\end{forest}
\end{document}

The basic idea is that every node in the tree is enclosed in square brackets. The node's subtree is included in the same brackets, if it has one.

Note that there are no dots for branch points and that there is no need to leave a space before a closing square bracket. In fact, the above code is equivalent to

\begin{forest}
  [IP[NP[Det[\textit{the}]][N$'$[N[\textit{package}]]]][I$'$[I[\textsc{3sg.Pres}]][VP[V$'$[V[\textit{is}]][AP[Deg[\textit{extremely}]][A$'$[A[\textit{straightforward}]][CP[\textit{to wield}, roof]]]]]]]]
\end{forest}

Obviously, this is anything but easy to read - hence my preference for lots of 'unnecessary' space.

forest cannot, however, abide a blank line and these must be avoided.

The above trees produce the following output:

tree

How to turn a tree into the bracket specification forest uses

Start with the root and put it inside a forest environment and inside square brackets:

\begin{forest}
  [IP% root
% rest of tree will go here
  ]
\end{forest}

The rest of the tree consists of one or more smaller trees. These are subtrees of the root node. In this case, we have 2 subtrees so we start with the root of each subtree and add each of them in its own pair of square brackets.

\begin{forest}
  [IP% root
    [NP% root of subtree
% rest of subtree will go here
    ]
    [I$'$% root of subtree
% rest of subtree will go here
    ]
  ]
\end{forest}

Then you can work on each of the subtrees in turn and repeat the operation.

Special styles

Because we are interested in this question in trees for linguistics, I added the option linguistics when loading the package.

\usepackage[linguistics]{forest}

This does two things: (1) loads the linguistics library, making various styles of use in linguistics available (e.g. the roof used above); (2) changes the default appearance of trees.

If we only wanted some trees to use the library's defaults (perhaps some of our trees are linguistics trees and some are some other kind of tree), we could instead use

\usepackage{forest}
\useforestlibrary{linguistics} 

in the preamble. Then we could use

\forestapplylibrarydefaults{linguistics}

within a local TeX scope in the body of the document to apply the defaults only to selected trees. For example,

{\forestapplylibrarydefaults{linguistics}
\begin{forest}
  <specification 1>
\end{forest}}

\begin{forest}
  <specification 2>
\end{forest}

would apply lingustics defaults to the tree given by <specification 1> but not to that given by <specification 2>.

But we'll assume that all the trees in our current document are linguistics trees for now.

To make the triangular roof, we just add , roof to the appropriate node and forest applies its triangular roof style.

If you later want to make more complex trees, you can also use TikZ styles in just the same way. Adding , text=red to a node will turn the text of the node red, for example.

     [N$'$, text=red
       [N
         [\textit{package}]
       ]
     ]

red node

Conditional styling saves typing

You can also, if you wish, save changing the font for every terminal node. If most of the terminal nodes should be italicised, you can say

if n children=0{% if the node doesn't have any children of its own
  font=\itshape
}{},

To apply this conditional to the whole tree and, hence, italics to all terminal nodes, we can say

  for tree={
    if n children=0{
      font=\itshape
    }{},
  }

after \begin{forest} and before specifying the tree itself. This is known as the preamble of the tree.

You can then override this for the single small-caps node, by saying , font=\scshape after specifying the node's contents.

Complete code for revised tree

\documentclass[tikz,border=10pt]{standalone}
\usepackage[linguistics]{forest}
\begin{document}
\begin{forest}
  for tree={
    if n children=0{
      font=\itshape
    }{},
  }
  [IP
    [NP
     [Det
       [the]
     ]
     [N$'$
       [N
         [package]
       ]
     ]
    ]
    [I$'$
      [I
        [3sg.Pres, font=\scshape]
      ]
      [VP
        [V$'$
          [V
            [is]
          ]
          [AP
            [Deg
              [extremely]
            ]
            [A$'$
              [A
                [straightforward]
              ]
              [CP
                [to wield, roof]
              ]
            ]
          ]
        ]
      ]
    ]
  ]
\end{forest}
\end{document}

Selected additional features

One common feature requested for linguists' trees seems to be to ensure that the terminal nodes are aligned.

forest allows you to specify that nodes should be aligned on a common tier. To use this feature, you just write , tier=<name of tier> after the content of the node is specified.

Here's an extreme example:

extreme tier alignment

\begin{forest}
  for tree={
    fit=band,% spaces the tree out a little to avoid collisions
  }
  [things
    [cabbages, tier=vegetables
      [peaches, tier=fruits]
    ]
    [kings, tier=aristocrats]
    [sealing wax
      [queens, tier=aristocrats
        [carrots, tier=vegetables]
        [pineapple, tier=fruits]
        [aubergine, tier=vegetables]
      ]
    ]
  ]
\end{forest}

In the case of our linguists' tree, we just want the terminal nodes aligned. We are already saying we want them in italics, so we can just add a tier specification there.

We did have

  for tree={
    if n children=0{
      font=\itshape
    }{},
  }

Now we change this to the following:

  for tree={
    if n children=0{
      font=\itshape,
      tier=terminal,
    }{},
  }

and the tree changes quite dramatically:

aligned terminal nodes


Earlier forest: version 1


Here is a forest version of the code for the tree posted in Antal S-Z's answer.

\documentclass[tikz,border=10pt]{standalone}
\usepackage{forest}
\begin{document}
\begin{forest}
  [IP
    [NP
     [Det
       [\textit{the}]
     ]
     [N$'$
       [N
         [\textit{package}]
       ]
     ]
    ]
    [I$'$
      [I
        [\textsc{3sg.Pres}
        ]
      ]
      [VP
        [V$'$
          [V
            [\textit{is}]
          ]
          [AP
            [Deg
              [\textit{extremely}]
            ]
            [A$'$
              [A
                [\textit{straightforward}]
              ]
              [CP
                [\textit{to wield}, triangle]
              ]
            ]
          ]
        ]
      ]
    ]
  ]
\end{forest}
\end{document}

The basic idea is that every node in the tree is enclosed in square brackets. The node's subtree is included in the same brackets, if it has one.

Note that there are no dots for branch points and that there is no need to leave a space before a closing square bracket. In fact, the above code is equivalent to

\begin{forest}
  [IP[NP[Det[\textit{the}]][N$'$[N[\textit{package}]]]][I$'$[I[\textsc{3sg.Pres}]][VP[V$'$[V[\textit{is}]][AP[Deg[\textit{extremely}]][A$'$[A[\textit{straightforward}]][CP[\textit{to wield}, triangle]]]]]]]]
\end{forest}

Obviously, this is anything but easy to read - hence my preference for lots of 'unnecessary' space.

forest cannot, however, abide a blank line and these must be avoided.

The above trees produce the following output:

tree

How to turn a tree into the bracket specification forest uses

Start with the root and put it inside a forest environment and inside square brackets:

\begin{forest}
  [IP% root
% rest of tree will go here
  ]
\end{forest}

The rest of the tree consists of one or more smaller trees. These are subtrees of the root node. In this case, we have 2 subtrees so we start with the root of each subtree and add each of them in its own pair of square brackets.

\begin{forest}
  [IP% root
    [NP% root of subtree
% rest of subtree will go here
    ]
    [I$'$% root of subtree
% rest of subtree will go here
    ]
  ]
\end{forest}

Then you can work on each of the subtrees in turn and repeat the operation.

Special styles

To make the triangular roof, we just add , triangle to the appropriate node and forest applies its triangular root style.

If you later want to make more complex trees, you can also use TikZ styles in just the same way. Adding , text=red to a node will turn the text of the node red, for example.

     [N$'$, text=red
       [N
         [\textit{package}]
       ]
     ]

red node

Branches for logicians and linguists

Even simple logicians' and linguists' trees probably need a little styling in order to look right. In particular, trees typically have branches which start from a common point beneath the parent node and extend to a point above the child. Although this is not default, we can implement it by saying

parent anchor=south,% start branches beneath the parent
child anchor=north,% end branches above the child

To apply this to the whole tree, we can say

\begin{forest}
  for tree={
    parent anchor=south,
    child anchor=north,
  }
  [IP
    ...
  ]
\end{forest}

branches for logicians and linguists

Conditional styling saves typing

You can also, if you wish, save changing the font for every terminal node. If most of the terminal nodes should be italicised, you can say

if n children=0{% if the node doesn't have any children of its own
  font=\itshape
}{},

You can then override this for the single small-caps node, by saying , font=\scshape after specifying the node's contents.

Complete code for revised tree

\documentclass[tikz,border=10pt,multi]{standalone}
\usepackage{forest}
\begin{document}
\begin{forest}
  for tree={
    parent anchor=south,
    child anchor=north,
    if n children=0{
      font=\itshape
    }{},
  }
  [IP
    [NP
     [Det
       [the]
     ]
     [N$'$
       [N
         [package]
       ]
     ]
    ]
    [I$'$
      [I
        [3sg.Pres, font=\scshape]
      ]
      [VP
        [V$'$
          [V
            [is]
          ]
          [AP
            [Deg
              [extremely]
            ]
            [A$'$
              [A
                [straightforward]
              ]
              [CP
                [to wield, triangle]
              ]
            ]
          ]
        ]
      ]
    ]
  ]
\end{forest}
\end{document}

Selected additional features

One common feature requested for linguists' trees seems to be to ensure that the terminal nodes are aligned.

forest allows you to specify that nodes should be aligned on a common tier. To use this feature, you just write , tier=<name of tier> after the content of the node is specified.

Here's an extreme example:

extreme tier alignment

\begin{forest}
  for tree={
    parent anchor=south,
    child anchor=north,
    fit=band,% spaces the tree out a little to avoid collisions
  }
  [things
    [cabbages, tier=vegetables
      [peaches, tier=fruits]
    ]
    [kings, tier=aristocrats]
    [sealing wax
      [queens, tier=aristocrats
        [carrots, tier=vegetables]
        [pineapple, tier=fruits]
        [aubergine, tier=vegetables]
      ]
    ]
  ]
\end{forest}

In the case of our linguists' tree, we just want the terminal nodes aligned. We are already saying we want them in italics, so we can just add a tier specification there.

We did have

  for tree={
    parent anchor=south,
    child anchor=north,
    if n children=0{
      font=\itshape
    }{},
  }

Now we change this to the following:

  for tree={
    parent anchor=south,
    child anchor=north,
    if n children=0{
      font=\itshape,
      tier=terminal,
    }{},
  }

and the tree changes quite dramatically:

aligned terminal nodes


For simple, non "graphical" tree you can use the dirtree package:

\documentclass{article}
\usepackage{dirtree}
\begin{document}

\dirtree{%
.1 debug.
.2 filename.
.2 modules.
.3 module.
.3 module.
.3 module.
.2 level.
}

\end{document}

dirtree

Tags:

Trees

Diagrams