1

I'm trying to make a plot as shown here in Tikz, but the path originating from midway are overlapping, so how do I define the originating position of the path as shown below.

Reference Image :- Image shows the path defined from the side, so that they do not interfere with each other

Code:

\documentclass{article}
\usepackage[latin1]{inputenc}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows,shapes.geometric, positioning}

\pagestyle{empty}
\usetikzlibrary{positioning, shapes.geometric}

\tikzset{arrow_box/.style={single arrow, draw=black, minimum width = 30pt,very thick, single arrow head extend=3pt, text centered,minimum height=75mm},%minimum width=2cm, minimum height=1cm,
block_small/.style={rectangle, draw, text width=12em,very thick, text centered,rounded corners, minimum height=2.75em},
block_tiny/.style={rectangle, draw, text width=8em,very thick, text centered,rounded corners, minimum height=2.75em},
block_medium/.style={rectangle, draw, text width=19em,very thick, text centered,rounded corners, minimum height=2.75em},
block_med/.style={rectangle, draw, text width=15em,very thick, text centered,rounded corners, minimum height=2.75em},
block/.style={rectangle, draw, text width=12em,very thick, text centered,rounded corners, minimum height=2.75em},
arrow/.style={line width=0.75mm, ->,>=stealth}}

\begin{document}
\begin{tikzpicture}[node distance=1cm and 2cm]

  % Nodes
\node (forcing) [arrow_box,fill=black!20] {Forcing Environmental Disturbance};
\node (receptivity) [block_medium, fill=black!10, below=0.5 of forcing] {Receptivity Mechanism};
\node (transient) [block_small, fill=black!10, below=0.5cm of receptivity] {Transient Growth};
\node (primary) [block_small, fill=black!10, below of=transient, xshift=-2cm, yshift=-0.5cm] {Primary Instability (Eigenmode Growth)};
\node (secondary) [block_med, fill=black!10, below of=primary, xshift=+0.5cm, yshift=-0.5cm] {Secondary Instability (Parametric $\&$ Mode Interactions)};
\node (bypass) [block_tiny, fill=black!10, right of=secondary, xshift=+3.75cm] {Bypass Mechanism};
\node (breakdown) [block_small, fill=black!10, below of=secondary, xshift=+1.5cm, yshift=-0.5cm] {Breakdown};
\node (turbulence) [block_small, fill=black!10, below of=breakdown, yshift=-0.5cm] {Turbulence};

% path
\draw [arrow] (forcing) -- (receptivity);
\draw [arrow] (receptivity) -- (transient);
\draw [arrow] (receptivity.east) -- (bypass) node[pos=0.9,above]{$e$};
\draw [arrow] (receptivity.west) -- (primary) node[pos=0.9,above]{$a$};
\draw [arrow] (transient) -- (bypass) node[above right, pos=0.5,above]{$d$};
\draw [arrow] (transient) -- (primary) node[pos=0.9,above]{$b$};
\draw [arrow] (transient)--(secondary) node[below right, pos=0.9,above]{$c$};
\draw [arrow] (primary)  -- (secondary);
\draw [arrow] (secondary.south)--(breakdown);
\draw [arrow] (bypass) -- (breakdown);
\draw [arrow] (breakdown) -- (turbulence);
\draw [arrow] (receptivity) edge node[above left, pos=0.5] {$a$}  (primary);
%\path [arrow] (receptivity) -- ++(0,-1) -- +(-2,0) -- (primary) node[pos=0.3,right] {$p_{repl}$};
%\path [arrow] (receptivity) -- ++(0,-1) -| (primary) node [pos=0.8,left] {};
\end{tikzpicture}
\end{document}

Result :

In the result image, I get the path originating from the midway node, but they are overlapping with the other.

enter image description here

Some of the answers mention the usage of midway, but I am not quite sure how to implement that here. This answer here uses the swap, but that is to avoid the overlapping of path with the labels.

2
  • Welcome to TeX.SX! You can use the option xshift in combination with anchors for this. For example: \draw [arrow] ([xshift=-.5cm]receptivity.south) -- ([xshift=-.5cm]transient.north); Jul 21 at 11:22
  • You can also use the calc tikzlibrary notation, such as ($(receptivity.south west)!0.5!(receptivity.south)$). Jul 21 at 14:12

1 Answer 1

0

In general, you can use the option xshift in combination with anchors (south and north in this case) to shift and align edges between nodes. For example, the following would—given the fact that both nodes are aligned vertically—shift the arrow drawn between the two nodes half a centimeter to the left:

\draw [arrow] ([xshift=-.5cm]receptivity.south) -- ([xshift=-.5cm]transient.north);

Since you also want to connect nodes that are not exactly aligned vertically, you would need to do a lot of calculation in order to find out, how much to shift the anchor of the lower node so that the arrow is exactly vertical. Luckily, TikZ has a nice feature that allows you to exactly determine a coordinate that consists of the x-value of one point and the y-value of another. The following code would draw an arrwos that starts 0.5 cm left of the south anchor of the upper node and just vertically goes down until it hits the lower node:

\draw [arrow] ([xshift=-.5cm]transient.south) -- ([xshift=-.5cm]transient.south |- primary.north);

Now, you have a lot of nodes and this would result in a lot of code to type. Therefore, I created a little helper style which allows you to easily draw such arrows (thanks go to the author of this answer for inspiration). The following code shows how to use it:

\documentclass{article}
\usepackage[latin1]{inputenc}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows,shapes.geometric, positioning}

\pagestyle{empty}
\usetikzlibrary{positioning, shapes.geometric}

\tikzset{arrow_box/.style={single arrow, draw=black, minimum width = 30pt,very thick, single arrow head extend=3pt, text centered,minimum height=75mm},%minimum width=2cm, minimum height=1cm,
block_small/.style={rectangle, draw, text width=12em,very thick, text centered,rounded corners, minimum height=2.75em},
block_tiny/.style={rectangle, draw, text width=8em,very thick, text centered,rounded corners, minimum height=2.75em},
block_medium/.style={rectangle, draw, text width=19em,very thick, text centered,rounded corners, minimum height=2.75em},
block_med/.style={rectangle, draw, text width=15em,very thick, text centered,rounded corners, minimum height=2.75em},
block/.style={rectangle, draw, text width=12em,very thick, text centered,rounded corners, minimum height=2.75em},
arrow/.style={line width=0.75mm, ->,>=stealth}}

\tikzset{
    edge xshift/.store in=\edgexshift,
    edge xshift=0pt,
    |/.style={
        to path={
            ([xshift=\edgexshift]\tikztostart.south) -- 
            ([xshift=\edgexshift]\tikztostart.south |- \tikztotarget.north) \tikztonodes
        }
    }
}

\begin{document}
\begin{tikzpicture}[node distance=1cm and 2cm]

  % Nodes
\node (forcing) [arrow_box,fill=black!20] {Forcing Environmental Disturbance};
\node (receptivity) [block_medium, fill=black!10, below=0.5 of forcing] {Receptivity Mechanism};
\node (transient) [block_small, fill=black!10, below=0.5cm of receptivity] {Transient Growth};
\node (primary) [block_small, fill=black!10, below of=transient, xshift=-2cm, yshift=-0.5cm] {Primary Instability (Eigenmode Growth)};
\node (secondary) [block_med, fill=black!10, below of=primary, xshift=+0.5cm, yshift=-0.5cm] {Secondary Instability (Parametric $\&$ Mode Interactions)};
\node (bypass) [block_tiny, fill=black!10, right of=secondary, xshift=+3.75cm] {Bypass Mechanism};
\node (breakdown) [block_small, fill=black!10, below of=secondary, xshift=+1.5cm, yshift=-0.5cm] {Breakdown};
\node (turbulence) [block_small, fill=black!10, below of=breakdown, yshift=-0.5cm] {Turbulence};

% path
\draw [arrow] (forcing) to[|] (receptivity);
\draw [arrow] (receptivity) to[|] (transient);
\draw [arrow] (receptivity) to[|, edge xshift=3cm] node[pos=0.9,right]{$e$} (bypass);
\draw [arrow] (receptivity) to[|, edge xshift=-3cm] node[pos=0.9,left]{$a$} (primary);
\draw [arrow] (transient) to[|, edge xshift=2cm] node[pos=0.9,right]{$d$} (bypass);
\draw [arrow] (transient) to[|] node[pos=0.9,right]{$b$} (primary);
\draw [arrow] (transient) to[|, edge xshift=0.75cm] node[pos=0.9,right]{$c$} (secondary);
\draw [arrow] (primary) to[|] (secondary);
\draw [arrow] (secondary) to[|] (breakdown);
\draw [arrow] (bypass) to[|, edge xshift=-1.25cm] (breakdown);
\draw [arrow] (breakdown) to[|] (turbulence);
\draw [arrow] (receptivity) to[|, edge xshift=-2.5cm] node[pos=0.9,right]{$a$} (primary);
%\path [arrow] (receptivity) -- ++(0,-1) -- +(-2,0) -- (primary) node[pos=0.3,right] {$p_{repl}$};
%\path [arrow] (receptivity) -- ++(0,-1) -| (primary) node [pos=0.8,left] {};
\end{tikzpicture}
\end{document}

Using \draw (A) to[|] (B); you tell TikZ to draw a vertical line between the two nodes, while \draw (A) to[|, edge xshift=1cm] (B); will draw a vertical line that is shifted 1 cm to the right.

enter image description here

2
  • I managed to do it like this, \draw [arrow] ([xshift=+3cm]receptivity.south) -- ([xshift=-0.22cm]bypass.north) node[right, pos=0.85]{$E$}; But your method is significantly more better and time saving. Thank you Jul 21 at 12:14
  • One think to notice with my approach: Since it is a to-path, you cannot place a node after the to-coordinate. You need to place all nodes between the two coordinates of the to-path. Jul 21 at 12:20

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.