11

In the TikZ manual we have the example below that shows how to apply an style to an entry of the matrix. It is also easy to apply it for an entire row and an entire column. My question is how can we achieve the same for several entries? Is there a simple way to specify a style, say for example, rows 1 & 3 and columns 1 & 2?

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}[row 2 column 3/.style=red]
\matrix [matrix of nodes]
{
 8 & 1 & 6 \\
 3 & 5 & 7 \\
 4 & 9 & 2 \\
  };
 \end{tikzpicture}
 \end{document}
  • 1
    How simple? [row 1/.style=red, row 3/.style=red] – John Kormylo May 6 '14 at 13:32
  • @JohnKormylo: Thanks but say the style is very long to type, is there a way to make it even simpler? Something like: row 1,3 /.style=... ? – Sergio Parreiras May 6 '14 at 15:57
  • You could create a new command, but it might get ugly. – John Kormylo May 6 '14 at 23:34
15

You can use the /.list feature John Kormylo mentioned in his answer to repeat a style for different inputs.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\tikzset{myset/.style={row 2 column #1/.style={nodes={text=red}}}}
\begin{tikzpicture}[myset/.list={1,3,5}]
\matrix [matrix of nodes]
{
 8 & 1 & 6 & 8 & 1 & 6 \\
 3 & 5 & 7 & 3 & 5 & 7 \\
 4 & 9 & 2 & 4 & 9 & 2 \\
  };
\end{tikzpicture}
\end{document}

enter image description here

  • list will be very useful for other projects, thanks! By any chance, besides the manual do you have any suggestions on references for TikZ programming? – Sergio Parreiras May 7 '14 at 8:32
  • 1
    @SergioParreiras Manual is very very good. I would say answer questions here :P It gives you a lot of practice and gives a chance to see others do their black magic. – percusse May 7 '14 at 8:33
8

More a long comment than a real answer... Based on percusse's answer, this style allows to specify both row and column.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\tikzset{myset/.style args = {(#1,#2)}{%
    row #1 column #2/.style={nodes={text=red}}}}
\begin{tikzpicture}[myset/.list={(2,1),(3,3),(1,5)}]
\matrix [matrix of nodes]
{
 8 & 1 & 6 & 8 & 1 & 6 \\
 3 & 5 & 7 & 3 & 5 & 7 \\
 4 & 9 & 2 & 4 & 9 & 2 \\
  };
\end{tikzpicture}
\end{document}

enter image description here

7

This can be done via \foreach indeed, but since the keys set with \pgfkeys are not global, their assignment are lost when the loop is exited. Unless you mess with \globaldef, as in the following example:

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

\newcommand{\rows}[2]{% #1 = rows, #2 = style
\foreach \r in {#1} {%
  \globaldefs=1\relax
  \tikzset{row \r/.style={#2}}
}%
}

\newcommand{\cols}[2]{% #1 = columns, #2 = style
\foreach \r in {#1} {%
  \globaldefs=1\relax
  \tikzset{column \r/.style={#2}}
}%
}

\begin{tikzpicture}
\cols{1,3}{blue}
\rows{1,3}{red}
\matrix [matrix of nodes]
{
 8 & 1 & 6 \\
 3 & 5 & 7 \\
 4 & 9 & 2 \\
  };
 \end{tikzpicture}
\end{document}

Result

  • Consider me considerably less fuzzy now. – John Kormylo May 7 '14 at 14:06
2

Interestingly, you cannot do this using \foreach. I understand this is because \foreach is actually implemented using \pgfkeys using the /.list={...} feature, but I'm a bit fuzzy on the details.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}

\newcommand{\row}[2]{% #1 = row, #2 = style
\tikzset{row #1/.style={#2}}}

\newcommand{\col}[2]{% #1 = column, #2 = style
\tikzset{column #1/.style={#2}}}

\begin{document}
\begin{tikzpicture}
\row{1}{red}
\row{3}{red}
\col{1}{blue}
\col{3}{blue}
\matrix [matrix of nodes]
{
 8 & 1 & 6 \\
 3 & 5 & 7 \\
 4 & 9 & 2 \\
  };
 \end{tikzpicture}
 \end{document}
1

I reopen this old questions because, from percusse's and cjorssen's answers, I managed to assign style to a block of cells only specifying its (top,left to bottom,right) coordinates. I share here my solution, hoping it will help someone else.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\tikzset{myblocks/.style args = {(#1,#2 to #3,#4)}{
            blockrows/.style={
                block/.style={
                    row ##1 column ####1/.style={nodes={text=red}}
                },
                block/.list={#2,...,#4}
            },
            blockrows/.list={#1,...,#3}
        }
}
\begin{tikzpicture}[myblocks/.list={(1,1 to 2,2),(1,4 to 3,5)}]
\matrix [matrix of nodes]
{
 8 & 1 & 6 & 8 & 1 & 6 \\
 3 & 5 & 7 & 3 & 5 & 7 \\
 4 & 9 & 2 & 4 & 9 & 2 \\
  };
\end{tikzpicture}
\end{document}

enter image description here

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.