8

I need a 4*4 grid to fill with selected colors. Basically, I am in search of a \newcommand, like this:

\newcommand{\mygrid}{11/blue, 32/brown} %coordinates/color is passed

which will produce the following grid:

.

Similar questions were asked before:

  1. Dynamically filling a grid with TikZ from a data array
  2. Drawing grids filled with random selected colors and connecting them
  3. Drawing a multicolored grid using TikZ

I tried to start from answers from all the questions, but got lost midway. Any help will be appreciated.

EDIT This is the last workable version I was trying (from here):

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\pgfmathdeclarerandomlist{MyRandomColors}{%
    {red}%
    {red!25}%
    {magenta}%
    {magenta!25}%
    {olive}%
    {olive!25}%
    {brown}%
    {brown!10}%
    {violet}%
    {violet!25}%
    {gray}%
    {purple}%
    {yellow}%
    {orange}%
    {orange!25}%
    {cyan}%
    {green}%    
}%

\newcommand*{\GridSize}{4}

\newcommand*{\ColorCells}{%
    \foreach \y in {1,...,\GridSize} {
        \foreach \x in {1,...,\GridSize} {
            \pgfmathrandomitem{\RandomColor}{MyRandomColors} 
            \node [fill=\RandomColor, fill opacity=0.4, draw=none, thick, minimum size=1cm] 
                at (\x-.5,\y-.5)
                {\x\y};
        }%
    }%
}%

%%%%%


%\listfiles
\begin{document}
\begin{tikzpicture}[scale=1]

    \begin{scope}[thick,]
        \ColorCells
        \draw (0, 0) grid (\GridSize, \GridSize);
        \coordinate (input);
    \end{scope}


\end{tikzpicture}
\end{document}

EDIT 2 Here's another (based on this) [argument 2 supports placing of grids to a preferred location]:

\documentclass{standalone}
\usepackage{tikz,amsmath}
\usetikzlibrary{positioning,backgrounds,shadings,calc,patterns, decorations.pathreplacing, fit, arrows}
\newcommand{\vrect}[3]{

%   \foreach \mark/\colorname [count=\k] in {#3}{
%       \ifnum\mark=34 \def\mycolorname{\colorname}\fi
%   }

    \foreach \x in {1,...,4}{
        \foreach \y in {1,...,4} {
            \foreach \px\py in {#2}{
            \node[draw=gray, fill=red!30,thick, minimum size=1cm,  anchor=mid,
            ] (z#1\x\y\px\py) at ($(\y,-\x)+(\px,\py)$) {#1\x\y\px\py}; %
        }
    }
    }
}


\begin{document}
    \begin{tikzpicture}[scale=1]
    \vrect{0}{6/6}{12/red,11/green}
    \end{tikzpicture}

\end{document}
8
  • Please show us what you had when you got lost. Commented Sep 8, 2017 at 16:03
  • To the down-voter: please some comments so that I can improve my question. I tried many things, it's impossible to show anything in particular.
    – hola
    Commented Sep 8, 2017 at 16:04
  • @BenjaminMcKay Well, I started from the 2nd answer of the first linked question. Modified the BITARRAY. Tried to get the values from the method I just learnt (tex.stackexchange.com/q/390398/38244). Tried to change the fill color in many ways..... Then, tried the first answer in many angles I could try with my little knowledge.... Switched to answer to the 2nd linked question, tried many things... Do you want me to paste some of the non-working codes?
    – hola
    Commented Sep 8, 2017 at 16:07
  • @BenjaminMcKay It's over five hours now... I lost count what/how many tweaks I tried.
    – hola
    Commented Sep 8, 2017 at 16:08
  • 1
    You desired syntax, \newcommand{\mygrid}{11/blue, 32/brown}, assumes the grid always has less than 10 rows and columns. Just sayin' Commented Sep 11, 2017 at 14:34

2 Answers 2

8

This is based on the first edit. Note: I assigned the name name to the grid so that you can use coordinates (name.south east) etc.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand*{\GridSize}{4}

\newcommand*{\ColorCells}[1]{% #1 = list of x/y/color
  \foreach \x/\y/\color in {#1} {
    \node [fill=\color, draw=none, thick, minimum size=1cm] 
      at (\x-.5,\GridSize+0.5-\y) {};
    }%
}%

%%%%%


%\listfiles
\begin{document}
\begin{tikzpicture}[scale=1]

    \begin{scope}[thick,local bounding box=name]
        \ColorCells{1/1/blue, 2/3/red, 3/2/green, 4/4/yellow}
        \draw (0, 0) grid (\GridSize, \GridSize);
    \end{scope}


\end{tikzpicture}
\end{document}

demo

9
  • Great! Is there any way to specify the location? I need to draw multiple such images in one document.
    – hola
    Commented Sep 8, 2017 at 17:42
  • OK. Found this: tex.stackexchange.com/a/144452/38244
    – hola
    Commented Sep 8, 2017 at 17:43
  • Yup, [shift=(coordinate)] is the key. BTW, I moved 1/1 to the upper left. Commented Sep 8, 2017 at 17:47
  • This is broken on my system. Was working perfectly well until recently. Is it just me? I've suggested an edit, closely based on the previous code.
    – PatrickT
    Commented Jan 20, 2019 at 13:19
  • 1
    @PatrickT the problem seems to be specific to the use of \color in \foreach, choosing an alternate macro name seems to be sufficient.
    – Dai Bowen
    Commented Jan 20, 2019 at 14:48
7

\definegrid[rows,cols] defines \grows and \gcols and proceeds to define all the cells of the grid \grid[i,j] where i and j are row and column indices as \wh (white). Note that \grid[i,j] is defined with \csname since i and j are catcode 12.

Then, \setgrid[i,j]{color} is used to redefine the cell \grid[i,j] to the desired color.

Finally, \drawgrid regurgitates the \grid[i,j] cells in the form of a stack.

Each cell is an \fbox, by the way, dimensions can be set as needed.

Revised for standalone:

\documentclass{standalone}
\usepackage{xcolor,stackengine,pgffor}
\def\block#1{\kern-\fboxrule\fboxsep=0pt\fbox{\color{#1}\rule{1ex}{1ex}}}
\def\wh{\block{white}}
\setstackgap{S}{-\fboxrule}
\setstackEOL{\\}

\makeatletter
\def\definegrid[#1,#2]{%
  \def\grows{#1}%
  \def\gcols{#2}%
  \foreach\i in {1,...,#1}%
  {%
    \foreach\j in {1,...,#2}%
    {%
      \expandafter\gdef\csname grid[\i,\j]\endcsname{\wh}%
    }%
  }%
\ignorespaces}

\newcommand\drawgrid{%
  \def\stackbuild{}%
  \foreach\i in {1,...,\grows}%
  {%
    \ifnum\i=1\else\g@addto@macro\stackbuild{\\}\fi%
    \foreach\j in {1,...,\gcols}%
    {%
      \expandafter\g@addto@macro\expandafter\stackbuild\expandafter{%
        \csname grid[\i,\j]\endcsname}%
    }%
  }%
  \kern\fboxrule%
  \expandafter\Shortstack\expandafter{\stackbuild}%
}

\def\setgrid[#1,#2]#3{\expandafter\gdef\csname grid[#1,#2]\endcsname{\block{#3}}%
  \ignorespaces}
\makeatother
\begin{document}
\definegrid[4,4]
%
\setgrid[1,1]{blue}
\setgrid[3,2]{red}
\setgrid[4,4]{green}
%
\drawgrid
\end{document} 

enter image description here


Here is a version in which \definegrid[rows,cols]{default-color} takes a mandatory trailing argument that sets the default color of the grid.

\documentclass{standalone}
\usepackage{xcolor,stackengine,pgffor}
\def\block#1{\kern-\fboxrule\fboxsep=0pt\fbox{\color{#1}\rule{1ex}{1ex}}}
\setstackgap{S}{-\fboxrule}
\setstackEOL{\\}

\makeatletter
\def\definegrid[#1,#2]#3{%
  \def\grows{#1}%
  \def\gcols{#2}%
  \foreach\i in {1,...,#1}%
  {%
    \foreach\j in {1,...,#2}%
    {%
      \expandafter\gdef\csname grid[\i,\j]\endcsname{\block{#3}}%
    }%
  }%
\ignorespaces}

\newcommand\drawgrid{%
  \def\stackbuild{}%
  \foreach\i in {1,...,\grows}%
  {%
    \ifnum\i=1\else\g@addto@macro\stackbuild{\\}\fi%
    \foreach\j in {1,...,\gcols}%
    {%
      \expandafter\g@addto@macro\expandafter\stackbuild\expandafter{%
        \csname grid[\i,\j]\endcsname}%
    }%
  }%
  \kern\fboxrule%
  \expandafter\Shortstack\expandafter{\stackbuild}%
}

\def\setgrid[#1,#2]#3{\expandafter\gdef\csname grid[#1,#2]\endcsname{\block{#3}}%
  \ignorespaces}
\makeatother
\begin{document}
\definegrid[4,4]{yellow}
%
\setgrid[1,1]{blue}
\setgrid[3,2]{red}
\setgrid[4,4]{green}
%
\drawgrid
\end{document} 

enter image description here

2
  • Thanks... When I put it under standalone class, I get a white region at left. Is there any fix to this?
    – hola
    Commented Sep 8, 2017 at 17:28
  • @pushpen.paul Those are added from each line-end. I have revised to add \ignorespaces to the end of each of my macros, so you don't need to manually add % to the end of each line. Commented Sep 8, 2017 at 17:32

You must log in to answer this question.

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