TikZ Colorize 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}
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}