18

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.

Display Name
  • 46,933

2 Answers2

22

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.

Download:    [ TikZ Library ]    [ Example ]


\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:

Result

New:

Result

Martin Scharrer
  • 262,582
9

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!

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
  • +1 @Andrew: Thanks for the effort. But it does not show the labeling numbers. – Display Name Mar 25 '11 at 14:40
  • 2
    @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! – Andrew Stacey Mar 25 '11 at 19:17