Is there the easiest way to toggle (show/hide) navigational grids in TikZ?

In PSTricks, we can toggle the grids easily by showgrid=[false/true]. How to do it in TikZ? Doing as follows is tedious.

\documentclass{minimal}
\usepackage{tikz}

\begin{document}

\tikzpicture

\draw[gray,very thin] (-4,-2) grid (4,2);
\foreach \x in {-4,...,4}
\draw[red] (\x,-1.9) -- (\x,-2.1) node [below] {\x};

\foreach \y in {-2,...,2}
\draw[red] (-3.9,\y) -- (-4.1,\y) node [right] {\y};

\draw (0,0) circle (2);

\endtikzpicture

\end{document}


Is there the easiest way to toggle (show/hide) navigational grids in TikZ?

Edit

The navigation needs not only the grids but also the labeling numbers.

-

You could define a showgrid style (or better show grid to following the TikZ naming scheme) which executes some code at the end of the picture which draws the grid relative to the current bounding box.

Update: I now figured out that the backgrounds library already provides this as show background grid or as gridded. You might want to add tight background to not add extra space around your picture.

However adding the numbers requires extra code anyway. So here my final solution including numbers. The trick is to round to the next lower left and upper right corner on the grid using PGF code and then use a \foreach loop for the labeling.

Update 2: I added the requested options to select the positions of the labels. See the example code.

I converted it now to the format of a TikZ library which can be loaded using \usetikzlibrary{showgrid} and put it on my website.

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\makeatletter
\newif\if@showgrid@grid
\newif\if@showgrid@left
\newif\if@showgrid@right
\newif\if@showgrid@below
\newif\if@showgrid@above
\tikzset{%
every show grid/.style={},
show grid/.style={execute at end picture={\@showgrid{grid=true,#1}}},%
show grid/.default={true},
show grid/.cd,
labels/.style={font={\sffamily\small},help lines},
xlabels/.style={},
ylabels/.style={},
keep bb/.code={\useasboundingbox (current bounding box.south west) rectangle (current bounding box.north west);},
true/.style={left,below},
false/.style={left=false,right=false,above=false,below=false,grid=false},
none/.style={left=false,right=false,above=false,below=false},
all/.style={left=true,right=true,above=true,below=true},
grid/.is if=@showgrid@grid,
left/.is if=@showgrid@left,
right/.is if=@showgrid@right,
below/.is if=@showgrid@below,
above/.is if=@showgrid@above,
false,
}

\def\@showgrid#1{%
\begin{scope}[every show grid,show grid/.cd,#1]
\if@showgrid@grid
\begin{pgfonlayer}{background}
\draw [help lines]
(current bounding box.south west) grid
(current bounding box.north east);
%
\pgfpointxy{1}{1}%
\edef\xs{\the\pgf@x}%
\edef\ys{\the\pgf@y}%
\pgfpointanchor{current bounding box}{south west}
\edef\xa{\the\pgf@x}%
\edef\ya{\the\pgf@y}%
\pgfpointanchor{current bounding box}{north east}
\edef\xb{\the\pgf@x}%
\edef\yb{\the\pgf@y}%
\pgfmathtruncatemacro\xbeg{ceil(\xa/\xs)}
\pgfmathtruncatemacro\xend{floor(\xb/\xs)}
\if@showgrid@below
\foreach \X in {\xbeg,...,\xend} {
\node [below,show grid/labels,show grid/xlabels] at (\X,\ya) {\X};
}
\fi
\if@showgrid@above
\foreach \X in {\xbeg,...,\xend} {
\node [above,show grid/labels,show grid/xlabels] at (\X,\yb) {\X};
}
\fi
\pgfmathtruncatemacro\ybeg{ceil(\ya/\ys)}
\pgfmathtruncatemacro\yend{floor(\yb/\ys)}
\if@showgrid@left
\foreach \Y in {\ybeg,...,\yend} {
\node [left,show grid/labels,show grid/ylabels] at (\xa,\Y) {\Y};
}
\fi
\if@showgrid@right
\foreach \Y in {\ybeg,...,\yend} {
\node [right,show grid/labels,show grid/ylabels] at (\xb,\Y) {\Y};
}
\fi
\end{pgfonlayer}
\fi
\end{scope}
}
\makeatother
%\tikzset{showgrid} % would enable it globally
\tikzset{every show grid/.style={show grid/keep bb}}%  Keep the original bounding box!
\begin{document}
\noindent
\begin{tikzpicture}
\draw (3,2) -- +(45:3);
\end{tikzpicture}
\hspace{1cm}%
\begin{tikzpicture}[show grid=false]
\draw (3,2) -- +(45:3);
\end{tikzpicture}
\hspace{1cm}%
\begin{tikzpicture}[show grid]
\draw (3,2) -- +(45:3);
\end{tikzpicture}
\hspace{1cm}%
\begin{tikzpicture}[show grid=true]
\draw (3,2) -- +(45:3);
\end{tikzpicture}
\par\bigskip\bigskip\bigskip\noindent
\begin{tikzpicture}[show grid=left]
\draw (3,2) -- +(45:3);
\end{tikzpicture}
\hspace{1cm}%
\begin{tikzpicture}[show grid=right]
\draw (3,2) -- +(45:3);
\end{tikzpicture}
\hspace{1cm}%
\begin{tikzpicture}[show grid=above]
\draw (3,2) -- +(45:3);
\end{tikzpicture}
\hspace{1cm}%
\begin{tikzpicture}[show grid=below]
\draw (3,2) -- +(45:3);
\end{tikzpicture}
\par\bigskip\bigskip\bigskip\noindent
\begin{tikzpicture}[show grid={left,right}]
\draw (3,2) -- +(45:3);
\end{tikzpicture}
\hspace{1cm}%
\begin{tikzpicture}[show grid={right,above}]
\draw (3,2) -- +(45:3);
\end{tikzpicture}
\hspace{1cm}%
\begin{tikzpicture}[show grid={above,below}]
\draw (3,2) -- +(45:3);
\end{tikzpicture}
\hspace{1cm}%
\begin{tikzpicture}[show grid={below,right}]
\draw (3,2) -- +(45:3);
\end{tikzpicture}
\end{document}


Result:

New:

-
@Martin: How to show the labeling numbers ? –  xport Mar 25 '11 at 14:31
@Martin: Thanks also. But it still has no labeling numbers. –  xport Mar 25 '11 at 14:41
@xport: I'm actually planning to release all my PGF/TikZ improvements as a bundle (but not anytime soon). –  Martin Scharrer Mar 25 '11 at 15:58
@xport: I added this now. –  Martin Scharrer Mar 25 '11 at 19:29
@xport: I didn't had any plans yet when/how to release it. Like I said I want to bundle it with some other PGF/TikZ improvements of mine and still have to find the right format. –  Martin Scharrer Mar 28 '11 at 3:21

There doesn't appear to be an every grid/.style={} option, so what you could do is define a new style to put on each grid which you can then toggle in the preamble. Something like:

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\tikzset{grid/.style={gray,very thin,opacity=1}}
\begin{tikzpicture}
\draw[grid] (0,0) grid (4,4);
\end{tikzpicture}
\end{document}


Then changing the opacity to 0 effectively removes the grid. I chose to implement it by changing the opacity rather than the draw colour as if it is drawn in the background colour then this will still draw over anything already existing, whereas making it fully transparent shows through anything underneath.

One could easily make this in to a command or an \if to be executed, maybe toggle it with the draft option, but just changing a 1 to a 0 seems simple enough to me!

-
+1 @Andrew: Thanks for the effort. But it does not show the labeling numbers. –  xport Mar 25 '11 at 14:40
@xport: Ah, I didn't realise that that was part of the spec (not being familiar with PSTricks). I see that Martin has - as usual! - written an entire package to do this! –  Loop Space Mar 25 '11 at 19:17