# How to prepare a PSTricks-like canvas (or drawing area) in PGF/Tikz before drawing other objects inside it?

Objectives:

1. To show a canvas bounding box with a specified size in advance. In other words, I want to create a \begin{pspicture}(-2,-2)(3,3)-like canvas before drawing other objects inside it. I don't like auto-determined canvas size produced by Tikz because of some reasons.

2. To show the colored grid with numbers along its axes for navigation purpose. It also clips any objects beyond its boundary. The grid can be applied to the canvas in 2 ways: permanent and temporary.

3. To hide GLOBALLY the temporary grid at the final phase without having to make adjustment one by one per \tikzpicture (that is tedious).

It is better if I provide the example in PSTricks to make it clearer.

## PSTricks

\documentclass[dvipsnames,dvips,rgb]{minimal}
\usepackage{pstricks}

\newpsstyle{gridstyle}{%
gridwidth=0.4pt,%default: 0.8pt
gridcolor=Red!10,%default: black
griddots=0,%default: 0
%
gridlabels=3pt,%default: 10pt
gridlabelcolor=Blue,%default: black
%
subgriddiv=5,%default: 5
subgridwidth=0.2pt,%default: 0.4pt
subgridcolor=Green!10,%default: gray
subgriddots=0%default: 0
}

\psset{style=gridstyle}

%To remove the grid globally, please remove th following comment.
%\let\psgrid\relax

\begin{document}

\begin{pspicture}[showgrid](-2,-2)(3,3)
%Permanent grid has been setup.
%other objects start from here
\pscircle[fillstyle=solid,opacity=0.25,fillcolor=red](0.5,0.5){2}
\end{pspicture}

\vspace{1cm}

\begin{pspicture}(-2,-2)(3,3)
\psgrid%this is a temporary grid that can be hidden globally later.
%other objects start from here
\pscircle[fillstyle=solid,opacity=0.25,fillcolor=red](0.5,0.5){2}
\end{pspicture}
\end{document}


## PGF/Tikz

My attempt below did not produce the same figure as the PSTricks did above.

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\clip (-2,-2) rectangle (3,3);
\draw (-2,-2) grid (3,3);
\draw[opacity=0.25,fill=red] (0.5,0.5) circle (2);
\end{tikzpicture}
\end{document}


## First attempt based on @Torbjorn's suggestion

It is better but not similar to the PSTricks one given above.

\documentclass{minimal}
\usepackage{tikz}
\begin{document}

\newcommand{\grid}[4]{\draw [green] (#1,#2) grid (#3,#4);}

\begin{tikzpicture}
\clip (-2,-2) rectangle (3,3);
\draw [opacity=0.25,fill=red,draw=black] (0.5,0.5) circle (2);
\draw [green] (-2,-2) grid (3,3);%Permanent
\end{tikzpicture}

\vspace{1cm}

\begin{tikzpicture}
\clip (-2,-2) rectangle (3,3);
\draw [opacity=0.25,fill=red,draw=black] (0.5,0.5) circle (2);
%
%I hope it to be temporarily grid that can be removed globally later.
\grid{-2}{-2}{3}{3}
\end{tikzpicture}
\end{document}

-

To limit the the picture to a specific rectangle, add a \clip command at the beginning of the picture, e.g.

\clip (-2,-2) rectangle (3,3);


This works with most paths (but not grid it seems), so you can, for instance specify the vertices manually or use a circle instead of a rectangle, should you want to.

As the grid is for navigational purposes, it would be best to have it on top, I suppose. You can do either by putting it at the end of the picture, or by using the execute at end picture key, like so:

\documentclass{minimal}
\usepackage[demo]{graphicx}
\usepackage{tikz}
\begin{document}
\noindent
\begin{tikzpicture}[%
execute at begin picture={\clip (0,0) rectangle (5,5);},
execute at end picture={\draw [red] (0,0) grid (5,5);}]
\draw (2.5,2.5) node[inner sep=0]{\includegraphics[width=5cm]{}};
\end{tikzpicture}
\end{document}


To remove the grid, simply comment out the line that draws the grid.

(The rest of the post may not be very relevant, but I'll leave it as is.)

The PGF manual describes two ways of defining the bounding box of a tikzpicture (see section 15.7 of the PGF 2.10 manual). Either, one can use the command \useasboundingbox, or one can use use as bounding box as an option to a path. Note that this does not clip the paths, so if you draw something outside this specified bounding box, it will flow into the surrounding text and/or margins. (To clip the picture as well, use the \clip command.)

By using the latter option you can draw the border of the bounding box at the same time, by adding the option to a \draw command. An example:

\documentclass{minimal}
\usepackage{tikz}
\usepackage{lipsum}
\begin{document}
\lipsum[1]
\begin{tikzpicture}
\draw[blue, use as bounding box] (0,0) rectangle (2,2);
\draw (-2,-2) -- (4,4);  % these demonstrate that
\draw (-2,4) -- (4,-2);  % paths are not clipped
\end{tikzpicture}
\lipsum[2]
\end{document}


If you just want to set the bounding box, and not draw the border, you can use

\useasboundingbox (0,0) rectangle (2,2);


Another way of drawing the border of the picture, is to use the predefined node current bounding box. This is a rectangle shape that is always the size of, well, the current bounding box. You can use its corners as coordinates to draw the border. Further, by using the key execute at end picture you can add the drawing command as on option to the tikzpicture environment. (You could, of course, also just add it at the end of the picture.)

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[execute at end picture={%
\draw [blue] (current bounding box.south west) rectangle
(current bounding box.north east);}]
\draw (0,0) circle (1cm);
\draw (3,0) circle (3pt);
\end{tikzpicture}
\end{document}


Regarding your example, the reason that the horizontal "margin" is different from the vertical, seems to be the inner sep of the node containing the image. It is this node that determines the width of the tikzpicture, while the grid determines the height. If you remove the grid, you'll see that the distance from the bounding box to the image is the same for both directions.

The size of the inner separation can be set by adding inner sep=<length> as an option to the node. This can also be defined separately for the horizontal and vertical direction, by using inner xsep=<length> and inner ysep=<length>, respectively.

\documentclass{minimal}
\usepackage[demo]{graphicx}
\usepackage{tikz}
\begin{document}
\noindent%
\begin{tikzpicture}[execute at end picture=%
{\draw [ultra thick] (current bounding box.south west) rectangle
(current bounding box.north east);}]
\draw (2.5,2.5) node[inner sep=0pt]{\includegraphics[width=5cm]{}};
\draw[draw=red] (0,0) grid (5,5);
\end{tikzpicture}
\end{document}

-
can we set the node's inner sep to 0? –  xport Jan 1 '11 at 8:48
Of course, I should perhaps have mentioned that. Simply add inner sep=0pt as an option for the node. I'll update the example in a few seconds. –  Torbjørn T. Jan 1 '11 at 8:53
Unit can be omitted, right? –  xport Jan 1 '11 at 8:56
Yes, it seems that works as well. I add the unit out of old habit. –  Torbjørn T. Jan 1 '11 at 8:58
In PSTricks, we must specify the drawing canvas area first. But it is determined automatically in tikz. Can we specify it in tikz as in PSTricks? Example: \begin{pspicture}(0,0)(20,20) –  xport Jan 1 '11 at 8:59

Edit: same idea but using only TikZ styles.

These styles can (1) fix the bounding box, (2) draw a grid and a subgrid, (3) draw labels, and (4) fix the clipping box. Note: labels are ignored for bounding box.

Here is the preamble and some useful styles:

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

\tikzset{
% fix bounding box <= two points
fix bounding box/.style 2 args={execute at begin scope={
\path[use as bounding box] (#1) rectangle (#2);
},
},
% fix clipping box <= two points
fix clipping box/.style 2 args={execute at begin scope={
\clip (#1) rectangle (#2);
},
},
% draw styled grid <= style and two points
draw styled grid/.style n args={3}{execute at begin scope={
\path
let \p1=(#2), \p2=(#3) in
\pgfextra{ % fixed order for grid !!!
\pgfmathsetmacro{\xmin}{min(\x1,\x2)}
\pgfmathsetmacro{\xmax}{max(\x1,\x2)}
\pgfmathsetmacro{\ymin}{min(\y1,\y2)}
\pgfmathsetmacro{\ymax}{max(\y1,\y2)}
}
[#1] (\xmin pt,\ymin pt) grid (\xmax pt,\ymax pt);
},
},
% draw grid labels <= two points
% (first point is used to position labels)
draw grid labels/.style 2 args={execute at begin scope={
\path
let \p1=(#1), \p2=(#2) in
\pgfextra{
\pgfmathsetmacro{\xmin}{min(\x1,\x2)}
\pgfmathsetmacro{\xmax}{max(\x1,\x2)}
\pgfmathsetmacro{\ymin}{min(\y1,\y2)}
\pgfmathsetmacro{\ymax}{max(\y1,\y2)}
\pgfmathsetmacro{\xmincm}{\xmin*0.036}
\pgfmathsetmacro{\xmaxcm}{\xmax*0.036}
\pgfmathsetmacro{\ymincm}{\ymin*0.036}
\pgfmathsetmacro{\ymaxcm}{\ymax*0.036}
\pgfmathtruncatemacro{\xbeg}{ceil(\xmincm)}
\pgfmathtruncatemacro{\xend}{floor(\xmaxcm)}
\pgfmathtruncatemacro{\ybeg}{ceil(\ymincm)}
\pgfmathtruncatemacro{\yend}{floor(\ymaxcm)}
}
\foreach \x in {\xbeg,...,\xend} {
node[x labelsstyle,at={(\x, 0 |- #1)}]{\x}
}
\foreach \y in {\ybeg,...,\yend} {
node[y labelsstyle,at={(#1 |- 0, \y)}]{\y}
};
}
},
% fix grids labels and clip <= two points
fix grids labels and clip/.style 2 args={
fix bounding box={#1}{#2},
draw styled grid={subgridstyle}{#1}{#2},
draw styled grid={gridstyle}{#1}{#2},
draw grid labels={#1}{#2},
fix clipping box={#1}{#2},
},
% fix and clip <= two points
fix and clip/.style 2 args={
fix bounding box={#1}{#2},
fix clipping box={#1}{#2},
},
% default styles for grid, subgrid and labels
gridstyle/.style={step=1,line width=.8pt,draw=black},
subgridstyle/.style={step=.2,line width=.4pt,draw=gray},
labelsstyle/.style={font=\scriptsize,text=black},
x labelsstyle/.style={labelsstyle,below},
y labelsstyle/.style={labelsstyle,left},
}


The code:

\pagestyle{empty}
\usepackage{parskip}

\tikzset{
custom grid/.style={
gridstyle/.style={step=1,line width=.4pt,draw=red!10},
subgridstyle/.style={step=.25,line width=.2pt,draw=green!10},
labelsstyle/.style={font=\tiny,text=blue},
y labelsstyle/.style={labelsstyle,right},
}
}
\begin{document}

Default grids and labels:

\begin{tikzpicture}[fix grids labels and clip={-2,-2}{3,3}]
\draw [fill opacity=0.25,fill=red,draw=black] (0.5,0.5) circle (2);
\draw [fill opacity=1,fill=blue,draw=black,even odd rule]
(0.5,0.5) circle (1.5) circle(1);
\draw (3,3) grid (-2,-2);
\draw [fill=lime,fill opacity=.5] (2.5,-1.5) circle (1);
\end{tikzpicture}

Grids and labels with specific styles:

\begin{tikzpicture}[custom grid,fix grids labels and clip={3,-2}{-2,3}]
\draw [fill opacity=0.25,fill=red,draw=black] (0.5,0.5) circle (2);
\draw [fill opacity=1,fill=blue,draw=black,even odd rule]
(0.5,0.5) circle (1.5) circle(1);
\draw [fill=lime,fill opacity=.5] (2.5,-1.5) circle (1);
\end{tikzpicture}

Just a fixed boundind box with clipping (useful with a local
scope):

\begin{tikzpicture}[fix and clip={-2,-2}{3,3}]
\draw [fill opacity=0.25,fill=red,draw=black] (0.5,0.5) circle (2);
\draw [fill opacity=1,fill=blue,draw=black,even odd rule]
(0.5,0.5) circle (1.5) circle(1);
\draw [fill=lime,fill opacity=.5] (2.5,-1.5) circle (1);
\begin{scope}[shift={(1,1)},rotate=20,fix grids labels and clip={-1,-1}{1,1}]
\fill[red] (.8,0) circle (2pt);
\end{scope}
\end{tikzpicture}

Some text...
\end{document}


Here, the result:

-

Hybrid solution by putting tikzpicture inside pspicture.

\documentclass[border=12pt,pstricks]{standalone}
\usepackage{pstricks,tikz}

\begin{document}
\begin{pspicture}[showgrid=top](6,6)
\rput(3,3){%
%============ BEGIN TIKZ ============
\begin{tikzpicture}
\draw (0,0) grid (6,6);
\end{tikzpicture}%
%============ END TIKZ ============
}
\end{pspicture}
\end{document}

-