Align levels in a tree using tikz-qtree

I'd like all levels in my tree diagram to be aligned vertically. The problem is that some branches 'skip' a level. Specifically, all x's and all C's should be next to each other (the rest is fine as it is). I managed to to this for the x's by specifying the distance from the root. But the C's are all over the place.

\documentclass[12pt]{beamer}
\usepackage{tikz}
\usepackage{tikz-qtree}

\begin{document}
\begin{frame}
\begin{tikzpicture}
\tikzset{frontier/.style={distance from root=150pt}}
\Tree   [.{\textbf{W}}
[.{\textbf{S}}
[.\textit{Onset} [.C {\textit{xx}} ]
[.C {\textit{x}} ] ]
[.\textit{Reim}
[.\textit{Nukleus}  [.C {\textit{x}} ]
[.C {\textit{x}} ] ]
[.\textit{Koda}         {C} ] ] ]
[.{\textbf{S}}
[.\textit{Onset} [.C {\textit{x}} ] ]
[.\textit{Reim }
[.\textit{Nukleus} [.C {\textit{x}} ] ]
[.\textit{Koda} {C} {C} ] ] ]
]
\end{tikzpicture}
\end{frame}
\end{document}


with your code i obtain the following image:

• i took liberty and add to your question the image generated by your code (on my computer). do you like that C below Onset is at the same level as are C below Nukleus? welcome to tex.se! Feb 9, 2018 at 13:24
• Thank you for the image, Zarko. I would like the C below Onset moved down to the same level as the C below Nukleus (as you said). I would also like the C below Koda at the same level (moved up).
– Max
Feb 9, 2018 at 13:26
• This would be easiest with Forest, but you'd have to change the way you specify the tree slightly. Then you can just say before typesetting nodes={where content={C}{tier=c, font=\upshape}{font=\itshape, if content={x}{tier=x}{}}} in the tree's preamble. (And drop the explicit \textits.
– cfr
Feb 9, 2018 at 16:55

I agree with cfr that forest is the way to go for this kind of tree, but if you have a lot of them and you don't mind some branches looking a bit odd you could simply add extra brackets around the nodes that are at the wrong level.

\documentclass[12pt]{beamer}
\usepackage{tikz}
\usepackage{tikz-qtree}
\tikzset{every tree node/.style={font=\itshape}}

\begin{document}
\begin{frame}
\begin{tikzpicture}
\tikzset{frontier/.style={distance from root=150pt}}
\Tree   [.{\textbf{\upshape W}}
[.{\textbf{\upshape S}}
[.Onset  [[.C {xx} ]]
[[.C {x} ]] ]
[.Reim
[.Nukleus  [.C {x} ]
[.C {x} ] ]
[.Koda       [.C  {x} ] ] ] ]
[.{\textbf{\upshape S}}
[.Onset [[.C {x} ]] ]
[.Reim
[.Nukleus [.C {x} ] ]
[.Koda [.C {x} ] [.C {x} ] ] ] ]
]
\end{tikzpicture}
\end{frame}
\end{document}


The extra x nodes I added to the tree don't affect the placement of the Cs. You can still align the C nodes and the x nodes even with missing x nodes:

\documentclass[12pt]{beamer}
\usepackage{tikz}
\usepackage{tikz-qtree}
\tikzset{every tree node/.style={font=\itshape}}

\begin{document}
\begin{frame}
\begin{tikzpicture}
\tikzset{frontier/.style={distance from root=150pt}}
\Tree   [.{\textbf{\upshape W}}
[.{\textbf{\upshape S}}
[.Onset  [[.C {xx} ]]
[[.C {x} ]] ]
[.Reim
[.Nukleus  [.C {x} ]
[.C {x} ] ]
[.Koda       [.C   ] ] ] ]
[.{\textbf{\upshape S}}
[.Onset [[.C {x} ]] ]
[.Reim
[.Nukleus [.C {x} ] ]
[.Koda [.C  ] [.C  ] ] ] ]
]
\end{tikzpicture}
\end{frame}
\end{document}


• Thanks, this looks like what I wanted. It's much more elegant than my own solution. I don't mind the odd looking branches under the first Onset, and I'm happy that I don't have to use another package.
– Max
Feb 10, 2018 at 17:45
• I'm glad it helped. In the longer term, though, it's probably a good idea to consider switching to forest. I was a big tikz-qtree fan but now do all my trees with forest. Feb 10, 2018 at 17:46
• Has rather more 'x's than the original, doesn't it? ;)
– cfr
Feb 11, 2018 at 0:56
• If you don't draw the odd-looking edges, could you add non-odd-looking ones by hand? @Max
– cfr
Feb 11, 2018 at 0:58
• @cfr Yes, of course you could. This is more or less what I did in my own solution. This obviously adds a bunch of work that needs to put into the whole thing, which gets tedious quickly. Also: You're right about this tree having more x's than the initial one - if you delete the ones I don't want, the solution doesn't work, which is a shame.
– Max
Feb 11, 2018 at 9:04

Since nobody has yet answered, here's a Forest version:

\documentclass[border=10pt]{standalone}
\usepackage[linguistics]{forest}
\begin{document}
\begin{forest}
before typesetting nodes={
where level<=1{font=\bfseries}{if content={C}{tier=c}{font=\itshape, if content={x}{tier=x}{}},}
},
[W
[S
[Onset
[C[xx]][C[x]]
]
[Reim
[Nukleus
[C[x]] [C[x]]
]
[Koda
[C]
]
]
]
[S
[Onset
[C[x]]
]
[Reim
[Nukleus
[C[x]]
]
[Koda
[C][C]
]
]
]
]
\end{forest}
\end{document}


The nice thing about this, of course, is that Forest does all the work: no need to hard-code distances or change them if the content or structure of the tree is modified later.

• i wait on your forest solution :-). my search in tikz-qtree manual doesn't give me a hope, that such image is possible to draw with it . (+1) Feb 10, 2018 at 4:58

After some trial and error I've just settled on specifying nodes and then moving each node individually. This is a bit tedious and I'll have to do it for every individual tree, so if someone has a better solution, please tell me.

Here's the code:

\documentclass[12pt]{beamer}
\usepackage{tikz}
\usepackage{tikz-qtree}

\begin{document}
\begin{frame}
\begin{tikzpicture}
\tikzset{frontier/.style={distance from root=150pt}}
\Tree   [.{\textbf{W}}
[.{\textbf{S}}
[.\textit{Onset} [.\node at (0,-1.1) {C}; {\textit{xx}} ]
[.\node at (0,-1.1) {C}; {\textit{x}} ] ]
[.\textit{Reim}
[.\textit{Nukleus}  [.C {\textit{x}} ]
[.C {\textit{x}} ] ]
[.\textit{Koda}         \node at (0,1) {C}; ] ] ]
[.{\textbf{S}}
[.\textit{Onset} [.\node at (0,-1.1) {C}; {\textit{x}} ] ]
[.\textit{Reim }
[.\textit{Nukleus} [.C {\textit{x}} ] ]
[.\textit{Koda} \node at (0,1.1) {C}; \node at (0,1.1) {C}; ] ] ]
]
\end{tikzpicture}
\end{frame}
\end{document}


Which gives me the desired result:

• Since the majority of your nodes are \itshape it would save you a lot of markup to add \tikzset{every tree node/.style={font=\itshape}} and then simply add \upshape inside the bolded nodes. Then you don't need to add \textit to every node. Feb 10, 2018 at 16:53
• Well, you've seen at least two better solutions, so I'm not clear what you're hoping people to come up with here.
– cfr
Feb 11, 2018 at 0:58
• @cfr I saw one better solution by the time I posted this, which used a package that I didn't want to use. The solution I accepted was posted later, but it isn't perfect either (see my recent comment on there).
– Max
Feb 11, 2018 at 9:08
• That's why we're telling you that Forest is the way to go here. I mean, not just me, but also @AlanMunn said as much. Either you have to do more tedious stuff yourself or you have to use a package which does (most) of that tedious stuff for you. Alan provided a solution of the first kind; I provided one of the second. I day say there will soon be an istgame solution, too, although its syntax is much less similar to what you're using now than Forest's.
– cfr
Feb 11, 2018 at 23:06
• @cfr Yes and I appreciate your solution, although it's not what I'm looking for, because I don't want to get into a new package at the moment. I'll have a look at forest when I have the time. The modifications that @AlanMunn made to his solution are spot on, exactly what I was looking for. They also avoid the tedious stuff that I thought was necessary in my own solution. I'm happy that he could get rid of that within the package that I've been working with. (His solution is also immediately applicable to other trees of the same sort (which don't only contain C's and x's), which is nice too.)
– Max
Feb 12, 2018 at 6:21