43

I would like to use TikZ matrices to for some drawings. I am currently using nodes and positioning them manually to simulate a tabular. That helps in positioning arrows and shading.

TikZ matrix

However, if I use something like the following code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}

\begin{tikzpicture}
\matrix [matrix of nodes,row sep=0,column 2/.style={nodes={rectangle,draw,minimum width=3em}}]
{
0   & 6 \\
1   & 3 \\
};
\end{tikzpicture}
\end{document}

The nodes' lower and upper borders do not overlap, resulting in a double border between nodes.

Double border

edit: Jake suggested a very nice solution, using negative row separation row sep. That work very well for one column tables. But the columns are misaligned when there are more columns.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\usetikzlibrary{positioning}
\begin{document}

\begin{tikzpicture}[cell/.style={rectangle,draw=black},
space/.style={minimum height=1.5em,matrix of nodes,row sep=-\pgflinewidth,column sep=-\pgflinewidth,column 1/.style={font=\ttfamily}}]

\matrix (first) [space, column 1/.style={font=\ttfamily},column 2/.style={nodes={cell,minimum width=2em}}]
{
0   & 6 \\
1   & 3 \\
2   & 9 \\
};

\matrix (second) [right=of first, space, column 2/.style={minimum width=3em,nodes={cell,minimum width=3.5em}},column 3/.style={nodes={cell,minimum width=2em}}]
{
0   &a  & 6 \\
1   &   & 3 \\
2   &c  & 9 \\
};

\matrix [right=of second, space, column 2/.style={minimum width=3em,nodes={cell,minimum width=3.5em}},column 3/.style={nodes={cell,minimum width=2em}}]
{
0   &a  & 6 \\
1   &b  & 3 \\
2   &c  & 9 \\
};
\end{tikzpicture}
\end{document}

enter image description here

2
  • 1
    It's a good idea to make your examples full compilable documents, starting from \documentclass. Otherwise everyone who tries to compile the example first has to figure out what packages are needed (it's not immediately obvious that \usetikzlibrary{positioning} is required here, for example), and then write an adequate .tex file.
    – Jake
    May 19 '11 at 9:27
  • 1
    Sorry, you are absolutely right. Matrix is also lacking. I will edit my question.
    – ipavlic
    May 19 '11 at 9:28
51

If you set row sep to -\pgflinewidth, the lines will overlap exactly:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}
\matrix [matrix of nodes,row sep=-\pgflinewidth,column 2/.style={nodes={rectangle,draw,minimum width=3em}}]
{
0   & 6 \\   1   & 3 \\   };
\end{tikzpicture}
\end{document}

matrix of nodes

In order to make sure that the cells align correctly horizontally, you need to make the text height and text depth the same across the entire row. By setting nodes in empty cells, all cells will be drawn, even if no content is provided. Alternatively, you can enter {} into empty cells to achieve the same effect.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix,positioning}
\begin{document}
\begin{tikzpicture}[cell/.style={rectangle,draw=black},
space/.style={minimum height=1.5em,matrix of nodes,row sep=-\pgflinewidth,column sep=-\pgflinewidth,column 1/.style={font=\ttfamily}},text depth=0.5ex,text height=2ex,nodes in empty cells]

\matrix (first) [space, column 1/.style={font=\ttfamily},column 2/.style={nodes={cell,minimum width=2em}}]
{
0   & 6 \\   1   & 3 \\   2   & 9 \\   };

\matrix (second) [right=of first, space, column 2/.style={minimum width=3em,nodes={cell,minimum width=3.5em}},column 3/.style={nodes={cell,minimum width=2em}}]
{
0   &a  & 6 \\   1   &   & 3 \\   2   &c  & 9 \\   };

\matrix [right=of second, space, column 2/.style={minimum width=3em,nodes={cell,minimum width=3.5em}},column 3/.style={nodes={cell,minimum width=2em}}]
{
0   &a  & 6 \\   1   &b  & 3 \\   2   &c  & 9 \\   };
\end{tikzpicture}
\end{document}

matrix tables with fixed text depth and text height

6
  • @Jake: A slight problem. What if some nodes are empty in a matrix of nodes. They then do not take up space, and various rows get misaligned.
    – ipavlic
    May 18 '11 at 19:46
  • @ipavlic: I'm not sure I understand what you mean. Could you edit your question to include an example?
    – Jake
    May 18 '11 at 19:51
  • @ipavlic: This behaviour is not because of the empty nodes, but because of the differing text height and text depth in your number and text nodes. I've edited my answer.
    – Jake
    May 19 '11 at 9:56
  • @Jake: I understand now, and also found more details in the documentation. Thank you very much!
    – ipavlic
    May 19 '11 at 10:19
  • @Jake, could you just include into your answer that when {} is inputed, the node is rendered with empty text. That is helpful when one wants to render all nodes, even the empty ones.
    – ipavlic
    May 19 '11 at 11:36
2

For information, the environment {NiceTabular} of nicematrix creates tabulars similar to {tabular} but with PGF/Tikz nodes under the cells, rows and columns. You can use those nodes with Tikz. However, you can also add rules in the tabular with the classical technics of {tabular} (eg: \hline).

In the following code, I have used the key hvlines which draws all the rules (excepted in the "first" column and "first" row).

\documentclass{article}
\usepackage{nicematrix,tikz}
\usetikzlibrary{arrows.meta}

\ExplSyntaxOn
\NewDocumentCommand \ValueMinusOne { m } { \int_eval:n { \int_use:c { c@#1 } - 1 } }
\ExplSyntaxOff

\begin{document}


\renewcommand{\arraystretch}{1.5}

\begin{NiceTabular}{>{\ttfamily}rc}[name=Left]
M         & \Block[draw]{} 0 \\
\\
L         & \Block[draw]{} 4 \\
\\
available & \Block[draw]{} 8 \\
\end{NiceTabular}\hspace{3cm}
\begin{NiceTabular}
  [
    first-col,
    code-for-first-col=\ValueMinusOne{iRow},
    first-row,
    hvlines,
    colortbl-like,
    name = Right
  ]
  {cc}  
& element & next \\
& \cellcolor{gray!30}
          & $6$  \\
& 1       & $3$  \\
& b       & $9$  \\
&         & $5$  \\
& \cellcolor{gray!30}
          & $7$  \\
&         & $-1$ \\
&         & $10$ \\
& a       & $2$  \\
&         & $11$ \\
& c       & $-1$ \\
& c       & $-1$ \\
&         & $1$  \\ 
\end{NiceTabular}

\begin{tikzpicture}[overlay,remember picture]
  \draw [->] (Left-1.5-|Left-last) to [bend right] (Right-1.5-|Right-1) ; 
  \draw [->] (Left-3.5-|Left-last) to [bend left] (Right-5.5-|Right-1) ; 
  \draw [->] (Left-5.5-|Left-last) to [bend left] (Right-9.5-|Right-1) ; 
\end{tikzpicture}

\end{document}

You need several compilations (because of the PGF/Tikz nodes).

Output of the above code

4
  • Would you mind explaining what \ValueMinusOne tries to achieve, and where do Left-3.5, Left-last come from?
    – green diod
    Nov 18 '21 at 13:04
  • @greendiod: \ValueMinusOne{n} computes n-1 . Left and Right are the names that I have decided to give to the environments {NiceTabular} that I have created (to give a name to a tabular, I have use the key name provided by nicematrix). 1.5, 2.5 , 3.5, etc. are numbers of the horizontal rules of the tabulars. In fact, when I write 3.5 (for instance), I specify the y-coordinate half-way between the horizontal rules 3 and 4 (that is to say the middle of the third row). Nov 18 '21 at 16:02
  • Thank you. I knew about east, west for nodes in the pgf/tikz last manual the last time I read it. I didn't know that one could refer to half-way rows. How would you specify x-coordinates? It's close to black magic! I'll check the 'nicematrix' package.
    – green diod
    Nov 22 '21 at 8:43
  • @greendiod: (i-|j) if the intersection of the horizontal rule number i and the vertical rule number j. You can use half values for both i and j (by design of nicematrix: this is not a general feature of Tikz). Nov 22 '21 at 12:13

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.