7

I am starting to learn TikZ and my goal is to draw the following image.

Goal

What I got until now with the following code:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{shapes.arrows}
\usepackage{array}
\begin{document}
\begin{tikzpicture} [
auto,
ff/.style    = { rectangle, draw=black, thick, 
    fill=ff_color, text width=10em, text centered,
    rounded corners, minimum height=4.5em },
embed/.style    = { rectangle, draw=black, thick, 
    fill=emb_color, text width=10em, text centered,
    rounded corners, minimum height=2em },
four/.style    = { rectangle, draw=black, thick, 
    fill=fourier_color, text width=10em, text centered,
    rounded corners, minimum height=4.5em },
addnorm/.style    = { rectangle, draw=black, thick, 
    fill=add_norm_color, text width=10em, text centered,
    rounded corners, minimum height=2em },
den/.style    = { rectangle, draw=black, thick, 
    fill=dense_color, text width=10em, text centered,
    rounded corners, minimum height=2em },
outp/.style    = { rectangle, draw=black, thick, 
    fill=output_color, text width=10em, text centered,
    rounded corners, minimum height=2em },
line/.style     = { draw, thick, ->, shorten >=0pt },
]
\definecolor{gray_bbox_color}{RGB}{243,243,244}
\definecolor{emb_color}{RGB}{252,224,225}
\definecolor{fourier_color}{RGB}{252,226,187}
\definecolor{add_norm_color}{RGB}{242,243,193}
\definecolor{ff_color}{RGB}{194,232,247}
\definecolor{output_color}{RGB}{203,231,207}
\definecolor{dense_color}{RGB}{220,223,240}


\draw[fill=gray_bbox_color, line width=0.03cm, rounded corners=0.300000cm] 
(-3.5, 3.35)        -- 
(2.725000, 3.35)  -- 
(2.725000, -4.0)  -- 
(-3.5, -4.0) -- 
cycle;

% Define nodes in a matrix
\matrix [column sep=1mm, row sep=5mm] {
    & \node [text centered] (output) {Output};         & \\
    & \node [outp] (output_proj) {Output Projection};  & \\
    & \node [den] (dense) {Dense};                     & \\
    & \node [addnorm] (add2) {Add \& Normalize};       & \\
    & \node [ff] (ff) {Feed Forward};                  & \\
    & \node (null2) {};                                & \\
    & \node [addnorm] (add) {Add \& Normalize};        & \\
    & \node [four] (fourier) {Fourier};                & \\
    & \node (null1) {};                                & \\
    & \node [embed] (embeddings) {Embeddings};         & \\
    & \node [text centered] (input) {Input};           & \\
};
% connect all nodes defined above
\begin{scope} [every path/.style=line]
\path (output_proj) --  (output);
\path (dense)       --  (output_proj);
\path (add2)        --  (dense);
\path (ff)          --  (add2);
\path (add)         --  (ff);
\path (null2)       --++  (-3,0) |- (add2);
\path (fourier)     --  (add);
\path (embeddings)  --  (fourier);
\path (null1)       --++  (-3,0) |- (add);
\path (input)       --  (embeddings);
\end{scope}
%
\end{tikzpicture}
\end{document}

The compiled image:

enter image description here

Can you help me understand how to put the "N x" missing and how to insert the box with Word, Position and Type that are missing? Also, if you have tips on how to improve the code, etc. I'd really appreciate the help. Thank you.

1
  • Strange idea to use a matrix of nodes when you only have a chain. Anyway, tha gray box around those nods would be better using fit library and drawn on the background (using backgrounds library), then you would just put a label on the left of this fit node. The last part could be done the same way.
    – SebGlav
    May 24, 2021 at 21:06

2 Answers 2

12

So, in order not to re-write everything, I decided to keep your original structure, even if I think matrix of nodes is not the fittest way to do that.
I used fit, backgrounds and of course positionning libraries.

whatever you call this

\documentclass[tikz,border=3.14mm]{standalone}

\usetikzlibrary{shapes.geometric,shapes.arrows,fit,backgrounds,positioning}
\usepackage{array}

\begin{document}
\begin{tikzpicture} [
ff/.style    = { rectangle, draw=black, thick, 
    fill=ff_color, text width=10em, text centered,
    rounded corners, minimum height=4.5em },
embeddings/.style    = { rectangle, draw=black, thick, 
    fill=embeddings_color,
    rounded corners, minimum height=2em },
embed/.style    = { rectangle, draw=black, thick, 
    fill=emb_color, text width=4em, text centered,
    rounded corners, minimum height=2em },
four/.style    = { rectangle, draw=black, thick, 
    fill=fourier_color, text width=10em, text centered,
    rounded corners, minimum height=4.5em },
addnorm/.style    = { rectangle, draw=black, thick, 
    fill=add_norm_color, text width=10em, text centered,
    rounded corners, minimum height=2em },
den/.style    = { rectangle, draw=black, thick, 
    fill=dense_color, text width=10em, text centered,
    rounded corners, minimum height=2em },
outp/.style    = { rectangle, draw=black, thick, 
    fill=output_color, text width=10em, text centered,
    rounded corners, minimum height=2em },
line/.style     = { draw, thick, ->, shorten >=0pt },
]
\definecolor{gray_bbox_color}{RGB}{243,243,244}
\definecolor{emb_color}{RGB}{252,224,225}
\definecolor{embeddings_color}{RGB}{232,204,205}
\definecolor{fourier_color}{RGB}{252,226,187}
\definecolor{add_norm_color}{RGB}{242,243,193}
\definecolor{ff_color}{RGB}{194,232,247}
\definecolor{output_color}{RGB}{203,231,207}
\definecolor{dense_color}{RGB}{220,223,240}


% Define nodes in a matrix
\matrix [column sep=1mm, row sep=5mm] {
    & \node [text centered] (output) {Output};         & \\
    & \node [outp] (output_proj) {Output Projection};  & \\
    & \node [den] (dense) {Dense};                     & \\
    & \node [addnorm] (add2) {Add \& Normalize};       & \\
    & \node [ff] (ff) {Feed Forward};                  & \\
    & \coordinate (null2);                                & \\
    & \node [addnorm] (add) {Add \& Normalize};        & \\
    & \node [four] (fourier) {Fourier};                & \\
    & \coordinate (null1);                                & \\
};

%


\node[below = 1cm of fourier] (embeddings) {Embeddings};
\node[below = 0mm of embeddings,embed] (position) {Position};
\node[left = 7mm of position,embed] (word) {Word};
\node[right = 7mm of position,embed] (type) {Type};
\path (word) -- (position) node [midway]{+} -- (type) node [midway]{+};


\begin{pgfonlayer}{background}
    \node[fit=(embeddings)(word)(type),embeddings](embed){};
    \coordinate (N1) at (embed.west|-fourier);
    \coordinate (N2) at (embed.east|-fourier);
    \node[inner xsep=0pt,inner ysep=8pt,fit=(add2)(fourier)(N1)(N2),fill=gray_bbox_color, line width=0.03cm,draw, rounded corners=0.3cm,label=left:$N_x$]{};
\end{pgfonlayer}

\node[below= 5mm of embed](input){Input};

% connect all nodes defined above
\begin{scope} [every path/.style=line]
\path (output_proj) --  (output);
\path (dense)       --  (output_proj);
\path (add2)        --  (dense);
\path (ff)          --  (add2);
\path (add)         --  (ff);
\path (null2)       --++  (-3,0) |- (add2);
\path (fourier)     --  (add);
\path (embed)  --  (fourier) coordinate[midway](null1) ;
\path (null1)  --++  (-3,0) |- (add);
\path (input) -- (embed);
\end{scope}


\end{tikzpicture}
\end{document}

There are so much thing that can be improved but you sure are on the right path to learn TikZ. Welcome to the club!

3
  • 1
    Hi, thank you, this is fantastic. I will look into that to learn more. How would you rewrite that? I mean, if you can say things I should look up, no need for actually rewriting it. Thank you again. May 25, 2021 at 8:21
  • 1
    Like I said, a simple chain for the principal nodes would do it great (see Zarko's answer to get the idea), then, for the embeddings part, what i did is ok. It's always good to try an rewrite differently something you came up with, just to learn.
    – SebGlav
    May 25, 2021 at 16:36
  • Cool, thank you! May 26, 2021 at 6:37
7
  • Points where loops start had to be defined as coordinates or as nodes with zero inner sep.
  • Your flowchart has simple structure: all nodes and coordinates are in single chain, so you may consider to use TikZ libraries backgrounds, chains, fit and positioning in drawing it:
\documentclass[border=3.141592]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,
                backgrounds,
                chains,
                fit,
                positioning,
                shapes.geometric}
\makeatletter
\tikzset{suppress join/.code={\def\tikz@after@path{}}}
\makeatother

\begin{document}
    \begin{tikzpicture}[
node distance = 4mm and 8mm,
  start chain = A going below,
   arr/.style = {Straight Barb-}, 
   box/.style = {draw, rounded corners, semithick, fill=#1,
                 text width=10em, text depth=0.5ex, align=center,
                 inner sep=1ex},
   FIT/.style = {box=gray!10, inner xsep=2em, fit=#1}
                       ]     
% nodes
    \begin{scope}[nodes={on chain=A, join=by arr}]      
\node   {Output};                                   % A-1
\node [box=olive!30]        {Output Projection};    
\node [box=gray!15!blue!15] {Dense}; 
\node [box=yellow!30]       {Add \& Normalize};     % A-4
\node [box=cyan!30]         {Feed Forward};         % A-5
\coordinate (aux1);                                 %  A-6
\node [box=yellow!30,
       suppress join]       {Add \& Normalize};     % A-7
\node [box=orange=30, 
       inner ysep=3ex]      {Fourier};              % A-8
\coordinate (aux2);                                 % A-9
\node [box=red!30,
       suppress join]       {Embeddings};           % A-10        
\node   {Input};
    \end{scope}
% background node
\scoped[on background layer]
    \node[FIT=(A-4) (A-9)] {};
% connections not considered in join macro
\draw   (A-10) -- (aux2)
        (A-7)  -- (aux1);
\draw[arr] (A-4) -|  ([xshift=-1em] A-5.west) |- (aux1);
\draw[arr] (A-7) -|  ([xshift=-1em] A-8.west) |- (aux2);
    \end{tikzpicture}
\end{document}

enter image description here

1
  • Thank you. I will definitely look into you code to learn more about TikZ. May 25, 2021 at 8:25

You must log in to answer this question.

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