# Vertical and angled arrows in flowchart using TikZ

I'm trying to recreate something similar to this flowchart using TikZ:

This is my code so far:

\begin{figure}[H]
\centering
\resizebox{0.99\textwidth}{!}{
\begin{tikzpicture}[node distance=2cm]
\node(first)[draw,rectangle]
{\shortstack{$\boldsymbol{M}^I = \boldsymbol{M}_s + \boldsymbol{M}_{h_0}$\\
$\boldsymbol{K}^I = \boldsymbol{K}_s + \boldsymbol{K}_h$}};
\node(second)[draw,rectangle,below of=first]
{\shortstack{$\boldsymbol{\Phi}^I$\\
$\omega_n^I$}};
\node(third)[draw,rectangle,below of=second]
{\shortstack{$\tilde{\boldsymbol{M}}^I$\\
$\tilde{\boldsymbol{K}}^I$\\
$\tilde{\boldsymbol{C}}^I = \alpha \tilde{\boldsymbol{M}}^I + \beta \tilde{\boldsymbol{K}}^I$}};
\node(fourth)[draw,rectangle,right of=first,xshift=4cm]
{\shortstack{$\boldsymbol{M}_i^{II}(\omega) = \boldsymbol{M}_{h,i}(\omega)$\\
$\boldsymbol{C}_i^{II}(\omega) = \boldsymbol{C}_{h,i}(\omega)$\\
$\boldsymbol{K}_i^{II} = \boldsymbol{K}_{h,i} - \boldsymbol{K}_{h,i} = \boldsymbol{0}$}};
\node(fifth)[draw,rectangle,below of=fourth]
{\shortstack{$\boldsymbol{M}^{II}(\omega) = \sum_{i=1}^7\boldsymbol{T}_i^T\boldsymbol{M}_i^{II}(\omega)\boldsymbol{T}_i$\\
$\boldsymbol{C}^{II}(\omega) = \sum_{i=1}^7\boldsymbol{T}_i^T\boldsymbol{C}_i^{II}(\omega)\boldsymbol{T}_i$}};
\node(sixth)[draw,rectangle,below of=fifth]
{\shortstack{$\tilde{\boldsymbol{M}}^{II}(\omega) = (\boldsymbol{\Phi}^I)^T\boldsymbol{M}^{II}(\omega)\boldsymbol{\Phi}^I$\\
$\tilde{\boldsymbol{C}}^{II}(\omega) = (\boldsymbol{\Phi}^I)^T\boldsymbol{C}^{II}(\omega)\boldsymbol{\Phi}^I$}};
\node(seventh)[draw,rectangle,below of=sixth]
{\shortstack{$\tilde{\boldsymbol{M}}(\omega) = \tilde{\boldsymbol{M}}^I + \tilde{\boldsymbol{M}}^{II}(\omega)$\\
$\tilde{\boldsymbol{C}}(\omega) = \tilde{\boldsymbol{C}}^I + \tilde{\boldsymbol{C}}^{II}(\omega)$\\
$\tilde{\boldsymbol{K}} = \tilde{\boldsymbol{K}}^I$}};
\node(eighth)[draw,rectangle,right of=fourth,xshift=5cm]
{\shortstack{$\boldsymbol{Q}_r(\omega, \theta)$}};
\node(ninth)[draw,rectangle,right of=eighth,xshift=2cm]
{\shortstack{$S_\eta(\omega,\theta) = S_\eta(\omega) D(\theta)$}};
\node(tenth)[draw,rectangle,below of=eighth,anchor=west]
{\shortstack{$\boldsymbol{S}_{p_rp_s}(\omega) = \int_\theta{\boldsymbol{Q}_r(\omega, \theta)}S_\eta(\omega, \theta)\boldsymbol{Q}_r(\omega, \theta)^H \; d\theta$}};
\node(eleventh)[draw,rectangle,below of=tenth]
{\shortstack{$\boldsymbol{S}_p(\omega) = \begin{bmatrix} \boldsymbol{S}_{p_1p_1}(\omega) & \cdots & \boldsymbol{S}_{p_1p_7}(\omega)\\ \vdots & \ddots & \vdots \\ \boldsymbol{S}_{p_7p_1}(\omega) & \cdots & \boldsymbol{S}_{p_7p_7}(\omega) \end{bmatrix}$}};
\node(twelfth)[draw,rectangle,below of=eleventh]
{\shortstack{$\tilde{\boldsymbol{S}}_p(\omega) = (\boldsymbol{\Phi}^I)^T\boldsymbol{S}_p(\omega)\boldsymbol{\Phi}^I$}};
\node(thirteenth)[draw,rectangle,below of=seventh,yshift=-1cm]
{\shortstack{$\tilde{\boldsymbol{S}}_u(\omega) = \tilde{\boldsymbol{H}}(\omega)\tilde{\boldsymbol{S}}_p(\omega)\tilde{\boldsymbol{H}}(\omega)^H$}};
\node(fourteenth)[draw,rectangle,below of=thirteenth]
{\shortstack{$\boldsymbol{S}_u(\omega) = \boldsymbol{\Phi}^I\tilde{\boldsymbol{S}}_u(\omega)(\boldsymbol{\Phi}^I)^T$}};
\node[rectangle,below of=seventh,anchor=west] {\shortstack{$\tilde{\boldsymbol{H}}(\omega)$}};
\draw[->,>=stealth] (first) -- (second);
\draw[->,>=stealth] (second) -- (third);
%\draw[->,>=stealth] (third) -- (seventh);
\draw[->,>=stealth] (fourth) -- (fifth);
\draw[->,>=stealth] (fifth) -- (sixth);
\draw[->,>=stealth] (sixth) -- (seventh);
\draw[->,>=stealth] (eighth) -- (tenth);
\draw[->,>=stealth] (ninth) -- (tenth);
\draw[->,>=stealth] (tenth) -- (eleventh);
\draw[->,>=stealth] (eleventh) -- (twelfth);
\draw[->,>=stealth] (seventh) -- (thirteenth);
\draw[->,>=stealth] (thirteenth) -- (fourteenth);
\end{tikzpicture}
}
\caption{Caption}
\label{fig:my_label}
\end{figure}


This results in the following:

I have two questions:

1. How should I get the rightmost "column" of nodes to have the same horizontal distance as the center "column" have relative to the leftmost "column"? Also, how to get the node arrows on the top right to point vertically down and not be inclined?

2. How can I get the 90 degree angled arrows as shown in the first screenshot?

These two points are the only ones I want to achieve. I do not want to recreate the colors or numbering from the first screenshot.

• How can I get the 90 degree angled arrows as shown in the first screenshot? If you know the start and end of the arrow, the synthax would be \draw[->] (startpoint coordintes) |- (endpoint coordintes) – Excelsior Apr 11 at 11:07
• How should I get the rightmost "column" of nodes to have the same horizontal distance as the center "column" have relative to the leftmost "column"? For this, you can have a look at \usetikzlibrary{calc}, where you can define the distance between nodes – Excelsior Apr 11 at 11:09
• Also, how to get the node arrows on the top right to point vertically down and not be inclined? Here, again, if you know the starting- and endpoint, you can draw a horizonal line easily. Maybe the pos option for the node you want to point add helps. – Excelsior Apr 11 at 11:11
• I can add an example for each topic in case you need some help ... – Excelsior Apr 11 at 11:13
• When typing \node(eighth)[draw,rectangle,right of=fourth,xshift=5cm] you already shifted the position of your third column. You can simply adjust your columns positions by modifying those xshift (even if it's not the best way to position everything in my opinion). – SebGlav Apr 11 at 11:30

As mentioned in the comments, one approach is to define nodes and shift them relative to each other, draw lines to specific points of the node, ...

Q1 How should I get the rightmost "column" of nodes to have the same horizontal distance as the center "column" have relative to the leftmost "column"?

As mentioned in the comments, \usetikzlibrary{calc} can be used for defining distances between nodes with the synthax ($(startnode) + (xshift,yshift)$)

\documentclass[border=5pt]{standalone}

\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}
\node(first)[draw,rectangle] at (0,0) {\shortstack{$\boldsymbol{M}^I = \boldsymbol{M}_s + \boldsymbol{M}_{h_0}$ \\
$\boldsymbol{K}^I = \boldsymbol{K}_s + \boldsymbol{K}_h$}};

\node(fourth)[draw,rectangle,anchor=north west] at ($(first.north east) + (4,0)$)
{\shortstack{$\boldsymbol{M}_i^{II}(\omega) = \boldsymbol{M}_{h,i}(\omega)$ \\
$\boldsymbol{C}_i^{II}(\omega) = \boldsymbol{C}_{h,i}(\omega)$ \\
$\boldsymbol{K}_i^{II} = \boldsymbol{K}_{h,i} - \boldsymbol{K}_{h,i} = \boldsymbol{0}$}};

\node(eighth)[draw,rectangle,anchor=north west] at ($(fourth.north east) + (4,0)$)
{\shortstack{$\boldsymbol{Q}_r(\omega, \theta)$}};

\node(tenth)[draw,rectangle,anchor=south west] at (fourth.south east -| eighth.south west)
{\shortstack{$\boldsymbol{S}_{p_rp_s}(\omega) = \int_\theta{\boldsymbol{Q}_r(\omega, \theta)}S_\eta(\omega, \theta)\boldsymbol{Q}_r(\omega, \theta)^H \; d\theta$}};

\node(ninth)[draw,rectangle,anchor=east] at (eighth.east -| tenth.east)
{\shortstack{$S_\eta(\omega,\theta) = S_\eta(\omega) D(\theta)$}};

\end{tikzpicture}
\end{document}


Q2 Also, how to get the node arrows on the top right to point vertically down and not be inclined?

Since we don't know the anchor of the endpoint, we can simply tell the length of the arrow using --++(xshift,yshift)

\documentclass[border=5pt]{standalone}

\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}

% nodes

\node(eighth)[draw,rectangle,anchor=north west] at (0,0)
{\shortstack{$\boldsymbol{Q}_r(\omega, \theta)$}};

\node(tenth)[draw,rectangle,anchor=north west] at ($(eighth.south west) - (0,1)$)
{\shortstack{$\boldsymbol{S}_{p_rp_s}(\omega) = \int_\theta{\boldsymbol{Q}_r(\omega, \theta)}S_\eta(\omega, \theta)\boldsymbol{Q}_r(\omega, \theta)^H \; d\theta$}};

\node(ninth)[draw,rectangle,anchor=east] at (eighth.east -| tenth.east)
{\shortstack{$S_\eta(\omega,\theta) = S_\eta(\omega) D(\theta)$}};

% arrows

\draw[-latex] (eighth.south) --++ (0,-1);
\draw[-latex] (ninth.south) --++ (0,-1);
\end{tikzpicture}
\end{document}


Q3 How can I get the 90 degree angled arrows as shown in the first screenshot?

This can be easily done when the starting- and endpoint are known using \draw[->] (startnode) |- (endnode).

\documentclass[border=5pt]{standalone}

\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}

% nodes

\node(third)[draw,rectangle] at (0,0)
{\shortstack{$\tilde{\boldsymbol{M}}^I$\\
$\tilde{\boldsymbol{K}}^I$\\
$\tilde{\boldsymbol{C}}^I = \alpha \tilde{\boldsymbol{M}}^I + \beta \tilde{\boldsymbol{K}}^I$}};

\node(seventh)[draw,rectangle,anchor=north west] at ($(third.south east) + (4,-4)$)
{\shortstack{$\tilde{\boldsymbol{M}}(\omega) = \tilde{\boldsymbol{M}}^I + \tilde{\boldsymbol{M}}^{II}(\omega)$\\
$\tilde{\boldsymbol{C}}(\omega) = \tilde{\boldsymbol{C}}^I + \tilde{\boldsymbol{C}}^{II}(\omega)$\\
$\tilde{\boldsymbol{K}} = \tilde{\boldsymbol{K}}^I$}};

% arrows

\draw[-latex] (third.south) |- ($(seventh.west) + (0,0.5)$);
\draw[-latex] (third.south) |- (seventh.west);
\draw[-latex] (third.south) |- ($(seventh.west) - (0,0.5)$);
\end{tikzpicture}
\end{document}


EDIT

The final result looks like this:

You can play around and maybe define your own tikzstyle for the different nodes to have them equal width for better alignment.

\documentclass[border=5pt]{standalone}

\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}

\usepackage{tikz}
\usetikzlibrary{calc,fit,backgrounds}

\begin{document}

\tikzset{%
every node/.style={minimum height=0.75cm},
}

\tikzstyle{node1} = [draw,fill=white,minimum width=3cm]
\tikzstyle{node2} = [draw,fill=white,minimum width=5cm]
\tikzstyle{node3} = [draw,fill=white,minimum width=7cm]
\tikzstyle{circ} = [draw,fill=white,circle]

\begin{tikzpicture}
% first column

\node(1)[node1] at (0,0)
{\shortstack{
$\boldsymbol{M}^I = \boldsymbol{M}_s + \boldsymbol{M}_{h_0}$ \\
$\boldsymbol{K}^I = \boldsymbol{K}_s + \boldsymbol{K}_h$}
};
\node(2)[node1,anchor=north] at ($(1.south) + (0,-1)$)
{\shortstack{
$\boldsymbol{\Phi}^I$ \\
$\omega_n^I$}
};
\node(3)[node1,anchor=north] at ($(2.south) + (0,-1)$)
{\shortstack{
$\tilde{\boldsymbol{M}}^I$\\
$\tilde{\boldsymbol{K}}^I$\\
$\tilde{\boldsymbol{C}}^I = \alpha \tilde{\boldsymbol{M}}^I + \beta \tilde{\boldsymbol{K}}^I$}
};

% second column

\node(4)[node2,anchor=north west] at ($(1.north east) + (2,0)$)
{\shortstack{
$\boldsymbol{M}_i^{II}(\omega) = \boldsymbol{M}_{h,i}(\omega)$\\
$\boldsymbol{C}_i^{II}(\omega) = \boldsymbol{C}_{h,i}(\omega)$\\
$\boldsymbol{K}_i^{II} = \boldsymbol{K}_{h,i} - \boldsymbol{K}_{h,i} = \boldsymbol{0}$}
};
\node(5)[node2,anchor=north] at ($(4.south) + (0,-1)$)
{\shortstack{$\boldsymbol{M}^{II}(\omega) = \sum_{i=1}^7\boldsymbol{T}_i^T\boldsymbol{M}_i^{II}(\omega)\boldsymbol{T}_i$\\
$\boldsymbol{C}^{II}(\omega) = \sum_{i=1}^7\boldsymbol{T}_i^T\boldsymbol{C}_i^{II}(\omega)\boldsymbol{T}_i$}};
\node(6)[node2,anchor=north] at ($(5.south) + (0,-1)$)
{\shortstack{
$\tilde{\boldsymbol{M}}^{II}(\omega) = (\boldsymbol{\Phi}^I)^T\boldsymbol{M}^{II}(\omega)\boldsymbol{\Phi}^I$\\
$\tilde{\boldsymbol{C}}^{II}(\omega) = (\boldsymbol{\Phi}^I)^T\boldsymbol{C}^{II}(\omega)\boldsymbol{\Phi}^I$}
};
\node(7)[node2,anchor=north] at ($(6.south) + (0,-1)$)
{\shortstack{
$\tilde{\boldsymbol{M}}(\omega) = \tilde{\boldsymbol{M}}^I + \tilde{\boldsymbol{M}}^{II}(\omega)$\\
$\tilde{\boldsymbol{C}}(\omega) = \tilde{\boldsymbol{C}}^I + \tilde{\boldsymbol{C}}^{II}(\omega)$\\
$\tilde{\boldsymbol{K}} = \tilde{\boldsymbol{K}}^I$}
};

% third column

\node(8)[draw,fill=white,anchor=north west] at ($(4.north east) + (2,0)$)
{\shortstack{
$\boldsymbol{Q}_r(\omega, \theta)$}
};
\node(10)[node3,anchor=north west] at ($(8.south west) + (0,-1)$)
{\shortstack{
$\boldsymbol{S}_{p_rp_s}(\omega) = \int_\theta{\boldsymbol{Q}_r(\omega, \theta)}S_\eta(\omega, \theta)\boldsymbol{Q}_r(\omega, \theta)^H \; d\theta$}
};
\node(9)[draw,fill=white,anchor=east] at (10.east |- 8.east)
{\shortstack{
$S_\eta(\omega,\theta) = S_\eta(\omega) D(\theta)$}
};
\node(11)[node3,anchor=north] at ($(10.south) + (0,-1)$)
{\shortstack{
$\boldsymbol{S}_p(\omega) = \begin{bmatrix} \boldsymbol{S}_{p_1p_1}(\omega) & \cdots & \boldsymbol{S}_{p_1p_7}(\omega)\\ \vdots & \ddots & \vdots \\ \boldsymbol{S}_{p_7p_1}(\omega) & \cdots & \boldsymbol{S}_{p_7p_7}(\omega) \end{bmatrix}$}
};
\node(12)[node3,anchor=north] at ($(11.south) + (0,-1)$)
{\shortstack{
$\tilde{\boldsymbol{S}}_p(\omega) = (\boldsymbol{\Phi}^I)^T\boldsymbol{S}_p(\omega)\boldsymbol{\Phi}^I$}
};

% second column

\node(13)[node2,anchor=north] at ($(7.south) + (0,-1)$)
{\shortstack{$\tilde{\boldsymbol{S}}_u(\omega) = \tilde{\boldsymbol{H}}(\omega)\tilde{\boldsymbol{S}}_p(\omega)\tilde{\boldsymbol{H}}(\omega)^H$}};
\node(14)[node2,anchor=north] at ($(13.south) + (0,-1)$)
{\shortstack{
$\boldsymbol{S}_u(\omega) = \boldsymbol{\Phi}^I\tilde{\boldsymbol{S}}_u(\omega)(\boldsymbol{\Phi}^I)^T$}
};

% arrows

\draw[-stealth] (1.south) -- (2.north);
\draw[-stealth] (2.south) -- (3.north);
\draw[-stealth] (3.south) |- ($(7.west) + (0,0.5)$);
\draw[-stealth] (4.south) -- (5.north);
\draw[-stealth] (5.south) -- (6.north);
\draw[-stealth] (6.south) -- (7.north);
\draw[-stealth] (8.south) --++ (0,-1);
\draw[-stealth] (9.south) --++ (0,-1);
\draw[-stealth] (10.south) -- (11.north);
\draw[-stealth] (11.south) -- (12.north);
\draw[-stealth] (12.south) |- (13.east);
\draw[-stealth] (7.south) -- (13.north) node[pos=0.5,right] {\shortstack{$\tilde{\boldsymbol{H}}(\omega)$}};
\draw[-stealth] (13.south) -- (14.north);

% labels

\foreach \i [count=\ii from 1] in {1,...,14}{%
\node(lab-\i)[circ,anchor=east]  at ($(\ii.west) + (-0.5,0)$) {\i};
}

% filling

\begin{pgfonlayer}{background}
\node[fit=(1)(3)(lab-1), fill=green!15!] {};
\node[fit=(4)(6)(lab-4), fill=blue!15!] {};
\node[fit=(12)(lab-8), fill=orange!15!] {};
\end{pgfonlayer}

\end{tikzpicture}
\end{document}

• Excellent and comprehensive answer, though one doesn't need to use the calc library to place nodes relatively to others. But this library is usefull to fine tune the arrow placement like you did. – SebGlav Apr 11 at 14:37
• To be absolutely complete, it's now also possible to use the backgrounds and fit libraries to draw the coloured rectangles behind the trees. – SebGlav Apr 11 at 14:39
• @SebGlav In case it is needed, I added your suggestion to the final chart. – Excelsior Apr 11 at 16:52
• Nice. Note that with fit, you don't have to name every node you want to fit in. Here, for example, I think that \node[fit=(12)(lab-8),fill=orange!25] would suffice. – SebGlav Apr 11 at 16:57
• @SebGlav Ok, so just include the corners. Thanks, I will keep it in mind. – Excelsior Apr 11 at 17:00