18

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: enter image description here Here's a picture of the effect I don't want, but which is easily achieved: enter image description here

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}

3 Answers 3

9

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{%
  \advance\index by 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.

enter image description here

9
  • 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. Feb 2, 2012 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. Feb 2, 2012 at 17:40
  • @Jamie: When all else fails: \box it ;-)
    – morbusg
    Feb 2, 2012 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? Feb 2, 2012 at 18:08
  • @Jamie: ah, of course! I'm sorry, I'll add information.
    – morbusg
    Feb 2, 2012 at 18:11
4

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{equation}
\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{equation}
\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.

enter image description here

4
  • It took quite longer than a minute,sorry :)
    – percusse
    Feb 2, 2012 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. Feb 2, 2012 at 23:00
  • @JamieVicary Not necessarily, you only need to change (B.west) to (A.east) in the last line
    – percusse
    Feb 3, 2012 at 13:06
  • Right - that's what I mean about "re-editing"! Feb 3, 2012 at 14:53
1

How about \raisebox{-\height/2}{<tikz code>}?

enter image description here

\begin{equation}
    \raisebox{-\height/2}{\begin{tikzpicture}
    \draw (0,0)
        node [above] {$A$}
        to [out=down, in=down] (1,0)
        node [above] {$A^*$};
    \end{tikzpicture}}
    = \raisebox{-\height/2}{\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{equation}

It's not exactly versatile, i.e. it doesn't allow alignment w.r.t. common features in different TikZ pictures but it certainly manages the vertical alignment (which might be all others stumbling upon this post are looking for).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .