5

I'm a new/beginner LaTeX user, and I would like to make syntactic trees with straight spines, somewhat like the ones here:

http://tanvirdhaka.blogspot.com/2010/01/phrase-structure-grammar.html

Can this be done with tikz-qtree? That is what I've been using til now.

Edit: Thanks for some of the responses here. I guess I had two questions. The first "problem" is that when I've created a tree, some branches (which have empty nodes or leaves) are uneven (angled) and thus it looks somewhat unsightly. I've included some of my original code to show what I mean. But I think the responses below might help me fix this problem.

\documentclass[10pt]{article}

\usepackage{tikz}
\usepackage{tikz-qtree}

\begin{document}

\begin{tikzpicture}
\Tree % Ugly tree with uneven branches and different lengths
[.CP 
[.{} ]
[.C$'$ 
    [.C ]
    [.(?) 
[.Neg ]         
[.TP
    [.{} ]
    [.T$'$ 
        [.T ] 
        [.\textit{v}P 
        [.AGENT ]
        [.\textit{v}$'$
            [.\textit{v} ] 
                [.VP 
                [.V ] 
                [.THEME ] ] ] ] ] ] ] ] ] ] ] ] ]
\end{tikzpicture}

\end{document}

The second question I had was how to make a tree with a continuous, straight spine from top to bottom (see second link in my original post above). Does anyone know how to do this?

  • 1
    Welcome to TeX SE. What do you have so far? All questions should include a Minimal (non-)Working Example demonstrating both the issue and your efforts to solve it. I would use qtree for this but that's just because I know it. I'm sure tikz-qtree is also fine if that's what you are familiar with. What's the problem? – cfr Apr 1 '14 at 0:46
3

The package forest (which builds on the graphics package tikz-pgf) can be configured as shown below to give you a straight-spined tree with symmetric binary branching. I took the intermediate projection (bar-level) labels out of your MWE to show the straight line through empty nodes as you requested.

enter image description here

\documentclass[10pt]{article}

\usepackage{tikz}
\usepackage{forest}
\forestset{sn edges/.style={for tree={parent anchor=south, child anchor=north}}}
\forestset{nice empty nodes/.style={for tree={calign=fixed edge angles},
        delay={where content={}{shape=coordinate, for parent={for children={anchor=north}}}{}}}}

\usepackage{times}

\begin{document}

\begin{forest}
sn edges, nice empty nodes
[CP 
    []
    [
        [C ]
         [(?) 
            [Neg ]         
            [TP
                [ ]
                [
                    [T ] 
                    [\textit{v}P 
                        [AGENT ]
                        [
                            [\vphantom{V}\textit{v} ] % the \vphantom{V} makes the height of the little v node the same as the VP node; without it, the branch to the little v goes too low
                            [VP 
                                [V ] 
                                [THEME ]
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
]                                   
\end{forest}

\end{document}

The styles sn edges (to get branches that come to a point below the parent node) and nice empty nodes (to get the straight spine and balanced empty nodes) are taken from the forest documentation, but note that with certain fonts, using these styles together can cause errors, as described in my answer to sn edges and nice empty nodes styles in forest lead to dividing by zero.

An alternative way to get straight-spined trees is to make them directly in tikz, as shown in this answer to Making mixed trees with and without text-containing nodes.

2

This type of diagram can be created using tikz-qtree by explicitly setting the distance of the leaf-nodes from the root of the tree. A minimum working example for this type of diagram would be:

\documentclass{article}

\usepackage{tikz}
\usepackage{tikz-qtree}

\begin{document}

% >>> Specify the "frontier"/leaf-level distance from root:
\tikzset{frontier/.style={distance from root=120pt}}

\Tree [.S   [.NP    [.Det The ]
            [.N Man ] ]
        [.VP    [.V captured ]
            [.NP    [.Det a ] 
                [.N bird ] ] ] ]

\end{document}

This uses elements described in the tikz-qtree documentation on page 5.

The result appears as:

diagram

2

forest is another option to build syntactic trees. In it's documentation abstract you can read:

Forest is a pgf/TikZ-based package for drawing linguistic (and other kinds of) trees. Its main features are (i) a packing algorithm which can produce very compact trees; (ii) a user-friendly interface consisting of the familiar bracket encoding of trees plus the key–value interface to option- setting; (iii) many tree-formatting options, with control over option values of individual nodes and mechanisms for their manipulation; (iv) the possibility to decorate the tree using the full power of pgf/TikZ; (v) an externalization mechanism sensitive to code-changes.

Previous example typed with forest is:

\documentclass[border=10pt]{standalone}
\usepackage{forest}

\begin{document}
\begin{forest}
    where n children=0{tier=word}{}
    [S 
        [NP 
            [Det [The]] 
            [N [Man]]
        ]
        [VP 
            [V [captured]]
            [NP 
                [Det [a]]
                [N [bird]]
            ]
        ]
    ]
\end{forest}
\end{document}

enter image description here

2

This is similar to Jason Zentz's answer, but begins with your original tree and modifies some things further. Like that solution, this uses forest, together with the manual's definition of nice empty nodes (although I implement the idea with a slight variation in coding).

Implemented with forest, the code for your original tree would be like this:

\begin{forest}
  [CP
    [
    ]
    [C$'$
      [C
      ]
      [(?)
        [Neg
        ]
        [TP
          [
          ]
          [T$'$
            [T
            ]
            [\textit{v}P
              [AGENT
              ]
              [\textit{v}$'$
                [\textit{v}
                ]
                [VP
                  [V
                  ]
                  [THEME
                  ]
                ]
              ]
            ]
          ]
        ]
      ]
    ]
  ]
\end{forest}

which gives us

tree 1

Hardly an improvement over the original. If we change the beginning of the tree like this, we can improve it a bit:

\begin{forest}
  for tree={
    parent anchor=south,
    child anchor=north,
    calign=fixed edge angles,
    calign primary angle=-45,
    calign secondary angle=45, 
  }
  [CP ...

This ensures that edges are always drawn from the south anchor of the parent node to the north of the child node, and that the angles between the lines connecting the parent with the leftmost and rightmost children are at constant angles of -45 and 45 degrees respectively. (These angles are measured from the direction of growth which is south by default.)

tree 2

There are a couple of issues here: the line to empty nodes is too long and, also, the line to short nodes is too long. The latter is less noticeable, but nonetheless clear when you compare, say, the siblings v and VP.

We can improve things, although not entirely eliminate the problem, by adding

align=center,
base=bottom,

which will create (potentially) multi-line, tabular nodes with centred columns, and will align siblings by aligning the bottom of these tabulars:

tree 3

Now for the code based on nice empty nodes which Jason Zentz used:

before typesetting nodes={% based on nice empty nodes - page 52 of the manual, used in Jason Zentz's answer: https://tex.stackexchange.com/a/216103/
    if content={}{
      for parent={
        for children={anchor=north},
      },
      shape=coordinate,
    }{},
},

which gives us:

tree 4

This more-or-less incidentally allows you to draw nice trees with empty nodes with children, provided no node has more than 2 children. For example, a tree specified as

  [
    [
      [
        [A
        ]
        [
        ]
      ]
      [
      ]
    ]
    [
      [
      ]
      [
        [
        ]
        [B
        ]
      ]
    ]
  ]

will look as follows:

tree 5

Complete Code

Here is the complete code for the final version of your original tree and the demonstration tree above. I've wrapped the modifications into a style nice tree so that you can just say:

\begin{forest}
  nice tree
  [root node ...

Again, this style will work well for trees where nodes have 0, 1 or 2 children. It will not work well for larger numbers of children, but the trees you are concerned with seem not to require that.

\documentclass[border=5pt, tikz, multi, varwidth]{standalone}
\usepackage{forest}
\standaloneenv{forest}
\begin{document}
\forestset{
  nice tree/.style={
    for tree={
      parent anchor=south,
      child anchor=north,
      calign=fixed edge angles,
      calign primary angle=-45,
      calign secondary angle=45,
      align=center,
      base=bottom,
      before typesetting nodes={% based on nice empty nodes - page 52 of the manual, used in Jason Zentz's answer: https://tex.stackexchange.com/a/216103/
          if content={}{
            for parent={
              for children={anchor=north},
            },
            shape=coordinate,
          }{},
      },
    },
  },
}
\begin{forest}
  nice tree
  [CP
    [
    ]
    [C$'$
      [C
      ]
      [(?)
        [Neg
        ]
        [TP
          [
          ]
          [T$'$
            [T
            ]
            [\textit{v}P
              [AGENT
              ]
              [\textit{v}$'$
                [\textit{v}
                ]
                [VP
                  [V
                  ]
                  [THEME
                  ]
                ]
              ]
            ]
          ]
        ]
      ]
    ]
  ]
\end{forest}
\begin{forest}
  nice tree
  [
    [
      [
        [A
        ]
        [
        ]
      ]
      [
      ]
    ]
    [
      [
      ]
      [
        [
        ]
        [B
        ]
      ]
    ]
  ]
\end{forest}
\end{document}
1

An alternative via tikz

enter image description here

Code

\documentclass[border=10pt]{standalone}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
 [
% Children and edges style
    edge from parent/.style={very thick,draw=black!70},
    level 1/.style={sibling distance=5.5cm, growth parent anchor=south,},
    level 2/.style={sibling distance=3.5cm},
    level 3/.style={sibling distance=3.5cm},
    level 4/.style={sibling distance=3.5cm}
    ]
%% Draw events and edges
 \node (g1) [] {S}
            child{node (e1) {NP}  % left branch
                child {node (e11) {Det}
                          child[level distance=3.25cm]{node{The}}}
                child {node (e13) {N}
                          child[level distance=3.25cm]{node{Man}}}
                    }
            child {node (e2) {VP} % right branch
                      child {node (e21) {V}
                          child[level distance=3.25cm]{node( ){captured}}
                           }
                     child {node (e32) {NP}
                          child {node (e11) {Det}  child{node(a){a}}}
                          child {node (e13) {N}    child{node(b) {bird}}}
}
};  
\end{tikzpicture}
  • 1
    I think that the lines joining the children of a particular node need to start from a single point under the node to make a kind of upside down 'V' shape. But I might be wrong about this - just that seems to be a common feature of these diagrams. – cfr Jan 7 '15 at 1:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.