6

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):

enter image description here

Is it possible?

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

  • 1
    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
9

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}

enter image description here

  • 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
3

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}

output

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}

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.