# Vertically-centering multiple TikZ pictures, preserving baseline height

I've often need to write out equations between pictures, which are drawn using TikZ. However, to display them properly, I have two requirements: any common features must be on the same horizontal line, and the diagrams as a whole must be vertically centered with respect to any = signs separating them.

Here's a picture of the effect I want: Here's a picture of the effect I don't want, but which is easily achieved:

Of course, for a particular diagram, it's just a couple of lines of code to get the effect I want. But ideally, I'd specify the position of the labels - perhaps by setting the baseline of the diagrams to the label A - and then the rest should happen automatically.

There are many ways I can achieve this manually: for example, increasing the size of the bounding box for the smaller diagram to artificially force it to have the same height as the larger one; or manually setting the baseline of the images to exactly the point which I want aligned with the baseline of the = sign. But both of these are fiddly, and none are robust against future changes of the diagrams.

Here's the code to produce the second image above:

\documentclass{article}
\usepackage{tikz}
\usepackage{amsmath}
\begin{document}
\begin{aligned} \begin{tikzpicture} \draw (0,0) node [above] {A} to [out=down, in=down] (1,0) node [above] {A^*}; \end{tikzpicture} \end{aligned} = \begin{aligned} \begin{tikzpicture} \draw (0,0) node [above] {A} to [out=down, in=up] (1,-1) to [out=down, in=down] (0,-1) to [out=up, in=down] (1,0) node [above] {A^*}; \end{tikzpicture} \end{aligned}
\end{document}

-

Another try. My basic idea is to have a list of the whole equation, then to map over that list so that the tikz pictures are \vcentered to the tallest of the bunch, while the normal mathematical objects are passed as-is. Please note that I haven't tested this (much):

\catcode@=11
\input lambda.sty
\input tikz

\def\Unravel#1{#1\Unravel@{}}
\def\Unravel@#1{#1\Foldr\Spaceize{}}
\def\Spaceize#1#2{ #1#2}

\newdimen\tallest
\newcount\index

\def\TypesetThem#1{%
\TeXif{\ifodd\index }{\vcenter to\tallest{\hbox{$#1$}\vss}}{#1}}

\def\FindTallest#1{%
\setbox0\vbox{\hbox{$#1$}}%
\ifdim\dimexpr\ht0+\dp0>\tallest\tallest=\dimexpr\ht0+\dp0\fi}

\def\SameHeight#1{%
\index=0
\tallest=0pt
\Unravel{\Map\FindTallest{#1}}
\Unravel{\Map\TypesetThem{#1}}}

\def\MyTikZList{\Listize[
{\tikz\draw (0,0)
node[above] {$A$}
to[out=down,in=down] (1,0)
node[above] {$A^*$};},
=,
{\tikz\draw (0,0)
node[above] {$A$}
to[out=down,in=up] (1,-1)
to[out=down,in=down] (0,-1)
to[out=up,in=down] (1,0)
node[above] {$A^*$};},
+,
{\tikz\draw (0,0)
node[above] {$A$}
to[out=down,in=up] (1,-1)
to[out=down,in=down] (0,-1)
to[out=up,in=down] (1,0)
node[above] {$A^*$};},
-,
{\tikz\draw (0,0)
node[above] {$A$}
to[out=down,in=down] (1,0)
node[above] {$A^*$};},
]}

$$\SameHeight\MyTikZList$$

\bye


The tikz pictures needed to be grouped.

-
Hi @morbusg, thanks for your suggestion. Unfortunately, that's not what I want. As I showed in the example image, the = sign has to be at the centre of the tallest image. –  Jamie Vicary Feb 2 '12 at 16:17
Thanks for your update. All these ideas work - as I say in the question, the difficulty isn't finding some way to do this. The difficulty is finding a way to do it which doesn't require specifying more than the logically minimal amount of information. In particular, I will be editing these pictures, and I don't want to have to change any auxiliary elements which are just put in place to make it align correctly. Your solution fails this test - if I change the height of the right-hand picture, I have to move my extra invisible coordinate. –  Jamie Vicary Feb 2 '12 at 17:40
@Jamie: When all else fails: \box it ;-) –  morbusg Feb 2 '12 at 18:04
Hi morbusg. Can you help me unpack your latest suggestion? How does it know to align them correctly with respect to one another? –  Jamie Vicary Feb 2 '12 at 18:08
@Jamie: ah, of course! I'm sorry, I'll add information. –  morbusg Feb 2 '12 at 18:11

This is not the optimal solution but required manual adjustment is not so much.

\documentclass{article}
\usepackage{tikz}
\usepackage{amsmath}
\usetikzlibrary{calc}
\begin{document}

An entangled equation and required meaningless text just to justify this sentence length.
$$\begin{tikzpicture}[baseline=(current bounding box.center)] \node (A) at (0,0) {\tikz{\draw (0,0) node [above] {A} to [out=down, in=down] (1,0) node [above] {A^*};}}; \node[anchor=north west] (B) at ((A.north east)+(1em,0)) { \tikz{\draw (0,0) node [above] {A} to [out=down, in=up] (1,-1) to [out=down, in=down] (0,-1) to [out=up, in=down] (1,0) node [above] {A^*}; } }; \node[left] (equa) at (B.west) {=}; \end{tikzpicture}$$
\end{document}


Basically you draw two distinct sides of the equation via nodes and then align them from their top limit and squeeze an equal sign in between.

-
It took quite longer than a minute,sorry :) –  percusse Feb 2 '12 at 20:49
Thanks percusse! An interesting solution. But still less automatic than I would like, as you say. In particular, if I edited the left diagram so that it became taller than the right diagram, the placement code would again need re-editing. –  Jamie Vicary Feb 2 '12 at 23:00
@JamieVicary Not necessarily, you only need to change (B.west) to (A.east)` in the last line –  percusse Feb 3 '12 at 13:06
Right - that's what I mean about "re-editing"! –  Jamie Vicary Feb 3 '12 at 14:53