TikZ 矩阵,为什么“每个偶数行”不能与“行分隔”选项一起使用?

TikZ 矩阵,为什么“每个偶数行”不能与“行分隔”选项一起使用?

请考虑以下事项姆韦

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{matrix}

\begin{document}
\begin{tikzpicture}
\matrix (m) [matrix of math nodes,
            nodes={draw, font=\footnotesize, minimum size=1em,
                   anchor=center,inner sep=0pt},
                   column sep=-\pgflinewidth,
                   row sep=-\pgflinewidth,
                   every even column/.style={column sep=2pt},
                   every even row/.style={row sep=2pt},% doesn't insert row separation
                   inner sep=1pt,
                   left delimiter={[},right delimiter={]},
             ]
{
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
};
\end{tikzpicture}
\end{document}

但是,every even column/.style={column sep=2pt},产生了预期的结果,例如,在每第二列之后引入额外的列分隔,但事实every even row/.style={row sep=2pt},并非如此。我做错了什么还是这是 TikZ v3.1 中的一个错误(我以前从未测试过这个,所以我不知道 v3.0.1 中是否会发生同样的事情)?

在此处输入图片描述

编辑:

同样的事情也发生在,例如,

row 2/.style = {row sep=2pt} 

因此,这可能意味着仅当想要更改行内单元格的某些属性(例如节点边框的颜色)时才能正常工作every even row/.style=...row <row number>

every even row/.style={draw red},

但如果要改变行间距则不行(请参阅下面@AndréC 的评论)。然而有趣的是,这是可以做到的every column sep...

当然,(临时)解决方法会终止矩阵的每个第二行,例如[2pt],但当矩阵很大时,这会很烦人,例如这里

答案1

这是库中的一个错误matrix。该错误报告于问题 #504在 PGF 错误跟踪器中。

问题是\pgfmatrixrowsep设置的范围(传递给的值row sep)在实际使用该值之前就结束了。

Henri Menke 提交了一份使固定此问题将在 PGF 的下一版本中解决。

同时,以下补丁将生效:

\makeatletter
\def\pgfmatrixendrow{%
  \let\pgf@matrix@signal@cell@end=\pgf@matrix@signal@cell@end
  \pgf@matrix@last@cell@in@rowtrue%
  \xdef\pgf@matrix@rowsep{\pgfmatrixrowsep}% <-- Define \pgf@matrix@rowsep globally
  &% <-- Scope ends here
  \pgf@matrix@correct@calltrue%
  \global\pgf@matrix@fixedfalse%
  \pgf@y=0pt%
  % The previous version used \pgfmatrixrowsep, which was reset at the &
  % \pgf@matrix@addtolength\pgf@y{\pgfmatrixrowsep}
  \pgf@matrix@addtolength\pgf@y{\pgf@matrix@rowsep}% <-- Now use the global def
  \pgfutil@ifnextchar[{\pgfmatrixendrow@skip}{\pgf@matrix@finish@line}%
}%
\makeatother

梅威瑟:

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{matrix}

\makeatletter
\def\pgfmatrixendrow{%
  \let\pgf@matrix@signal@cell@end=\pgf@matrix@signal@cell@end
  \pgf@matrix@last@cell@in@rowtrue%
  \xdef\pgf@matrix@rowsep{\pgfmatrixrowsep}%
  &\pgf@matrix@correct@calltrue%
  \global\pgf@matrix@fixedfalse%
  \pgf@y=0pt%
  \pgf@matrix@addtolength\pgf@y{\pgf@matrix@rowsep}%
  \pgfutil@ifnextchar[{\pgfmatrixendrow@skip}{\pgf@matrix@finish@line}%
}%
\makeatother

\begin{document}
\begin{tikzpicture}
\matrix (m) [matrix of math nodes,
            nodes={draw, font=\footnotesize, minimum size=1em,
                   anchor=center,inner sep=0pt},
                   column sep=-\pgflinewidth,
                   row sep=-\pgflinewidth,
                   every even column/.style={column sep=2pt},
                   every even row/.style={row sep=2pt},% doesn't insert row separation
                   inner sep=1pt,
                   left delimiter={[},right delimiter={]},
             ]
{
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
};
\end{tikzpicture}
\end{document}

答案2

问题在于范围。为了确保当前行的样式代码仅适用于当前行,样式代码在当前行的本地范围内执行。此范围在结束行并添加行分隔之前关闭,因此在应用值之前会将其还原。解决方案是将更改设为全局。row seprow sep将值存储在其中,\pgfmatrixrowsep因此我们将其全局定义为更新的值。由于此更改是全局的,因此它适用于所有行,因此我们需要一个every odd row将行分隔设置为零的键来将其切换回来。

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{matrix}

\begin{document}
\begin{tikzpicture}
\matrix (m) [matrix of math nodes,
            nodes={draw, font=\footnotesize, minimum size=1em,
                   anchor=center,inner sep=0pt},
                   column sep=-\pgflinewidth,
                   every even column/.style={column sep=2pt},
                   every even row/.style={/utils/exec=\gdef\pgfmatrixrowsep{2pt}},
                   every odd row/.style={/utils/exec=\gdef\pgfmatrixrowsep{-\pgflinewidth}},
                   inner sep=1pt,
                   left delimiter={[},right delimiter={]},
             ]
{
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
};
\end{tikzpicture}
\end{document} 

在此处输入图片描述

答案3

这更像是一个扩展的评论,而不是答案。评论涉及Hood Chathams 建议将维度全球化. 事情的经过如下:

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{matrix}

\begin{document}
\begin{tikzpicture}
\matrix (m) [matrix of math nodes,
            nodes={draw, font=\footnotesize, minimum size=1em,
                   anchor=center,inner sep=0pt},
                   inner sep=1pt,
                   left delimiter={[},right delimiter={]},
             ]
{
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
};
\end{tikzpicture}

\begin{tikzpicture}
\matrix (m) [matrix of math nodes,
            nodes={draw, font=\footnotesize, minimum size=1em,
                   anchor=center,inner sep=0pt},
                   column sep=-\pgflinewidth,
                   every even column/.style={column sep=2pt},
                   every even row/.style={/utils/exec=\gdef\pgfmatrixrowsep{2pt}},
                   every odd row/.style={/utils/exec=\gdef\pgfmatrixrowsep{-\pgflinewidth}},
                   inner sep=1pt,
                   left delimiter={[},right delimiter={]},
             ]
{
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
};
\end{tikzpicture}

\begin{tikzpicture}
\matrix (m) [matrix of math nodes,
            nodes={draw, font=\footnotesize, minimum size=1em,
                   anchor=center,inner sep=0pt},
                   inner sep=1pt,
                   left delimiter={[},right delimiter={]},
             ]
{
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
};
\end{tikzpicture}

\end{document} 

在此处输入图片描述

不过,我要强调的是,我真的很喜欢 Hood Chatham 的回答,因为它很好地解释了为什么会发生这种情况。我只想补充一点警告。

这是另一个建议。

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}
\matrix (m) [matrix of math nodes,
            nodes={draw, font=\footnotesize, minimum size=1em,
                   anchor=center,inner sep=0pt},
                   column sep=-\pgflinewidth,
                   row sep=\ifodd\pgfmatrixcurrentrow%
                   -\pgflinewidth%
                   \else%
                   2pt%
                   \fi,
                   every even column/.style={column sep=2pt},
                   left delimiter={[},right delimiter={]},
             ]
{
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
};
\end{tikzpicture}
\end{document}

在此处输入图片描述

它确实产生了所需的输出。但是,它还会产生以下类型的警告\end occurred when \ifx on line 21 was incomplete。所以我绝对不是说这个建议比 Hood Chathams 的建议更好。

当然,一个非常务实的解决方案是使用

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{matrix}

\begin{document}
\begin{tikzpicture}
\matrix (m) [matrix of math nodes,
            nodes={draw, font=\footnotesize, minimum size=1em,
                   anchor=center,inner sep=0pt},
                   column sep=-\pgflinewidth,
                   row sep=-\pgflinewidth,
                   every even column/.style={column sep=2pt},
                   inner sep=1pt,
                   left delimiter={[},right delimiter={]},
             ]
{
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\[2pt]
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
};
\end{tikzpicture}
\end{document}

答案4

评论:这个问题似乎已经固定的,因此你的 MWE 应该可以在该库的未来版本中工作matrix


我只是想简单提一下可以实现相同结果的另一种方法,因此您也可以将其视为扩展评论。

row sep和的值column sep在使用时实际上会传递到 pgf 数学引擎中,因此您可以分配一个取决于当前行/列号的值。以下内容应产生所需的输出:

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{matrix}

\begin{document}
\begin{tikzpicture}
\matrix (m) [matrix of math nodes,
            nodes={draw, font=\footnotesize, minimum size=1em,
                   anchor=center,inner sep=0pt},
                   row sep=iseven(\pgfmatrixcurrentrow)?2pt:-\pgflinewidth,
                   column sep=iseven(\pgfmatrixcurrentcolumn)?2pt:-\pgflinewidth,
                   inner sep=1pt,
                   left delimiter={[},right delimiter={]},
             ]
{
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
\alpha  & \beta   & \gamma  & \delta    \\
};
\end{tikzpicture}
\end{document}

输出

如果您不熟悉,该符号<condition>?<true branch>:<false branch>表示如果<condition>为真(实际上非​​零)<true branch>,则使用,<false branch>否则使用。函数isevenisodd(以及isprime,哇)记录在pgf 手册(在 Ti 版本中,第 1004 页第 99.3 节Z3.1)。

实际上,这有一个相当烦人的限制,这是因为 的参数row sep实际上被剥离了三对括号({…}),然后在数学引擎看到它之前在逗号处拆分(每个逗号分隔的项都单独应用)。这意味着您不能使用语法中包含逗号的函数,除非您将整个值包裹在至少四组括号中({{{{…}}}},更多也可以),如下所示:

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{matrix}

\begin{document}
\begin{tikzpicture}
\matrix (m) [matrix of math nodes,
            nodes={draw, font=\footnotesize, minimum size=1em,
                   anchor=center,inner sep=0pt},
                   row sep={{{{Mod(\pgfmatrixcurrentrow,3)?-\pgflinewidth:2pt}}}},
                   column sep={{{{Mod(\pgfmatrixcurrentcolumn,3)?-\pgflinewidth:2pt}}}},
                   inner sep=1pt,
                   left delimiter={[},right delimiter={]},
             ]
{
\alpha  & \beta   & \gamma  & \delta & \epsilon & \zeta & \eta   \\
\alpha  & \beta   & \gamma  & \delta & \epsilon & \zeta & \eta   \\
\alpha  & \beta   & \gamma  & \delta & \epsilon & \zeta & \eta   \\
\alpha  & \beta   & \gamma  & \delta & \epsilon & \zeta & \eta   \\
\alpha  & \beta   & \gamma  & \delta & \epsilon & \zeta & \eta   \\
\alpha  & \beta   & \gamma  & \delta & \epsilon & \zeta & \eta   \\
\alpha  & \beta   & \gamma  & \delta & \epsilon & \zeta & \eta   \\
};
\end{tikzpicture}
\end{document}

输出

相关内容