I'm trying to make some Automatic Control charts illustrating Mason's rule, but couldn't find any suitable library. Is there any way to ease the process of creating these with TikZ?

An example can be found on this page in section sfg.m4: Signal-flow graphs

enter image description here

I found this way to make one of the flows, however, I wonder if there is any clearer or simpler way to do this drawing, using any library (as when making circuits or blocks with the libraries a \usepackage{blocks} or \usepackage{schemabloc} or \usepackage{circuitikz}) so that the code is not as large and is more clear and clean the program?

        \node [style=none] (0) at (1, 1) {};
        \node [style=none] (1) at (-4, 0.5) {$\frac{1}{K}$};
        \node [style=none] (2) at (-2, 0.5) {$\frac{K}{M}$};
        \node [style=none] (3) at (0, 0.5) {$s^{-1}$};
        \node [style=none] (4) at (2, 0.5) {$s^{-1}$};
        \node [style=none] (5) at (-5, -0) {};
        \node [style=none] (6) at (-4, -0) {};
        \node [style=none] (7) at (-3, -0) {};
        \node [style=none] (8) at (-2, -0) {};
        \node [style=none] (9) at (-1, -0) {};
        \node [style=none] (10) at (0, -0) {};
        \node [style=none] (11) at (1, -0) {};
        \node [style=none] (12) at (2, -0) {};
        \node [style=none] (13) at (3, -0) {};
        \node [style=none] (14) at (0, -0.75) {};
        \node [style=none] (15) at (0, -1.5) {};
        \draw [-triangle 60] (9.center) to (10.center);
        \draw [bend right] (0.center) to (9.center);
        \draw [-triangle 60, bend left, looseness=0.75] (11.center) to (14.center);
        \draw [-triangle 60, bend left] (0.center) to (13.center);
        \draw [-triangle 60] (11.center) to (12.center);
        \draw [-triangle 60] (5.center) to (6.center);
        \draw [bend right] (7.center) to (15.center);
        \draw [bend left] (14.center) to (9.center);
        \draw (6.center) to (7.center);
        \draw [-triangle 60] (7.center) to (8.center);
        \draw [-triangle 60, bend right] (15.center) to (13.center);
        \draw (10.center) to (11.center);
        \draw (12.center) to (13.center);
        \draw (8.center) to (9.center);

3 Answers 3


Here is another one with slightly more complicated definition but still easy to use. I have defined some styles to make it a little easier to read the code. Also I defined a label placing option label revd to switch the location of the label above or below. The amark is for placing an arrow and a node at the middle (hi-jacked from one of my earlier answers ) .

The reason for weird names is to avoid the clash with other libraries and I am not sure about terminal. Please test with circuit library (or related packages) and change those instances if so. You can automate even more but it should give you a head start.

I tried to use as many different options as possible to show the variety and you can always search in the manual what each option does (apart from the ones I have defined).

label revd/.is if=labrev,
%label revd/.default=true,
                        mark=at position {0.5} with { 
                                    \iflabrev \node[above] {#1};\else \node[below] {#1};\fi
terminal/.style 2 args={draw,circle,inner sep=2pt,label={#1:#2}},

%Place the nodes
\node[terminal={below}{$f(t)$}] (a) at (0,0) {};
\node[terminal={below left}{$y_1$}] (b) at (3cm,0) {};
\node[terminal={below left}{$\ddot{y}_2$}] (c) at (6cm,0) {};
\node[terminal={[xshift=-4mm]below right}{$\dot{y}_2=x_2$}] (d) at (9cm,0) {};
\node[terminal={below right}{$y_2=x_1$}] (e) at (12cm,0) {};
%Draw the connections
\draw[amark=$1/K$] (a) to (b);
\draw[amark=$K/M$] (b) to (c);
\draw[amark=$s^{-1}$] (c) to (d);
\draw[amark=$s^{-1}$] (d) to (e);
\draw[amark=$-B/M$] (d) to[bend left=45] (c);
\draw[amark=$1$,label revd] (e) to[bend left=50] (b);
\draw[amark=$-K/M$,label revd] (e) to[bend right=50] (c);

enter image description here


Here are some usefull things:

  • In this question Caramdir shows nicely how to put arrows to the middle of a line. I used this to define the midarrow style.

  • I placed the nodes manually, three units apart. You could also use relative positioning, see section 3.8 of the TikZ/PGF manual.

  • An edge from a node to it self might be done using (a) to (a). You can use in=degree and out=degree to specify where the lines leave and enter.

  • In Order to get the loops smaller or bigger, you can play with the looseness key.

  • To draw bent lines, you can use the straight forward notion bend left=degrees or bend right=degrees.

An example, the bottom left one:



\begin{tikzpicture}[midarrow/.style={decoration={markings, mark=at position 0.5 with {\arrow{stealth}}},postaction={decorate}}]
    \node[draw,circle,label=90:$r_2$] (r2) at (0,0) {};
    \node[draw,circle,label=90:$r_1$] (r1) at (0,3) {};
    \node[draw,circle,label=0:$x_2$] (x2) at (3,0) {};
    \node[draw,circle,label=0:$x_1$] (x1) at (3,3) {};

    \draw[midarrow] (r1) -- node[above] {1} (x1);
    \draw[midarrow] (r2) -- node[above] {1} (x2);

    \draw[midarrow,looseness=20] (x1) to[out=50,in=130] node[above] {$q_{11}$} (x1);
    \draw[midarrow,looseness=40] (x1) to[out=40,in=-40] node[right] {$a_{11}$} (x1);
    \draw[midarrow,looseness=20] (x2) to[out=230,in=310] node[below] {$q_{22}$} (x2);

    \draw[midarrow,bend right=30] (x1) to node[left] {$a_{21}$} (x2);
    \draw[midarrow,bend right=30] (x2) to node[right] {$a_{12}$} (x1);


enter image description here


Here an answer with tkz-graph. This example is funny because I use decoration to compute the labels. I need to update vey quickly tkz-graph because there are a lot of codes insubstantial.


% the next 4 lines are define labels and arrows 
\tikzset{position/.style = {below}} 

 \tikzset{VertexStyle/.append style = {% set the style of vertices
   shape        = circle,
   fill         = lightgray!50,
   text         = black,
   inner sep    = 2pt,
   outer sep    = 0pt,
   minimum size= 32 pt}}   

\begin{tikzpicture} [decoration={% I place the arrow and the label and step the indice
    mark= at position .5 with {\arrow[>=latex',line width=1.8 pt]{\myarrow},

 \Vertices[unit=3]{line}{1,2,3,4} % I get the vertices with one macro

 \tikzset{EdgeStyle/.style = {postaction={decorate}}} 


 \tikzset{EdgeStyle/.append style = {-,out=45,in=135}}

  \tikzset{EdgeStyle/.append style = {-,out=80,in=100}} 

 \tikzset{position/.style = {above}}
 \def\letter{P} \setcounter{indice}{1}  

  \foreach \v in {1,...,4}
  {\Loop[dist=3cm,dir=SO,style={-}](\v) }  

enter image description here

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.