# Visualization of aligned text columns

This question is equally on graphic design as it is on an efficient implementation via LaTeX.

I would like to visualize several aligned string columns. These columns are to be read from top to bottom and may occasionally contain blank fields. The alignment must - obviously - not be broken, and the individual strings should remain readable.

COL1 COL2 COL3
foo  foo  foo
bar  bar  bar
baz       baz
qux  qux
quux quux


What would be an efficient way to visualize these columns in TEX?

Here is an example via ASCII, where the strings are boxed up and the boxes connected by vertical lines.

 ---      ---      ---
|foo|    |foo|    |foo|
---      ---      ---
|        |        |
---      ---      ---
|bar|    |bar|    |bar|
---      ---      ---
|        |        |
---       |       ---
|baz|      X      |baz|
---       |       ---
|        |        |
---      ---       |
|qux|    |qux|      X
---      ---       |
|        |        |
|       ---      ---
X      |quux|   |quux|
---      ---


Since you think of these as columns, I'm assuming you'd rather input your strings column by column rather than row by row. One way to do this is using the forest package:

\documentclass[tikz, border=5pt]{standalone}

\usepackage{forest}
\forestset{%
my columns/.style={%
for descendants={rectangle, draw},
for children={no edge},
phantom, s sep=1cm,
},
% Pick one of these styles
hidden empty nodes/.style={%
delay={%
where content={}{%
shape=coordinate,
}{},
},
},
x empty nodes/.style={%
delay={%
where content={}{%
content=\textsf{x}, draw=none
}{},
},
},
}
\begin{document}

\begin{forest} my columns, hidden empty nodes [
[foo [bar [baz [qux []]]]]
[foo [bar [ [qux [quxx]]]]]
[foo [bar [baz [ [quxx]]]]]
]
\end{forest}

\begin{forest} my columns, x empty nodes [
[foo [bar [baz [qux []]]]]
[foo [bar [ [qux [quxx]]]]]
[foo [bar [baz [ [quxx]]]]]
]
\end{forest}

\end{document}


Of course, forest seems like a bit of overkill in this situation, and leaves you with a slightly odd notation in the source...

EDIT: To make the empty nodes use bullets instead of xs, you can replace content=\textsf{x} with content=\textbullet. In this case you might want to also set inner sep=0 for empty nodes so that the line touches the bullet. On the other hand, it might be easier to just draw the node as a filled circle, as I've done in the example below.

To add column headers one option is to add a label to the first node in each column, like [foo, label={Col 1} [bar [baz [qux []]]]]. In this case you can control the distance between the header and the first node by setting, e.g., \tikzset{label distance=1em}. On the other hand, if you want to write the column header first you could just remove the box and edge from the first node in each column. The resulting code looks like

\documentclass[tikz, border=5pt]{standalone}

\usepackage{forest}
\forestset{%
my columns/.style={%
for descendants={
rectangle, draw,
anchor=center, % vertically align (empty) nodes at the middle
font=\strut, % make the box size independent of ascenders/descenders
l sep=0em, % make the level height independent of box height
},
for children={no edge,
draw=none, inner sep=0pt, outer sep=0pt, font={}, % style of column header
for children={no edge,
l=2em, % header distance (minimum 1em)
}
},
phantom, % hide the root node
s sep=1cm, % distance between columns
bullet empty nodes
},
bullet empty nodes/.style={%
delay={%
where content={}{%
circle, inner sep=.5mm, fill, font={}
% draw=none, content=\textbullet, font={}, inner sep=-1pt,
}{},
},
},
}
\begin{document}

\begin{forest} my columns [
[Col 1 [foo [bar [baz [qux []]]]]]
[Col 2 [foo [bar [ [qux [bar]]]]]]
[Col 3 [foo [bar [baz [ [quxx]]]]]]
]
\end{forest}

\end{document}


Here I've also added some things to make it so that ascenders and descenders (or lack thereof) don't change the heights of the boxes and so that the empty nodes add the same height to their columns as non-empty nodes (even though the empty node itself is smaller than a non-empty node).

• Excellent, this is exactly what I was looking for! However, I would need two minor adjustments that I cannot get to work: (a) How would I add column headers (i.e., COL1, COL2, COL3)? (b) I cannot replace the x denoting missing elements with a symbol, such as \bullet (i.e., content=\bullet, draw=none). – Michael G Nov 14 '16 at 11:12
• @MichaelGruenstaeudl I've edited the solution above to (hopefully) address these requests. – Emma Nov 15 '16 at 5:19

One possible way is to define a macro.

Code:

\documentclass{amsart}
\usepackage{etoolbox}
\newcommand{\example}[3] {
$\boxed{{\sim\text{#1}\sim}}$&$\boxed{{\sim\text{#2}\sim}}$&$\boxed{{\sim\text{#3}\sim}}$\\\|&\|&\|\\}
\newcommand{\finish}[3] {
$\boxed{{\sim\text{#1}\sim}}$&$\boxed{{\sim\text{#2}\sim}}$&$\boxed{{\sim\text{#3}\sim}}$}
\begin{document}
\Huge
\begin{tabular}{c c c}
COL1&COL2&COL3\\
\example{foo}{foo}{foo}
\example{bar}{bar}{bar}
\example{baz}{}{baz}
\example{qux}{qux}{}
\finish{}{quux}{quux}
\end{tabular}
\end{document}


This gives: