1

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 ? enter image description here

\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}
6

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}

enter image description here

  • 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
4

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.

One way to add padding is to simply

\def\padding{5cm}
\path (-\padding,0) -- (\padding,0) ;

The output

enter image description here

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);
      \def\padding{0cm}
      \path (-\padding,0) -- (\padding,0) ;
      \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
3

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.

enter image description here

\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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.