5

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:

enter image description here

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?

6

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}

enter image description here

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}

enter image description here

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}

enter image description here

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}
| improve this answer | |
  • Great answer! What is the difference between \fill and \draw? – recipe_for_disaster Jan 3 '19 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 '19 at 19:39
2

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).

matrix

\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}
| improve this answer | |
2

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}

enter image description here

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}
| improve this answer | |

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.