14

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}
3
  • 1
    How simple? [row 1/.style=red, row 3/.style=red] May 6, 2014 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=... ? May 6, 2014 at 15:57
  • You could create a new command, but it might get ugly. May 6, 2014 at 23:34

5 Answers 5

21

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

2
  • 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? May 7, 2014 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, 2014 at 8:33
9

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

1
  • Consider me considerably less fuzzy now. May 7, 2014 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}
2

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .