4

I an trying to write the following block diagram in tikz. What I want to do Because it mainly consists in aligned blocks, I am using a matrix for the layout. I wrote the following tikz instructions, which give the picture at the end of this post. Here are the problems I have:

  • I don't know how to do the large blocks with 2 inputs / 2 outputs
  • I don't know how to deal with the arrows so that they do not superpose each other on the C blocks

My document:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{varwidth}
\usetikzlibrary{shapes}
\usetikzlibrary{matrix}
\usetikzlibrary{fit}

\tikzstyle{B} = [draw,align=center]

\tikzset{
  max width/.style args={#1}{
    execute at begin node={\begin{varwidth}{#1}},
      execute at end node={\end{varwidth}}
  }
}

\begin{document}
\begin{tikzpicture}
    \matrix[column sep=5pt,row sep=10pt] {
        \coordinate (tmp_HH1_1);   &
        &
        &
        &
        \coordinate (tmp_x1);  &
        &
        &
        &
        &
        &
        \\
        &
        &
        &
        \coordinate (tmp_P1);  &
        &
        &
        &
        &

        &
        \\
        &
        \coordinate (u1); \node[above][max width=3cm] {$u_1$}; &
        \node[B]    (C1) {$C_1$}; &
        \node[B]    (P1) {$P_1$}; &
        \coordinate (x1);  &
        \node[B]    (H1) {$H_1$}; &
        \node[B]    (D1) {$D_1$}; &
        \node[B]    (R1) {$R_1$}; &
        \coordinate (yy1); &
        &
        \coordinate (y1); \node[above][max width=3cm] {$y_1$};
        \\
        &
        \coordinate (u2); \node[above][max width=3cm] {$u_2$}; &
        \node[B]    (C2) {$C_2$}; &
        \node[B]    (P2) {$P_2$}; &
        \coordinate (x2);  &
        \node[B]    (H2) {$H_2$}; &
        \node[B]    (D2) {$D_2$}; &
        \node[B]    (R2) {$R_2$}; &
        &
        \coordinate (yy2);&
         \coordinate (y2); \node[above][max width=3cm] {$y_2$};
        \\
        \coordinate (tmp_HH1_2);    &
        &
        &
        \coordinate (tmp_P2);  &
        &
        &
        &
        &
        \\
        &
        &
        &
        &
        \coordinate (tmp_x2);  &
        &
        &
        &
        \\
        &
        &
        &
        &
        &
        \node[B]    (HH1) {$H^{-1}_1$}; &
        &

        \\
        &
        &
        &
        &
        &
        \node[B]    (HH2) {$H^{-1}_2$}; &
        &
        \\

        &
        &
        &
        &
       \coordinate (delta); \node[below][max width=3cm] {$\delta$};  &
        &
        &
        \\
    };

    \draw[->] (u1) -- (C1);
    \draw[->] (C1) -- (P1);
    \draw[->] (P1) -- (H1);
    \draw[->] (H1) -- (D1);
    \draw[->] (D1) -- (R1);
    \draw[->] (R1) -- (y1);

    \draw[-] (x1) -- (tmp_x1);
    \draw[->] (tmp_x1) -| (C1);
    \draw[-] (P1) -- (tmp_P1);
    \draw[->] (tmp_P1) -| (C1);

    \draw[->] (u2) -- (C2);
    \draw[->] (C2) -- (P2);
    \draw[->] (P2) -- (H2);
    \draw[->] (H2) -- (D2);
    \draw[->] (D2) -- (R2);
    \draw[->] (R2) -- (y2);

    \draw[-] (x2) -- (tmp_x2);
    \draw[->] (tmp_x2) -| (C2);
    \draw[-] (P2) -- (tmp_P2);
    \draw[->] (tmp_P2) -| (C2);

    \draw[->] (yy1) |- (HH1);
    \draw[->] (yy2) |- (HH2);

    \draw[->] (HH2) -| (delta);

    \draw[-] (HH1) -| (tmp_HH1_1);
    \draw[->] (tmp_HH1_1) -| (C1);
    \draw[->] (tmp_HH1_2) -| (C2);
\end{tikzpicture}


\end{document}

What I have

3

For the big blocks, one approach is to modify the nodes you currently have to be on the form

\node[B, draw=none] (H1) {\phantom{$H_1$}}; 

So added draw=none and placed the node contents in a \phantom, meaning that you essentially get an invisible node. (There are other ways of achieving the same.) To draw the big node you can, after the matrix, do

\node [inner sep=-0.5\pgflinewidth,fit=(H1)(H2), draw] {$H$};

To fix the overlapping arrows, you can shift the endpoints a bit, by making the final coordinates of the form

([xshift=3pt]C1.north)

instead of just C1.

Complete code below. Note I also drew the arrows going into the C blocks in one path, as this will improve the look of the corners. (Try zooming really far in on, for example, the tmp_X2 corner.)

enter image description here

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{varwidth}
\usetikzlibrary{shapes}
\usetikzlibrary{matrix}
\usetikzlibrary{fit}

\tikzset{
  B/.style={draw,align=center},
  max width/.style args={#1}{
    execute at begin node={\begin{varwidth}{#1}},
      execute at end node={\end{varwidth}}
  }
}

\begin{document}
\begin{tikzpicture}
    \matrix[column sep=5pt,row sep=10pt] {
        \coordinate (tmp_HH1_1);   &
        &
        &
        &
        \coordinate (tmp_x1);  &
        &
        &
        &
        &
        &
        \\
        &
        &
        &
        \coordinate (tmp_P1);  &
        &
        &
        &
        &

        &
        \\
        &
        \coordinate (u1); \node[above][max width=3cm] {$u_1$}; &
        \node[B]    (C1) {$C_1$}; &
        \node[B]    (P1) {$P_1$}; &
        \coordinate (x1);  &
        \node[B, draw=none]    (H1) {\phantom{$H_1$}}; &
        \node[B]    (D1) {$D_1$}; &
        \node[B, draw=none]    (R1) {\phantom{$R_1$}}; &
        \coordinate (yy1); &
        &
        \coordinate (y1); \node[above][max width=3cm] {$y_1$};
        \\
        &
        \coordinate (u2); \node[above][max width=3cm] {$u_2$}; &
        \node[B]    (C2) {$C_2$}; &
        \node[B]    (P2) {$P_2$}; &
        \coordinate (x2);  &
        \node[B, draw=none]    (H2) {\phantom{$H_2$}}; &
        \node[B]    (D2) {$D_2$}; &
        \node[B, draw=none]    (R2) {\phantom{$R_2$}}; &
        &
        \coordinate (yy2);&
         \coordinate (y2); \node[above][max width=3cm] {$y_2$};
        \\
        \coordinate (tmp_HH1_2);    &
        &
        &
        \coordinate (tmp_P2);  &
        &
        &
        &
        &
        \\
        &
        &
        &
        &
        \coordinate (tmp_x2);  &
        &
        &
        &
        \\
        &
        &
        &
        &
        &
        \node[B]    (HH1) {$H^{-1}_1$}; &
        &

        \\
        &
        &
        &
        &
        &
        \node[B]    (HH2) {$H^{-1}_2$}; &
        &
        \\

        &
        &
        &
        &
       \coordinate (delta); \node[below][max width=3cm] {$\delta$};  &
        &
        &
        \\
    };

    \node [inner sep=-0.5\pgflinewidth,fit=(H1)(H2), draw] {$H$};
    \node [inner sep=-0.5\pgflinewidth,fit=(R1)(R2), draw] {$R$};

    \draw[->] (u1) -- (C1);
    \draw[->] (C1) -- (P1);
    \draw[->] (P1) -- (H1);
    \draw[->] (H1) -- (D1);
    \draw[->] (D1) -- (R1);
    \draw[->] (R1) -- (y1);

    \draw[->] (x1) -- (tmp_x1) -| (C1);
    \draw[->] (P1) -- (tmp_P1) (tmp_P1) -| ([xshift=3pt]C1.north);

    \draw[->] (u2) -- (C2);
    \draw[->] (C2) -- (P2);
    \draw[->] (P2) -- (H2);
    \draw[->] (H2) -- (D2);
    \draw[->] (D2) -- (R2);
    \draw[->] (R2) -- (y2);

    \draw[->] (x2) -- (tmp_x2) -| (C2);
    \draw[->] (P2) -- (tmp_P2) -| ([xshift=3pt]C2.south);

    \draw[->] (yy1) |- (HH1);
    \draw[->] (yy2) |- (HH2);

    \draw[->] (HH2) -| (delta);

    \draw[->] (HH1) -| (tmp_HH1_1) -| ([xshift=-3pt]C1.north);
    \draw[->] (tmp_HH1_2) -| ([xshift=-3pt]C2.south);
\end{tikzpicture}


\end{document}
| improve this answer | |
  • Thanks a lot! I didn't know about draw=none and \phantom so my backup plan was to put 4 temporary coordinates and draw lines to form a rectangle. Thank you showing that draw lines can be chained. I always did those in several steps because \draw[->] (pt1) -|- (pt2); didn't work. – hage May 29 '19 at 2: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.