TikZ Colorize a matrix

This code

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

\usepackage{tikz}
\usetikzlibrary{matrix, positioning}

\tikzset{
matstyle/.style={
matrix of nodes,
nodes={
draw
}
}
}

\begin{document}

\begin{tikzpicture}

\matrix (I) [matstyle]
{
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
};

\draw [fill=red, fill opacity=0.5] (I-1-1.north west) rectangle (I-2-2.south east);
\draw [fill=green, fill opacity=0.5] (I-4-5.north west) rectangle (I-5-6.south east);

\end{tikzpicture}
\end{document}


produces the following output:

I would like to know how to colorize a predefined area of a matrix. The above approach has the disadvantage that I cannot set the color intensity to 100%, otherwise the matrix element disappears. What other possibilities are there to dye parts of a matrix?

You did already all the hard work. In order to go to full opacity, you only need to fill on the background layer, which comes with the backgrounds library.

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

\usepackage{tikz}
\usetikzlibrary{matrix, positioning,backgrounds}

\tikzset{
matstyle/.style={
matrix of nodes,
nodes={
draw
}
}
}

\begin{document}

\begin{tikzpicture}

\matrix (I) [matstyle]
{
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
};
\begin{scope}[on background layer]
\draw [fill=red] (I-1-1.north west) rectangle (I-2-2.south east);
\draw [fill=green] (I-4-5.north west) rectangle (I-5-6.south east);
\end{scope}
\end{tikzpicture}
\end{document}


It becomes slightly more appealing IMHO if you only fill but do not draw.

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

\usepackage{tikz}
\usetikzlibrary{matrix, positioning,backgrounds}

\tikzset{
matstyle/.style={
matrix of nodes,
nodes={
draw
}
}
}

\begin{document}

\begin{tikzpicture}

\matrix (I) [matstyle]
{
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
};
\begin{scope}[on background layer]
\fill[red] (I-1-1.north west) rectangle (I-2-2.south east);
\fill[green] (I-4-5.north west) rectangle (I-5-6.south east);
\end{scope}
\end{tikzpicture}
\end{document}


Here is an addendum in which all the lines have the same width (because there are negative values for column sep and row sep) and a style that slightly simplifies the filling. Now you "only" have to say \fill[red] (I-1-1) to[fill entries] (I-2-2); instead of \fill[red] (I-1-1.north west) rectangle (I-2-2.south east);. If you are willing to load the calc library, one could make this become "intelligent", i.e. find the appropriate anchors by itself.)

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

\usepackage{tikz}
\usetikzlibrary{matrix, positioning,backgrounds}

\tikzset{
matstyle/.style={
matrix of nodes,row sep=-\pgflinewidth,column sep=-\pgflinewidth,
nodes={
draw,
}
},fill entries/.style={to path=(\tikztostart.north west) rectangle
(\tikztotarget.south east)
}
}

\begin{document}

\begin{tikzpicture}

\matrix (I) [matstyle]
{
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
};
\begin{scope}[on background layer]
\fill[red] (I-1-1) to[fill entries] (I-2-2);
\fill[green] (I-4-5) to[fill entries] (I-5-6);
\end{scope}
\end{tikzpicture}
\end{document}


The same output can be achieved using the fit library, which is perhaps the most elegant option.

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

\usepackage{tikz}
\usetikzlibrary{matrix, positioning,backgrounds,fit}

\tikzset{
matstyle/.style={
matrix of nodes,row sep=-\pgflinewidth,column sep=-\pgflinewidth,
nodes={
draw,
}
}
}

\begin{document}

\begin{tikzpicture}

\matrix (I) [matstyle]
{
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
};
\begin{scope}[on background layer]
\node[fill=red,fit=(I-1-1) (I-2-2),inner sep=0pt]{};
\node[fill=green,fit=(I-4-5)  (I-5-6),inner sep=0pt]{};
\end{scope}
\end{tikzpicture}
\end{document}

• Great answer! What is the difference between \fill and \draw? Jan 3, 2019 at 19:37
• @Samuel \draw also draws the contour. If you look very carefully at the upper screen shot, you see that the boundaries of the red fill slightly overshoot, i.e. the matrix becomes wider and higher around this area. If this is what you want, use \draw, if not, use \fill, which does not draw the contour.
– user121799
Jan 3, 2019 at 19:39

As marmot has was much faster, I propose an alternative with pgf layers (see pages 1080; 1081 of manual 3.0.1a) .

Here, I place the matrix in the foreground (for a change).

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

\usepackage{tikz}
\usetikzlibrary{matrix, positioning}
%\usetikzlibrary{backgrounds}
\tikzset{
matstyle/.style={
matrix of nodes,
nodes={
draw
}
}
}
%\pgfdeclarelayer{background layer}
\pgfdeclarelayer{foreground layer}
\pgfsetlayers{main,foreground layer}
\begin{document}

\begin{tikzpicture}
\begin{pgfonlayer}{foreground layer}
\matrix (I) [matstyle]
{
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
};
\end{pgfonlayer}
%\begin{scope}[on background layer]
\draw [fill=red] (I-1-1.north west) rectangle (I-2-2.south east);
\draw [fill=green] (I-4-5.north west) rectangle (I-5-6.south east);
%\end{scope}
\end{tikzpicture}
\end{document}


Another alternative consists in applying specific styles to desired cells. You can use |[style]| expression before each cell contents to apply this style to the cell.

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

\usepackage{tikz}
\usetikzlibrary{matrix, positioning}

\tikzset{
matstyle/.style={
matrix of nodes,
nodes={
draw
}
}
}

\begin{document}

\begin{tikzpicture}

\matrix (I) [matstyle]
{
|[fill=red]|0 & |[fill=red]|0 & 0 & 0 & 0 & 0 & 0 & 0\\
|[fill=red]|0 & |[fill=red]|0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 &|[fill=green]| 1 &|[fill=green]| 0 & 0 & 0\\
0 & 0 & 1 & 0 &|[fill=green]| 1 &|[fill=green]| 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
};

\end{tikzpicture}
\end{document}


You can save some typing declaring the style:

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

\usepackage{tikz}
\usetikzlibrary{matrix, positioning}

\tikzset{
matstyle/.style={
matrix of nodes,
nodes={
draw
}
},
r/.style={fill=red},
g/.style={fill=green}
}

\begin{document}

\begin{tikzpicture}

\matrix (I) [matstyle]
{
|[r]|0 & |[r]|0 & 0 & 0 & 0 & 0 & 0 & 0\\
|[r]|0 & |[r]|0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 &|[g]| 1 &|[g]| 0 & 0 & 0\\
0 & 0 & 1 & 0 &|[g]| 1 &|[g]| 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
};

\end{tikzpicture}
\end{document}


Another option could be to declare an style which can be applied with a .list (see TikZ matrix, style for combination or rows and columns)

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

\usepackage{tikz}
\usetikzlibrary{matrix, positioning}

\tikzset{
matstyle/.style={
matrix of nodes,
row sep=-\pgflinewidth,
column sep=-\pgflinewidth,
nodes={
draw
}
},
redset/.style args ={(#1,#2)}{%
row #1 column #2/.style={nodes={fill=red}}},
greenset/.style args ={(#1,#2)}{%
row #1 column #2/.style={nodes={fill=green}}}
}

\begin{document}

\begin{tikzpicture}

\matrix (I) [matstyle, redset/.list={(1,1),(1,2),(2,1),(2,2)}, greenset/.list={(4,5),(4,6),(5,5),(5,6)}]
{
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
};

\end{tikzpicture}
\end{document}