我正在学习如何使用 tikz 绘制图表,我在texample.net,它们都是免费使用的,而且大多数作者都非常活跃tex.stackexchange.com
我下载了这个“示例:光纤系统的 BER 测量 发布日期 2009-07-31 | 作者:Jose Luis Diaz“这看起来非常有趣,可以学习并制作类似的图表。
当我编译示例时,出现了一些无法解决的错误。有人能帮我找到这个代码中的问题吗?
% BER measurement on fibre optical system
% Author: Jose Luis Diaz
\documentclass{minimal}
\usepackage[a4paper, landscape]{geometry}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,shapes.arrows,decorations.pathmorphing}
\usetikzlibrary{matrix,chains,scopes,positioning,arrows,fit}
\begin{document}
\sffamily\begin{tikzpicture}
% Define a macro to draw the filter symbol
\def\filterSS{\node{}; % 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
\def\MOD#1{\node{#1}; % 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
\def\Polaris{\node[coordinate]{}; % 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,
anchor=center,
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},
ellip/.style={ellipse,scale=0.5},
empty/.style={draw=none}
]
{
% 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
Laser
& % m-2-2
\MOD{MOD}
& % m-2-3
|[right iso]|
& % m-2-4
SOA
& % m-2-5
\filterSS
& % m-2-6
VOA
& % m-2-7
|[ellip]|
& % m-2-8
|[coordinate, xshift=-1cm]|
\\
% Third row of symbols
% m-3-1 empty
& % m-3-2
VOA
& % m-3-3
\filterSS
& % m-3-4
|[left iso]|
& % m-3-5
|[draw=orange!80!white, ultra thick]| \textbf{QDSOA}
& % m-3-6
|[left iso]|
& % m-3-7
\Polaris
& % 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
|[ellip]|
& % m-4-3
|[right iso]|
& % m-4-4
SOA
& % m-4-5
|[right iso]|
& % m-4-6
\filterSS
& % m-4-7
Rx
& % 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}};
\end{tikzpicture}
\end{document}
错误:包 pgf 错误:没有已知的名为“chain-2”的形状。\chainin (m-2-2);
包 pgf 错误:没有已知的名为“chain-5”的形状。\chainin (m-2-6);
包 pgf 错误:没有已知名为“chain-10”的形状。\chainin (m-3-6);
包 pgf 错误:没有已知的名为“chain-20”的形状。\chainin (m-4-7);...
答案1
矩阵会为每个单元格隐式创建一个节点。节点会(<matrixname>-<row>-<col>)
自动命名。但是,矩阵中的某些节点是明确定义的,即命令\filterSS
、\MOD
和\Polaris
包含\node ...
。这些节点没有名称。但是,(m-<row>-<col>)
稍后需要使用形式为 的名称,例如在\chainin
命令中。
一个解决方法是将这些节点命名为
(\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn)
\filterSS
、\MOD
和更改后的最终代码\Polaris
为:
% BER measurement on fibre optical system
% Author: Jose Luis Diaz
\documentclass{minimal}
\usepackage[a4paper, landscape]{geometry}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,shapes.arrows,decorations.pathmorphing}
\usetikzlibrary{matrix,chains,scopes,positioning,arrows,fit}
\begin{document}
\sffamily\begin{tikzpicture}
% Define a macro to draw the filter symbol
\def\filterSS{\node(\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn){}; % 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
\def\MOD#1{\node(\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn){#1}; % 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
\def\Polaris{\node(\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn)[coordinate]{}; % 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,
anchor=center,
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},
ellip/.style={ellipse,scale=0.5},
empty/.style={draw=none}
]
{
% 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
Laser
& % m-2-2
\MOD{MOD}
& % m-2-3
|[right iso]|
& % m-2-4
SOA
& % m-2-5
\filterSS
& % m-2-6
VOA
& % m-2-7
|[ellip]|
& % m-2-8
|[coordinate, xshift=-1cm]|
\\
% Third row of symbols
% m-3-1 empty
& % m-3-2
VOA
& % m-3-3
\filterSS
& % m-3-4
|[left iso]|
& % m-3-5
|[draw=orange!80!white, ultra thick]| \textbf{QDSOA}
& % m-3-6
|[left iso]|
& % m-3-7
\Polaris
& % 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
|[ellip]|
& % m-4-3
|[right iso]|
& % m-4-4
SOA
& % m-4-5
|[right iso]|
& % m-4-6
\filterSS
& % m-4-7
Rx
& % 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}};
\end{tikzpicture}
\end{document}
答案2
正如 user187803 在他们的回答中所说,问题在于矩阵节点内部的节点嵌套。解决此问题的另一种方法是\nodes
使用insert path
选项替换嵌套。
例如,除了宏的定义之外\MOD
,您还可以将以下内容添加到矩阵的样式中:
mod/.style={insert path={
\pgfextra{
\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;
}
}}
然后你需要\MOD{MOD}
在矩阵中用替换。对和 的|[mod]|MOD
另外两个定义也可以这样做。完整的代码将变成:\Polaris
\filterSS
% BER measurement on fibre optical system
% Author: Jose Luis Diaz
\documentclass{minimal}
\usepackage[a4paper, landscape]{geometry}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,shapes.arrows,decorations.pathmorphing}
\usetikzlibrary{matrix,chains,scopes,positioning,arrows,fit}
\begin{document}
\sffamily\begin{tikzpicture}
% 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,
anchor=center,
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},
ellip/.style={ellipse,scale=0.5},
empty/.style={draw=none},
mod/.style={insert path={
\pgfextra{
\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;
}
}},
polaris/.style={insert path={
\pgfextra{
\draw[line width=1pt] (0mm, -2mm) circle (2mm)
(-2mm,2mm) circle (2mm)
(2mm, 2mm) circle (2mm);
}
}},
filterSS/.style={insert path={
\pgfextra{
\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);
}
}}
]
{
% 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
Laser
& % m-2-2
|[mod]|MOD
& % m-2-3
|[right iso]|
& % m-2-4
SOA
& % m-2-5
|[filterSS]|
& % m-2-6
VOA
& % m-2-7
|[ellip]|
& % m-2-8
|[coordinate, xshift=-1cm]|
\\
% Third row of symbols
% m-3-1 empty
& % m-3-2
VOA
& % m-3-3
|[filterSS]|
& % m-3-4
|[left iso]|
& % m-3-5
|[draw=orange!80!white, ultra thick]| \textbf{QDSOA}
& % m-3-6
|[left iso]|
& % m-3-7
|[polaris]|
& % 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
|[ellip]|
& % m-4-3
|[right iso]|
& % m-4-4
SOA
& % m-4-5
|[right iso]|
& % m-4-6
|[filterSS]|
& % m-4-7
Rx
& % 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}};
\end{tikzpicture}
\end{document}