5

Consider the following matrix

enter image description here

This matrix was produced with the code

\begin{tikzpicture}
  \matrix[
  , matrix of nodes
  , left delimiter={[},right delimiter = {]}
  ] (m)
  {
    * & * & * & * \\
    * & * & * & * \\
    * & * & * & * \\
  };

\node at (m-2-4) {\textbullet};

\end{tikzpicture}

The dot in the (1, 4) position was placed with \node at (m-1-4) {\textbullet};.

I might want to add columns to this matrix, but I want the dot to remain in the last column. I'm curious if it is possible to programatically refer to the last column of this matrix with a syntax like \node at (m-1-last column index) {\textbullet};. Is this possible?

2 Answers2

8

pgf has the counts \pgfmatrixcurrentrow and \pgfmatrixcurrentcolumn, which get reset whenever you start a new matrix. So if you inspect the counts right after a matrix, it they will contain the number of rows and columns. Otherwise you can store them in macros. However, in your example you need only

\documentclass[tikz,border=3mm]{standalone}

\usetikzlibrary{matrix}

\begin{document} \begin{tikzpicture} \matrix[ , matrix of nodes , left delimiter={[},right delimiter = {]} ] (m) { * & * & * & * \ * & * & * & * \ * & * & * & * \ };

\node at (m-2-\the\pgfmatrixcurrentcolumn) {\textbullet};

\end{tikzpicture} \end{document}

enter image description here

If the number of columns is smaller than the maximum in the last row, the above method fails. You can define styles for this case. Starting from pgf version 3.1.6 there is a method that allows you to smuggle the results out of the path. You can then retrieve them after using some appropriate pop.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{matrix}
\makeatletter
\tikzset{record number of columns in/.style={execute at end matrix={%
\edef#1{\the\pgf@matrix@numberofcolumns}%
\pgfutil@pushmacro#1}},
record number of rows in/.style={execute at end matrix={%
\edef#1{\the\pgfmatrixcurrentrow}%
\pgfutil@pushmacro#1}}
}
\newcommand\pgfpop[1]{\pgfutil@popmacro#1}
\makeatother
\begin{document}
\begin{tikzpicture}
  \matrix[matrix of nodes,
  left delimiter={[},right delimiter = {]},
  record number of columns in=\mycols,
  record number of rows in=\myrows
  ] (m)
  {
    * & * & * & * \\
    * & * & * & * \\
    * & * & * & * \\
  };
  \pgfpop\mycols
  \pgfpop\myrows
  \node[anchor=center] at (m-2-\mycols.center) {\textbullet};
\end{tikzpicture}
\end{document}

Alternatively you can introduce new counts.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{matrix}
\newcount\tikzmatrixrows
\newcount\tikzmatrixcols
\makeatletter
\tikzset{record matrix dimensions/.style={execute at end matrix={%
\global\tikzmatrixcols=\pgf@matrix@numberofcolumns
\global\tikzmatrixrows=\pgfmatrixcurrentrow}}}
\makeatother
\begin{document}
\begin{tikzpicture}
  \matrix[matrix of nodes,
  left delimiter={[},right delimiter = {]},
  record matrix dimensions
  ] (m)
  {
    * & * & * & * \\
    * & * & * & * \\
    * & * & * & * \\
  };
  \node[anchor=center] at (m-2-\the\tikzmatrixcols.center) {\textbullet};
\end{tikzpicture}
\end{document}

Finally, you do not need to know the number explicitly.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}
  \matrix[matrix of nodes,nodes={alias=m-\the\pgfmatrixcurrentrow-last},
  left delimiter={[},right delimiter = {]}
  ] (m)
  {
    * & * & * & * \\
    * & * & * & * \\
    * & * & * & * \\
  };

\node at (m-2-last) {\textbullet};

\end{tikzpicture} \end{document}

2

Strictly speaking, this is not an answer to the question, but maybe some people will be interested to see that this feature is directly available in the environments of nicematrix (which create PGF/Tikz nodes under the cells of the matrix).

\documentclass{article}
\usepackage{nicematrix}
\usepackage{tikz}

\begin{document}

$\begin{pNiceMatrix} * & * & * & * \ * & * & * & * \ * & * \ \CodeAfter \tikz \node at (1-last) {$\bigcirc$}; \end{pNiceMatrix}$

\end{document}

Output of the above code

F. Pantigny
  • 40,250