# Draw lines inside a matrix

I have the following code to draw a matrix:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}[cell/.style={rectangle,draw=black}, nodes in empty cells]
\matrix[
matrix of math nodes,
row sep =-\pgflinewidth,
column sep = -\pgflinewidth,
nodes={anchor=center, minimum width=2cm, cell},
column 1/.style = {nodes={minimum width=1cm, fill=mlightgray}},
column 2/.style = {nodes={minimum width=3.2cm}},
column 3/.style = {nodes={minimum width=3.2cm}},
row 1/.style = {nodes={text height=1.3ex, text depth=0, fill=mlightgray}},
row 2/.style = {text height=1.3ex, text depth=0},
row 3/.style = {text height=1.3ex, text depth=0},
row 4/.style = {text height=1.3ex, text depth=0},
]
{   &  \text{1} & \text{2}  \\
\text{1} & & \\
\text{2} & & \\
\text{3} & & \\
};
\end{tikzpicture}
\end{document}


Now, I would like to draw lines among cells to realise the following (which was generated by pspicture, but I want to convert everything to tikz):

Is it possible?

PS: I don't need a general solution, just being able to realise this figure will be fine.

• Section 57 on page 654 of the 3.0.0 manual describes what you need... simply name the matrix and then you can \draw (name-row-cell) -- (name-row-cell); – darthbith Apr 6 '15 at 1:00

You can label the matrix and then use the (m-1-2) syntax to draw. It means the first row and second column of matrix (m) (i.e., 1-2 are indices of the entry).

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}[cell/.style={rectangle,draw=black}, nodes in empty cells]
\matrix[
matrix of math nodes,
row sep =-\pgflinewidth,
column sep = -\pgflinewidth,
nodes={anchor=center, minimum width=2cm, cell},
column 1/.style = {nodes={minimum width=1cm, fill=lightgray}},
column 2/.style = {nodes={minimum width=3.2cm}},
column 3/.style = {nodes={minimum width=3.2cm}},
row 1/.style = {nodes={text height=1.3ex, text depth=0, fill=lightgray}},
row 2/.style = {text height=1.3ex, text depth=0},
row 3/.style = {text height=1.3ex, text depth=0},
row 4/.style = {text height=1.3ex, text depth=0},
](m)
{   &  1 & 2  \\
1 & \bullet & \bullet \\
2 & \bullet & \bullet \\
3 & \bullet & \bullet \\
};
\draw[-latex] (m-4-3.center) -- (m-3-2.center);
\draw[-latex] (m-4-3.center) -- (m-3-3.center);
\draw[-latex] (m-3-2.center) -- (m-2-2.center);
\draw[-latex] (m-3-3.center) -- (m-2-2.center);
\end{tikzpicture}
\end{document}


• I guess it would be a little bit better if the bullets are made as circle nodes. (So arrows will not overlap it.) – Symbol 1 Apr 6 '15 at 14:50

A fully automated PSTricks solution:

\documentclass{article}

\usepackage{multido}
\usepackage{pstricks}
\usepackage{xfp}

% settings
\psset{
dimen = m,
fillcolor = gray!60
}

% parameters
\def\Columns{2}
\def\ColumnWidth{3}
\def\Rows{3}
\def\RowHeight{0.7}

\begin{document}

\begin{pspicture}(\fpeval{\Columns*\ColumnWidth+1},\fpeval{(\Rows+1)*\RowHeight})
\multido{\r = 0+\RowHeight}{\fpeval{\Rows+1}}{%
\psframe[fillstyle = solid](0,\r)(1,\fpeval{\r+\RowHeight})%
}
\multido{
\rE = 0+\RowHeight,
\rF = \fpeval{0.5*\RowHeight}+\RowHeight,
\iB = \Rows+-1
}{\Rows}{%
\multido{
\rA = 1+\ColumnWidth,
\rB = \fpeval{0.5*\ColumnWidth+1}+\ColumnWidth,
\rC = \fpeval{0.5*\RowHeight}+\RowHeight,
\rD = \fpeval{1.5*\RowHeight}+-\RowHeight,
\iA = 1+1
}{\Columns}{%
\psframe[fillstyle = solid]%
(\rA,\fpeval{\Rows*\RowHeight})%
(\fpeval{\rA+\ColumnWidth},\fpeval{(\Rows+1)*\RowHeight})
\rput(\rB,\fpeval{(\Rows+0.5)*\RowHeight}){$\iA$}
\psframe(\rA,\rE)(\fpeval{\rA+\ColumnWidth},\fpeval{\rE+\RowHeight})
\rput(\rB,\rF){\psdot}}
\rput(0.5,\rF){$\iB$}}
\psline{->}(\fpeval{1+(\Columns-0.5)*\ColumnWidth},\fpeval{0.5*\RowHeight})%
(\fpeval{1+0.5*\ColumnWidth},\fpeval{(\Rows-1.5)*\RowHeight})
\psline{->}(\fpeval{1+0.5*\ColumnWidth},\fpeval{(\Rows-1.5)*\RowHeight})%
(\fpeval{1+0.5*\ColumnWidth},\fpeval{(\Rows-0.5)*\RowHeight})
\psline{->}(\fpeval{1+(\Columns-0.5)*\ColumnWidth},\fpeval{0.5*\RowHeight})%
(\fpeval{1+(\Columns-0.5)*\ColumnWidth},\fpeval{1.5*\RowHeight})
\psline{->}(\fpeval{1+(\Columns-0.5)*\ColumnWidth},\fpeval{1.5*\RowHeight})%
(\fpeval{1+0.5*\ColumnWidth},\fpeval{(\Rows-0.5)*\RowHeight})
\end{pspicture}

\end{document}


All you have to do is change the values of the parameters and the drawing will be adjusted accordingly.

Update

If you want a macro, here is how it can be done:

\documentclass{article}

\usepackage{multido}
\usepackage{pstricks}
\usepackage{xfp}

% settings
\psset{
dimen = m,
fillcolor = gray!60
}

% \Table[<cell width>,<cell height>]{<number of columns}{<number of rows>}
\def\Table[#1,#2]#3#4{%
\begin{pspicture}(\fpeval{#3*#1+1},\fpeval{(#4+1)*#2})
\multido{\r = 0+#2}{\fpeval{#4+1}}{%
\psframe[fillstyle = solid](0,\r)(1,\fpeval{\r+#2})%
}
\multido{
\rE = 0+#2,
\rF = \fpeval{0.5*#2}+#2,
\iB = #4+-1
}{#4}{%
\multido{
\rA = 1+#1,
\rB = \fpeval{0.5*#1+1}+#1,
\rC = \fpeval{0.5*#2}+#2,
\rD = \fpeval{1.5*#2}+-#2,
\iA = 1+1
}{#3}{%
\psframe[fillstyle = solid]%
(\rA,\fpeval{#4*#2})%
(\fpeval{\rA+#1},\fpeval{(#4+1)*#2})
\rput(\rB,\fpeval{(#4+0.5)*#2}){$\iA$}
\psframe(\rA,\rE)(\fpeval{\rA+#1},\fpeval{\rE+#2})
\rput(\rB,\rF){\psdot}}
\rput(0.5,\rF){$\iB$}}
\psline{->}(\fpeval{1+(#3-0.5)*#1},\fpeval{0.5*#2})%
(\fpeval{1+0.5*#1},\fpeval{(#4-1.5)*#2})
\psline{->}(\fpeval{1+0.5*#1},\fpeval{(#4-1.5)*#2})%
(\fpeval{1+0.5*#1},\fpeval{(#4-0.5)*#2})
\psline{->}(\fpeval{1+(#3-0.5)*#1},\fpeval{0.5*#2})%
(\fpeval{1+(#3-0.5)*#1},\fpeval{1.5*#2})
\psline{->}(\fpeval{1+(#3-0.5)*#1},\fpeval{1.5*#2})%
(\fpeval{1+0.5*#1},\fpeval{(#4-0.5)*#2})
\end{pspicture}}

\begin{document}

\Table[3,0.7]{2}{3}

\end{document}

\end{document}