Equation with tikzpictures as l/rhs

I would like to write equations where the left and right hand side are obtained from tikzpictures.

I have the following for now, but is there a simpler way to do so ?

\tikzset{
link/.style    = { white, double = black, line width = 1.8pt,
double distance = 0.8pt },
channel/.style = { white, double = black, line width = 0.8pt,
double distance = 0.6pt },
nat/.style     = {fill=white,draw,circle,minimum size=0.5cm,inner sep=1pt},
}
\begin{tikzpicture}
\node at (-2,0) {$\begin{tikzpicture}[scale=0.5, transform shape] \coordinate (v1) at (0,4) {}; \coordinate(v2) at (0,0) {}; \coordinate (v3) at (-3,4) {}; \coordinate (v4) at (-3,0) {}; \coordinate (v5) at (3,4) {}; \coordinate (v6) at (3,0) {}; \fill[fill=blue!20] (v4.center) -- (v3.center) -- (v1.center) -- (v2.center) -- cycle; \fill[fill=yellow!10] (v1.center) -- (v5.center) -- (v6.center) -- (v2.center); \draw (v1) edge (v2); \draw (v1) node[above,scale=2] {$y$}; \draw (v2) node[below,scale=2] {$y$}; \draw (-1.5,0) node[below,scale=2]{$m$}; \coordinate (mor) at (0,3) {}; \coordinate (nat) at (0,1.5) {}; \draw (0,1.5) .. controls (-1,1.5) and (-1.5,1) .. (-1.5,0); \node[nat,scale=2] at (nat) {$a$}; \node[nat,scale=2] at (mor) {$f$}; \end{tikzpicture}$};
\node at (3,0) {$\begin{tikzpicture}[scale=0.5, transform shape] \coordinate (v1) at (0,4) {}; \coordinate (v2) at (0,0) {}; \coordinate (v3) at (-3,4) {}; \coordinate (v4) at (-3,0) {}; \coordinate (v5) at (3,4) {}; \coordinate (v6) at (3,0) {}; \fill[fill=blue!20] (v4.center) -- (v3.center) -- (v1.center) -- (v2.center) -- cycle; \fill[fill=yellow!10] (v1.center) -- (v5.center) -- (v6.center) -- (v2.center); \draw (v1) edge (v2); \draw (v1) node[above,scale=2] {$y$}; \draw (v2) node[below,scale=2] {$x$}; \draw (-1.5,0) node[below,scale=2]{$n$}; \coordinate (mor) at (0,1.5) {}; \coordinate (nat) at (0,3) {}; \draw (nat) .. controls ++(-1,0) and (-1.5,1) .. (-1.5,0); \node[nat,scale=2] at (nat) {$b$}; \node[nat,scale=2] at (mor) {$f$}; \end{tikzpicture}$};
\draw (0,0) node{$=$};
\end{tikzpicture}


If you want a parametric version, I have created a pic with 6 args: the 5 labels plus lownode/upnode for the starting point of the bending curve.

Remember that it's better not to nest tikzpictures.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{array}
\usepackage{tikz}
\usetikzlibrary{decorations.markings,positioning}

\begin{document}
\tikzset{%
nat/.style     = {fill=white,draw,circle,minimum size=0.5cm,inner sep=1pt},
pics/myeq/.style args={#1/#2/#3/#4/#5/#6}{code={%
\path[fill=blue!20] (0,0) rectangle (1.5,2);
\path[fill=yellow!10] (1.5,2) rectangle (3,0);
\draw[postaction={decorate,decoration={markings,
mark=at position 0.25 with {\node[nat] (upnode) {#2};},
mark=at position 0.60 with {\node[nat] (lownode) {#3};},
}}] (1.5,2) coordinate [label=above:{#1}] {} --
(1.5,0) coordinate [label=below:{#4}] {};
\coordinate[label=below:{#5}] (bordernode) at (.75,0);
\draw (#6) to[bend right] (bordernode);
}},
}
\begin{tabular}{m{3cm}>{\centering\arraybackslash}m{1cm}m{3cm}}
\begin{tikzpicture}
\pic {myeq={$y$/$f$/$a$/$y$/$m$/lownode}};
\end{tikzpicture} &
$=$ &
\begin{tikzpicture}
\pic {myeq={$y$/$b$/$f$/$x$/$n$/upnode}};
\end{tikzpicture} \\
\end{tabular}
\end{document}


• Awesome technique ! I want to to let you know I applied the pic with args I learnt from your answer here. Please check it out ! (I ping you here because I don't know if it works in answers body...) – marsupilam Jun 18 '17 at 22:32
• great technique, thanks for sharing. also tabular scales to more 2 sides. – nicolas Jun 18 '17 at 22:39
• @nicolas You're welcome, thank you for accepting my answer! – CarLaTeX Jun 19 '17 at 1:20

I would do it like this, without a surrounding tikzpicture.

Basically

• define \leftHandSide \rightHandSide commands for your two drawings
• then write \leftHandSide{}={}\rightHandSide in your document
(or as a node in a tikzpicture if needed)

If you do not like

• the vertical alignment, you can adjust the (myNode) in the \commonCommands referenced through baseline=(myNode).
• the horizontal alignment, you can adjust adding hspace on both sides of the = or by adding padding to your tikzpictures.

\def\padding{5cm}


The code

I changed the yellow to a fuller tone, as I had trouble even seeing it.

\documentclass[12pt, border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\tikzset{
link/.style         = { white, double = black, line width = 1.8pt,
double distance = 0.8pt },
channel/.style      = { white, double = black, line width = 0.8pt,
double distance = 0.6pt },
nat/.style          = {fill=white,draw,circle,minimum size=0.5cm,inner sep=1pt},
blue area/.style    = {fill=blue!30},
yellow area/.style  = {fill=yellow!30},
}
\newcommand\commonCommands
{
\coordinate (v1) at (0,4) {};
\coordinate(v2) at (0,0) {};
\coordinate (v3) at (-3,4) {};
\coordinate (v4) at (-3,0) {};
\coordinate (v5) at (3,4) {};
\coordinate (v6) at (3,0) {};
\fill[blue area] (v4) -- (v3) -- (v1) -- (v2) -- cycle;
\fill[yellow area] (v1) -- (v5) -- (v6) -- (v2);
\draw  (v1) edge (v2);
\coordinate (myNode) at ($(v1)!.52!(v2)$) ;
}

\newcommand\leftHandSide
{
\begin{tikzpicture}[scale=0.5, transform shape, baseline=(myNode)]
\commonCommands
\draw (v1) node[above,scale=2] {$y$};
\draw (v2) node[below,scale=2] {$y$};
\draw (-1.5,0) node[below,scale=2]{$m$};
\coordinate (mor) at (0,3) {};
\coordinate (nat) at (0,1.5) {};
\draw (0,1.5) .. controls (-1,1.5) and (-1.5,1) .. (-1.5,0);
\node[nat,scale=2] at (nat) {$a$};
\node[nat,scale=2] at (mor) {$f$};
\end{tikzpicture}
}

\newcommand\rightHandSide
{
\begin{tikzpicture}[scale=0.5, transform shape, baseline=(myNode)]
\commonCommands
\draw (v1) node[above,scale=2] {$y$};
\draw (v2) node[below,scale=2] {$x$};
\draw (-1.5,0) node[below,scale=2]{$n$};
\coordinate (mor) at (0,1.5) {};
\coordinate (nat) at (0,3) {};
\draw (nat) .. controls ++(-1,0) and (-1.5,1) .. (-1.5,0);
\node[nat,scale=2] at (nat) {$b$};
\node[nat,scale=2] at (mor) {$f$};
\end{tikzpicture}
}

\leftHandSide{}={}\rightHandSide

\end{document}

• interesting use of \newcommand. I would be wary of polluting the namespace but braces {} might scope them. – nicolas Jun 19 '17 at 7:56

You can certainly do it with a lot less code. I would also set it as an equation, with one tikzpicture on each side of an =, you just need baseline to align it vertically. You could also make macros, as in marsupilam's answer, but I haven't done that here. It could also be made a bit more flexible, but unless you're going to make a lot of very similar ones, that might not be necessary.

\documentclass{article}
\usepackage{tikz}
\tikzset{
nat/.style     = {fill=white,draw,circle,minimum size=0.5cm,inner sep=1pt},
}
\begin{document}
$\begin{tikzpicture}[baseline={(0,1)}] \fill[blue!20] (0.5,0) rectangle (2,2); \fill[yellow!50] (2,0) rectangle (3.5,2); \draw (2,0) -- (2,2) node[pos=0,below] {y} node[pos=0.4,nat] (a) {a} node[pos=0.8,nat] {f} node[pos=1,above] {y}; \draw (1.25,0) node[below] {m} to[bend left] (a); \end{tikzpicture} = \begin{tikzpicture}[baseline={(0,1)}] \fill[blue!20] (0.5,0) rectangle (2,2); \fill[yellow!50] (2,0) rectangle (3.5,2); \draw (2,0) -- (2,2) node[pos=0,below] {x} node[pos=0.4,nat] {f} node[pos=0.8,nat] (b) {b} node[pos=1,above] {y}; \draw (1.25,0) node[below] {n} to[bend left=20] (b); \end{tikzpicture}$
\end{document}

• That's some serious cleaning ! just got to learn tikz yesterday, thank you for the rewrite, it provides some nice nuggets. out of curiosity, how long did it take you to rewrite ? – nicolas Jun 18 '17 at 22:35
• @nicolas Hard to say, I never keep track of such things. Something like 10 minutes perhaps, give or take a bit. – Torbjørn T. Jun 19 '17 at 6:40