TikZ matrix, why doesn't "every even row" work with "row sep" option?
The issue is with scopes. In order to make sure that the style code for the current row only applies to the current row, the style code is executed inside of a scope that is local to the current row. This scope is closed prior to ending the row and adding the row separation, so the value is reverted before it is applied. The solution is to make the change to the row sep
global. The key row sep
stores the value in \pgfmatrixrowsep
so we globally define this to be the updated value. Because this change is global, it applies to all rows going forward, so we need an every odd row
key setting the row sep to zero to switch it back.
\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}
This is more an extended comment than an answer. The comment concerns Hood Chathams proposal to make the dimensions global. Here is what happens:
\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}
Let me, however, stress that I really like the answer by Hood Chatham as a whole as it has a very nice explanation for why this happens. I just want add a word of caution.
Here is another proposal.
\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}
It does produce the desired output. However, it also produces warnings of the type \end occurred when \ifx on line 21 was incomplete
. So I am definitely not claiming this proposal is better than Hood Chathams suggestion.
Of course, a very pragmatic solution would be to use
\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}
Remark: This problem appears to have been fixed, so
your MWE should work in some future version of the matrix
library.
I just wanted to briefly mention another way in which the same result could be accomplished, so you may also consider this an extended comment.
The values of row sep
and column sep
are actually passed into the pgf math engine when they're used, so you can assign a value that depends on the current row/column number.
The following should produce the desired output:
\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}
In case you're not familiar with it, the notation <condition>?<true branch>:<false branch>
means that if <condition>
is true (non-zero,actually) the <true branch>
is used and that the <false branch>
is used otherwise.
The functions iseven
and isodd
(and also isprime
, wow) are documented in the pgf manual (in §99.3 on p1004 in the version for TikZ 3.1).
There is actually one rather annoying limitation to this, which is due the fact that the argument of row sep
is actually stripped of three pairs of braces ({…}
) and then split at comma's before the math engine gets to see it (each comma-separated term is applied separately).
This means that you can't use functions whose syntax includes a comma unless you wrap the entire value in at least four sets of braces ({{{{…}}}}
, more is also okay), like this:
\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}