17

I'm trying to programmatically set the style of the columns of a TikZ matrix. My attempt is the following:

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

\begin{document}

\begin{tikzpicture}

\tikzstyle{mymatrix}=[draw]  
\foreach \c [count=\i] in {red, green, blue} {
    \globaldefs=1        % make tikz style global
    \tikzset{mymatrix/.append style={column \i/.style={nodes={fill=\c}}}}
}

\matrix (m) [matrix of nodes, mymatrix] {
 1 & 2 & 3 & 4 \\
 5 & 6 & 8 & 8 \\ };

\end{tikzpicture}

\end{document}

Unfortunately, this code does not compile because the commands \i and \c are undefined. My guess is that the style inside the for-loop has to be expanded inside the for-loop, but I don't know how to do this. Any ideas?

3 Answers 3

15

You can expand the variables by using an \edef to define a new command:

\documentclass{article}
\usepackage{pgfplots}
\usetikzlibrary{matrix}

\begin{document}

\begin{tikzpicture}

\tikzstyle{mymatrix}=[draw]  
\foreach \c [count=\i] in {red, green, blue} {
    \globaldefs=1 
    \edef\dotikzset{
        \noexpand\tikzset{
            mymatrix/.append style={
                column \i/.style={
                    nodes={fill=\c}
                }
            }
        }
    }
    \dotikzset
}

\matrix (m) [matrix of nodes, mymatrix] {
 1 & 2 & 3 & 4 \\
 5 & 6 & 8 & 8 \\ };

\end{tikzpicture}

\end{document}
0
10

Jake was faster but here is something I learned from egreg in this question :

\documentclass{article}
\usepackage{etoolbox}
\usepackage{tikz}
\usetikzlibrary{matrix}

\let\mystyle\empty
\newcommand{\populatestyle}{%
  \foreach \c [count=\i] in {red, green, blue} {
    \begingroup\edef\x{\endgroup
       \noexpand\gappto\noexpand\mystyle{column \i/.style={nodes={fill=\c}},}}\x
    }%
}
\populatestyle

\tikzset{mymatrix/.estyle={\mystyle}}

\begin{document}
\begin{tikzpicture}
\matrix (m) [matrix of nodes,mymatrix] {
 1 & 2 & 3 & 4 \\
  5 & 6 & 7 & 8 \\ };
\end{tikzpicture}
\end{document}

enter image description here

4
  • Interesting solution, I will keep this approach in mind, it might come in handy. Thanks!
    – yori
    Commented May 12, 2012 at 17:52
  • Why does the \endgroup command have to be inside the definition of \x?
    – yori
    Commented May 12, 2012 at 18:41
  • @Yori It's better to remove it anyway :) \edef\x{\noexpand\gappto\noexpand\mystyle{column \i/.style={nodes={fill=\c}},}}\x should work too.
    – percusse
    Commented May 12, 2012 at 19:31
  • Yes, I noticed; I just used your idea in a different part of my code. Works like a charm.
    – yori
    Commented May 12, 2012 at 19:33
1

This is a rather old question which has two excellent answers. Nevertheless, there might be some room for yet another answer which neither uses \globaldefs nor loads another package. (This answer has a weak point: if the list of colors has less entries than the matrix has rows, then there will be an error.)

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{matrix} 
\begin{document}
\begin{tikzpicture}[colorize cells/.style={/utils/exec={%
 \pgfmathsetmacro{\mycolor}{{#1}[\the\pgfmatrixcurrentcolumn-1]}
 \pgfkeysalso{/tikz/fill=\mycolor}}}]
 \matrix (m) [matrix of nodes,nodes={colorize cells={"red","green","blue","white"}}] {
 1 & 2 & 3 & 4 \\
 5 & 6 & 8 & 8 \\ };
\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 .