37

I am new to the use of TikZ. I have been evaluating the TikZ-KTikZ combination, over the last 2 days, as an alternative to Xfig, which I have used for 17 years. I have managed to create a grid structure using the following code:

\begin{tikzpicture}
\newcommand{\GL}{5};
\draw [step=0.1, help lines,red!20] (-\GL,-\GL) grid (\GL,\GL);
\draw [step=1.0, help lines,red!40] (-\GL,-\GL) grid (\GL,\GL);
\draw [step=\GL.0, help lines,red!100] (-\GL,-\GL) grid (\GL,\GL);
\foreach \x in {-\GL,...,\GL} { \draw node at (\x,-\GL) [label=below:{\tiny $\x.0$}]{}; };
\foreach \x in {-\GL,...,\GL} { \draw node at (\x,\GL) [label=above:{\tiny $\x.0$}] {}; };
\foreach \y in {-\GL,...,\GL} { \draw node at (-\GL,\y) [label=left:{\tiny $\y.0$}]  {}; };
\foreach \y in {-\GL,...,\GL} { \draw node at (\GL,\y) [label=right:{\tiny $\y.0$}]  {}; };
\end{tikzpicture}

I like using the grid structure because it enables me to place my picture elements in the {tikzpicture} environment quickly. However, I have to comment it out after drawing my picture. I would like to package the above code into a single flexible command which I can insert into the {tikzpicture} and comment out quickly when I am done.

Could someone with a lot of experience in TikZ advise me on how I could package the above code into a single command which could accept optional parameters such as Xmin, Xmax, Ymin, Ymax and grid color, with default values.

Any help would be greatly appreciated.

1

2 Answers 2

42

Here is a solution via pgfkeys.

First, I create the new family mygrid, I define some keys with their initial values in this family and I define the new command \mygridset to use this family:

\pgfkeys{
  mygrid/.is family,
  mygrid,
  min x/.initial=-5,
  max x/.initial=5,
  min y/.initial=-5,
  max y/.initial=5,
  small step/.initial=.1,
  step/.initial=1,
  big step/.initial=5,
  color/.initial=red,
}
\newcommand\mygridset[1]{\pgfkeys{mygrid,#1}}

Then I define the new command \mygrid with an empty optional parameter. The first lines of this command (the call to \mygridset) changes the values of the keys via #1 then store the value of each key in a macro. The last lines draw the grid with these values.

\newcommand\mygrid[1][]{
  \mygridset{#1,
    min x/.get=\gridminx,
    max x/.get=\gridmaxx,
    min y/.get=\gridminy,
    max y/.get=\gridmaxy,
    small step/.get=\gridsmallstep,
    step/.get=\gridstep,
    big step/.get=\gridbigstep,
    color/.get=\gridcolor
  }

  \draw [step=\gridsmallstep, help lines,\gridcolor!20]
  (\gridminx,\gridminy) grid (\gridmaxx,\gridmaxy);
  \draw [step=\gridstep, help lines,\gridcolor!40]
  (\gridminx,\gridminy) grid (\gridmaxx,\gridmaxy);
  \draw [step=\gridbigstep, help lines,\gridcolor!100]
  (\gridminx,\gridminy) grid (\gridmaxx,\gridmaxy);
  \foreach \x in {\gridminx,...,\gridmaxx} {
    \node[below,font=\tiny] at (\x,\gridminy) {$\x$};
    \node[above,font=\tiny] at (\x,\gridmaxy) {$\x$};
  };
  \foreach \y in {\gridminy,...,\gridmaxy} {
    \node[left,font=\tiny] at (\gridminx,\y) {$\y$};
    \node[right,font=\tiny] at (\gridmaxx,\y) {$\y$};
  };
}

Here is a complete example (3 pages) to illustrate the usage:

enter image description here

enter image description here

enter image description here

And the complete code:

\documentclass[tikz]{standalone}

\pgfkeys{
  mygrid/.is family,
  mygrid,
  min x/.initial=-5,
  max x/.initial=5,
  min y/.initial=-5,
  max y/.initial=5,
  small step/.initial=.1,
  step/.initial=1,
  big step/.initial=5,
  color/.initial=red,
}
\newcommand\mygridset[1]{\pgfkeys{mygrid,#1}}
\newcommand\mygrid[1][]{
  \mygridset{#1,
    min x/.get=\gridminx,
    max x/.get=\gridmaxx,
    min y/.get=\gridminy,
    max y/.get=\gridmaxy,
    small step/.get=\gridsmallstep,
    step/.get=\gridstep,
    big step/.get=\gridbigstep,
    color/.get=\gridcolor
  }

  \draw [step=\gridsmallstep, help lines,\gridcolor!20]
  (\gridminx,\gridminy) grid (\gridmaxx,\gridmaxy);
  \draw [step=\gridstep, help lines,\gridcolor!40]
  (\gridminx,\gridminy) grid (\gridmaxx,\gridmaxy);
  \draw [step=\gridbigstep, help lines,\gridcolor!100]
  (\gridminx,\gridminy) grid (\gridmaxx,\gridmaxy);
  \foreach \x in {\gridminx,...,\gridmaxx} {
    \node[below,font=\tiny] at (\x,\gridminy) {$\x$};
    \node[above,font=\tiny] at (\x,\gridmaxy) {$\x$};
  };
  \foreach \y in {\gridminy,...,\gridmaxy} {
    \node[left,font=\tiny] at (\gridminx,\y) {$\y$};
    \node[right,font=\tiny] at (\gridmaxx,\y) {$\y$};
  };
}

% a style to memorize some change to the default values
\mygridset{
  a grid/.style={
    min x=-3,
    max x=3,
    min y=-3,
    max y=3,
    small step=.2,
    step=1,
    big step=2,
    color=orange,
  }
}

\begin{document}
\begin{tikzpicture}
  % a grid with default values
  \mygrid
\end{tikzpicture}
\begin{tikzpicture}
  % a grid with specific values 
  \mygrid[min x=-3, max x=2,min y=-2,max y=1,color=blue]
\end{tikzpicture}
\begin{tikzpicture}
  % a grid using the `a grid` style
  \mygrid[a grid]
\end{tikzpicture}
\end{document}
3
  • Very nice! I suspected as much: pgfkeys is the most flexible solution, but really don't have the time to explore it in detail - I really should. So, this is +1 for you! :)
    – Count Zero
    Jan 8, 2013 at 11:28
  • Thank you very much Professor Paul Gaborit. I have tried out your proposed solution. It works wonderfully well. Besides, it has enabled me to learn more about pgf. I am very grateful for the solution. (Dr Henry Okoyo.)
    – user24098
    Jan 8, 2013 at 15:32
  • 1
    @user24098 In addition of posting a “Thank you” as comment (thanks for that), you should thank by upvoting this answer (with the upward pointing arrow to the left of it) and accepting it (by clicking on the green checkmark)... Note: I am not yet Professor ! :-) Jan 8, 2013 at 15:39
8

Here is my take on it. The difficulty really resides in the fact that LaTeX accepts a default value only for one argument (the first) in \newcommand. If you want to specify more than one, you need to come up with some trick. This does not really pertain to TikZ. My solution uses the xstring package (and is maybe not the most elegant solution):

\newcommand{\bgndgrid}[1]{%
\IfStrEq{#1}{default}{%
\draw [step=0.1, help lines,red!20] (-5,-5) grid (5,5);
\draw [step=1, help lines,red!40] (-5,-5) grid (5,5);
\draw [step=5, help lines,red!100] (-5,-5) grid (5,5);
\foreach \x in {-5,...,5} {\draw node at (\x,-5) [label=below:{\tiny $\x.0$}]{};};
\foreach \x in {-5,...,5} {\draw node at (\x,5) [label=above:{\tiny $\x.0$}]{};};
\foreach \y in {-5,...,5} {\draw node at (-5,\y) [label=left:{\tiny $\y.0$}]{};};
\foreach \y in {-5,...,5} {\draw node at (5,\y) [label=right:{\tiny $\y.0$}]{};};
}%
{%
\StrBefore{#1}{,}[\xmin]
\StrBetween[1,2]{#1}{,}{,}[\ymin]
\StrBetween[2,3]{#1}{,}{,}[\xmax]
\StrBetween[3,4]{#1}{,}{,}[\ymax]
\StrBehind[4]{#1}{,}[\gcolor]
\draw [step=0.1, help lines,\gcolor!20] (-\xmin,-\ymin) grid (\xmax,\ymax);
\draw [step=1, help lines,\gcolor!40] (-\xmin,-\ymin) grid (\xmax,\ymax);
\draw [step=5, help lines,\gcolor!100] (-\xmin,-\ymin) grid (\xmax,\ymax);
\foreach \x in {-\xmin,...,\xmax} {\draw node at (\x,-\ymin) [label=below:{\tiny $\x.0$}]{};};
\foreach \x in {-\xmin,...,\xmax} {\draw node at (\x,\ymax) [label=above:{\tiny $\x.0$}]{};};
\foreach \y in {-\ymin,...,\ymax} {\draw node at (-\xmin,\y) [label=left:{\tiny $\y.0$}]{};};
\foreach \y in {-\ymin,...,\ymax} {\draw node at (\xmax,\y) [label=right:{\tiny $\y.0$}]{};};
}
}

You need to type: \bgndgrid{default} to get the coded default behavior (grid from (-5,-5) to (5,5), in red). You can redefine the default string, if you like. Otherwise the macro will try to chop up the argument where it finds commas (delimiters) and if successful, will draw the grid. The parameters are to be entered as: \bgndgrid{xmin,ymin,xmax,ymax,color}, like in:

\bgndgrid{1,2,3,4,blue}

which yields:

Feel free to customize!

3
  • Thanks for your proposed solution. I have tried the command \bgndgrid{1,2,3,4,blue}. However, it fails to compile. Error message: Undefined control sequence.\bgndgrid #1->\IfStrEq {#1}{default}{\draw [step=0.1, help lines,red!20] (-5...
    – user24098
    Jan 8, 2013 at 17:00
  • @user24098: Did you load the xstring package (\usepackage{xstring})?
    – Count Zero
    Jan 8, 2013 at 17:01
  • Yes I did. Thanks. Confirmed that I have the package in my TeX tree.
    – user24098
    Jan 8, 2013 at 17:02

You must log in to answer this question.

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