With tikz v3 the matrix behavior has changed slightly. The great example at http://www.texample.net/tikz/examples/BER-measurement/ doesn't seem to compile any longer. The problem is that the default naming of matrix nodes as m-1-1 etc. is now overridden.

My question is what would be a good replacement in defining custom node shapes, such as the filter or polarization controller in the example? A way that would keep the matrix element referencing usable.

I've searched through some questions related to this problem, and I've found two possible solutions, albeit not satisfactory:

  1. Defining custom node styles. This is clearly much more cumbersome approach than before in the example.

  2. Nesting \begin{tikzpicture}customshapehere\end{tikzpicture} inside the node. However, then the connection behavior of the matrix nodes changes. It also seems that there is a margin between the edge of the nested tikzpicture and the node.


1 Answer 1


The problem you've found is explained in Nodes and matrix of nodes. A matrix of nodes assigns names with style matrix-row-column to all nodes except all those constructed with an explicit \node command.

As you can see, the example contains nodes defined with commands like \Polaris or \filterSS which call \node commands. Therefore, these nodes don't have name in form matrix-row-column and posterior \chainin references to them fail.

The best solution would be reading and understanging the answers to Nodes and matrix of nodes and convert all compound drawing commands (\Polaris, \filterSS, ...) to pics nodes as is explained there.

By chance, JLDiaz is the author of one of the mentioned answers and also the author of this example, so I hope he could provide a better solution.

In the mean time, an easy and not elegant solution could be adding a parameter to all these commands and introducing through it the expected matrix-row-column name. This is what is shown in next code:

% BER measurement on fibre optical system
% Author: Jose Luis Diaz
\usepackage[a4paper, landscape]{geometry}

  % Define a macro to draw the filter symbol
  \newcommand\filterSS[1]{\node (#1) {};  % This empty node draws the box. 
     % Then we draw the inner curves
     \draw[line width=1pt] (-2mm,-4mm) to[in=200,out=20] (-2mm, 4mm) 
                           (0mm,-4mm) to[in=200,out=20] (0mm, 4mm) 
                           (2mm,-4mm) to[in=200,out=20] (2mm, 4mm); 

  % Define a macro to draw the MOD symbol
  \newcommand\MOD[2]{\node (#1) {#2}; % The box with the text inside. Then draw the polygon around the text
    \draw[line width=1pt,sharp corners](-0.75cm,0cm)--(-0.35cm,0.25cm)--
         (0.35cm, 0.25cm)--(0.75cm, 0cm)--(0.35cm, -0.25cm)--(-0.35cm, -0.25cm) -- cycle; 

  % Define a macro to draw the Polariser symbol
  \newcommand\Polaris[1]{\node[coordinate] (#1) {}; % Node of type coordinate is a simple point 
       % Now draw the three circles
       \draw[line width=1pt] (0mm, -2mm)  circle (2mm) 
                             (-2mm,2mm)  circle (2mm)
                             (2mm, 2mm)  circle (2mm);}

  % Place all element in a matrix of nodes, called m
  % By default all nodes are rectangles with round corners
  % but some special sytles are defined also
  \matrix (m) [matrix of nodes, 
    column sep=5mm,
    row sep=1cm,
    nodes={draw, % General options for all nodes
      line width=1pt,
      text centered,
      rounded corners,
      minimum width=1.5cm, minimum height=8mm, 
    % Define styles for some special nodes
    right iso/.style={isosceles triangle,scale=0.5,sharp corners, anchor=center, xshift=-4mm},
    left iso/.style={right iso, rotate=180, xshift=-8mm},
    txt/.style={text width=1.5cm,anchor=center},
  % First row of symbols (mostly empty, only the power meter at the right end)
    % m-1-1 empty
  & % m-1-2 empty
  & % m-1-3 empty
  & % m-1-4 empty
  & % m-1-5 empty
  & % m-1-6 empty
  & % m-1-7
    |[txt]| {Power Meter} 

  % Second row of symbols
  % m-2-1
  & % m-2-2
  & % m-2-3
    |[right iso]|  
  & % m-2-4
  & % m-2-5
  & % m-2-6
  & % m-2-7
  & % m-2-8
    |[coordinate, xshift=-1cm]|  
  % Third row of symbols
    % m-3-1 empty
  & % m-3-2
  & % m-3-3
  & % m-3-4
    |[left iso]| 
  & % m-3-5
    |[draw=orange!80!white, ultra thick]| \textbf{QDSOA} 
  & % m-3-6
    |[left iso]| 
  & % m-3-7
  & % m-3-8 (no symbol here, only a point to draw the path)
    |[coordinate, xshift=-1cm]| 
  % Fourth row of symbols
    % m-4-1
    |[txt]| {Power Meter} 
  & % m-4-2
  & % m-4-3
    |[right iso]| 
  & % m-4-4
  & % m-4-5
    |[right iso]| 
  & % m-4-6
  & % m-4-7
  & % m-4-8
    |[txt]| {Error\\Detector} 
  };  % End of matrix

  % Now, connect all nodes in a chain.
  % The names of the nodes are automatically generated in the previous matrix. Since the
  % matrix was named ``m'', all nodes have the name m-row-column
  { [start chain,every on chain/.style={join}, every join/.style={line width=1pt}]
    \chainin (m-2-1);
    \chainin (m-2-2);
    \chainin (m-2-3);
    \chainin (m-2-4);
    \chainin (m-2-5);
    \chainin (m-2-6);
    % Connect to the power meter, and put a label saying 10%
    \path[line width=1pt] (m-1-7) edge node [right] {$10\%$} (m-2-7);
    \chainin (m-2-7);
    \chainin (m-2-8);
    % Draw the label saying 90%
    \path (m-2-8) edge node [right] {$90\%$} (m-3-8) ;
    \chainin (m-3-8);
    \chainin (m-3-7);
    \chainin (m-3-6);
    \chainin (m-3-5);
    \chainin (m-3-4);
    \chainin (m-3-3);
    \chainin (m-3-2);
    % Connect to the power meter, and put a label saying 10%
    \path[line width=1pt] (m-4-1) edge node [above] {$10\%$} (m-4-2);
    \chainin (m-4-2);
    % Draw the label saying 90%
    \path (m-4-2) edge node [below] {$90\%$} (m-4-3) ;
    \chainin (m-4-3);
    \chainin (m-4-4);
    \chainin (m-4-5);
    \chainin (m-4-6);
    \chainin (m-4-7);
    \chainin (m-4-8);
  % Finally, put some text above some symbols
  \draw (m-2-3.left side) node[above, inner sep=5mm] {Isolator};
  \draw (m-2-5.north) node[above, inner sep=3mm] {Filter};
  \draw (m-3-7) node[above, inner sep=6mm, text centered, text width=2cm] {Polarisation\\controller};

  % The big arrow over the MOD symbol is a bit laborious
  \node[yshift=2mm] (MOD arrow) at (m-2-2.north) [anchor=east,single arrow, draw,line width=1pt, 
                rotate=-90, minimum height=7mm, minimum width=1.3cm, 
                single arrow head extend=1.2mm, single arrow tip angle=120] {};
  % The text above the arrow (the starting of the arrow is at west in the arrow shape, even if the
  % arrow was rotated and it lies now at top)
  \node (MOD text) at (MOD arrow.west) [above, inner sep=2mm] {10Gb/s PRBS};

  % Define the style for the blue dotted boxes
  \tikzset{blue dotted/.style={draw=blue!50!white, line width=1pt,
                               dash pattern=on 1pt off 4pt on 6pt off 4pt,
                                inner sep=4mm, rectangle, rounded corners}};

  % Finally the blue dotted boxes are drawn as nodes fitted to other nodes
  \node (first dotted box) [blue dotted, 
                            fit = (MOD text) (m-2-1) (m-2-4)] {};
  \node (second dotted box) [blue dotted,
                            fit = (m-4-4) (m-4-8)] {};

  % Since these boxes are nodes, it is easy to put text above or below them                          
  \node at (first dotted box.north) [above, inner sep=3mm] {\textbf{Transmitter}};
  \node at (second dotted box.south) [below, inner sep=3mm] {\textbf{Receiver}};

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.