7

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}
  • Please show us what you had when you got lost. – Benjamin McKay Sep 8 '17 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. – pushpen.paul Sep 8 '17 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? – pushpen.paul Sep 8 '17 at 16:07
  • @BenjaminMcKay It's over five hours now... I lost count what/how many tweaks I tried. – pushpen.paul Sep 8 '17 at 16:08
  • @CarLaTeX Added one example :-) – pushpen.paul Sep 8 '17 at 16:33
6

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

  • Great! Is there any way to specify the location? I need to draw multiple such images in one document. – pushpen.paul Sep 8 '17 at 17:42
  • OK. Found this: tex.stackexchange.com/a/144452/38244 – pushpen.paul Sep 8 '17 at 17:43
  • Yup, [shift=(coordinate)] is the key. BTW, I moved 1/1 to the upper left. – John Kormylo Sep 8 '17 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 Jan 20 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 Jan 20 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

  • Thanks... When I put it under standalone class, I get a white region at left. Is there any fix to this? – pushpen.paul Sep 8 '17 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. – Steven B. Segletes Sep 8 '17 at 17:32

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.