2

I'm having an issue with matrix names in tikz being "persistent".

Consider the two matrices:

enter image description here

These matrices were generated with the following code:

\documentclass[border=12pt]{standalone}

\usepackage{tikz} \usetikzlibrary{matrix}

\begin{document} $ \begin{tikzpicture} \matrix[ , matrix of math nodes , left delimiter = {[} , right delimiter = {]} ] (m) { 1 & -32 & 0 & 15 \ 16 & -138 & -3 & 5 \ 4 & 14 & 11 & 19 \ }; \end{tikzpicture} $ $ \begin{tikzpicture} \matrix[ , matrix of math nodes , left delimiter = {[} , right delimiter = {]} ] (a) { 1 \ 16 \ 4 \ };

\draw[red, thick] (m-1-4) -- (m-3-1); \end{tikzpicture} $

\end{document}

The two matrices are constructed in different tikzpicture environments. The one on the left is named m and the one on the right is named a.

The second tikzpicture has a \draw command that references nodes in a matrix from a previous tikzpicture. I actually want this code to throw an error, since this tikzpicture has no matrix named m.

Is it possible to ask tikz to "forget" the matrix m?

  • 1
    In TikZ all coordinates are global. So they do not get forgotten even if you start a new tikzpicture or even if you go on the next page. So the answer is no. You can create mechanisms that produce the error message by installing some coordinate prefixes, say. –  Nov 12 '20 at 20:51
  • @abcdefg Interesting. It sound then like the best solution is to just give every matrix a different name. Still, this will get annoying as my document grows... – Brian Fitzpatrick Nov 12 '20 at 22:12
  • 1
    You could generate individual tikz graphs in standalone documentclass, and just \includegraphics the result. That way, no residue of the original code would be in the document. – Steven B. Segletes Nov 18 '20 at 18:47

3 Answers3

3

Strictly speaking, this is not an answer to the question of the OP but it may be useful.

Since the OP uses the Tikz library matrix, he should have a look at nicematrix. The environments of that extension create matrices with a Tikz node for each cell of the matrix (and also Tikz nodes for the position of the potential rules, which the Tikz module matrix doesn't do).

It's possible to use those nodes with a syntax i-j for the node of the cell in row i and column j. There is no name of the matrix (those names are valid only in the current matrix, that is to say in the current environment).

So, there is no risk to refer by accident to a node in another matrix.

For example, with the following code, we will have an error since there is no node 1-4 in the current matrix (there is one in the previous one but that does not interfer).

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

\begin{document} $ \begin{pNiceMatrix} 1 & -32 & 0 & 15 \ 16 & -138 & -3 & 5 \ 4 & 14 & 11 & 19 \ \end{pNiceMatrix} $ $ \begin{bNiceMatrix} 1 \ 16 \ 4 \ \CodeAfter \tikz \draw [red, thick] (1-4) -- (3-1) ; % error : there is no node (1-4) \end{bNiceMatrix} $

\end{document}

F. Pantigny
  • 40,250
2

In TikZ all coordinates are global. So they do not get forgotten even if you start a new tikzpicture or even if you go on the next page. So the answer is no. You can create mechanisms that produce the error message by installing some coordinate prefixes, say. Here is a code that installs a unique prefix in every tikzpicture. Please use with care if you decide to use it.

\documentclass[border=12pt]{standalone}

\usepackage{tikz} \usetikzlibrary{matrix} \newcounter{TikZpicture} \tikzset{every picture/.append style={step tikz counter, name prefix=pic-\number\value{TikZpicture}}, step tikz counter/.code={\stepcounter{TikZpicture}}}

\begin{document} $ \begin{tikzpicture} \matrix[ , matrix of math nodes , left delimiter = {[} , right delimiter = {]} ] (m) { 1 & -32 & 0 & 15 \ 16 & -138 & -3 & 5 \ 4 & 14 & 11 & 19 \ }; \end{tikzpicture} $ $ \begin{tikzpicture} \matrix[ , matrix of math nodes , left delimiter = {[} , right delimiter = {]} ] (a) { 1 \ 16 \ 4 \ };

\draw[red, thick] (m-1-4) -- (m-3-1); \end{tikzpicture} $

\end{document}

2

It turns out that TikZ nodes are stored as 5 global macros. I can't actually delete nodes, but I can alias them to all be the same (nonexistent) node. Presumably the now unused global macros will be released as with \global\let\foo=\relax.

\documentclass[border=12pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}

\makeatletter \newcommand{\removenode}[1]% #1 = node name {\bgroup \let\pgf@nodecallback=\pgfutil@gobble% \pgfnodealias{#1}{}% node () \egroup} \newcommand{\removematrix}[3]% #1 = matrix name, #2 = number rows, #3 = number columns {\bgroup% use local \i and \j \let\pgf@nodecallback=\pgfutil@gobble% \foreach \i in {1,...,#2}{% \foreach \j in {1,...,#3}{\pgfnodealias{#1-\i-\j}{}}}% \pgfnodealias{#1}{}% \egroup} \makeatother

\begin{document} \begin{tikzpicture}[baseline=(current bounding box.center)] \matrix[ , matrix of math nodes , left delimiter = {[} , right delimiter = {]} ] (m) { 1 & -32 & 0 & 15 \ 16 & -138 & -3 & 5 \ 4 & 14 & 11 & 19 \ }; \end{tikzpicture}

\removematrix{m}{3}{4}%

\begin{tikzpicture}[baseline=(current bounding box.center)] \matrix[ , matrix of math nodes , left delimiter = {[} , right delimiter = {]} ] (a) { 1 \ 16 \ 4 \ }; \draw[red, thick] (m-1-4) -- (m-3-1); \end{tikzpicture} \end{document}


BTW, a faster but less readable version of \removematrix follows.

\newcommand{\removematrix}[3]% #1 = matrix name, #2 = number rows, #3 = number columns
{\bgroup% use local registers
  \let\pgf@nodecallback=\pgfutil@gobble%
  \count1=#2\relax
  \loop\ifnum\count1>0{% one loop per group
    \count2=#3\relax
    \loop\ifnum\count2>0
      \edef\nodename{#1-\number\count1-\number\count2}%
      \pgfnodealias{\nodename}{}%
      \advance\count2 by -1
    \repeat}%
    \advance\count1 by -1
  \repeat
  \pgfnodealias{#1}{}%
\egroup}
John Kormylo
  • 79,712
  • 3
  • 50
  • 120