1

I am trying to position node(2) in a page in coordinates related to the page (origin at upper left corner of the body of the page). My code is:

\documentclass[border=10pt,a4paper]{memoir}
\usepackage[total={16.51cm,21.59cm},
top=1.2in, left=0.9in, includefoot]{geometry}
\usepackage{tikz}
\usepackage{fancyhdr}
\usepackage{comment}
\pagestyle{fancy}
\fancyhf{}
\renewcommand{\headrulewidth}{2pt}
\renewcommand{\footrulewidth}{1pt}
\begin{document}
\begin{tikzpicture}
\node[](1) at (0cm,0cm) {1};
\node[](2) at (0.5\textwidth,-0.5\textheight) {2};
\end{tikzpicture}
\vspace{1cm}
\noindent
\end{document}

For node(2) to be positioned in the centre of the page at (0.5\textwidth,-0.5\textheight) I have to create another node (1) in the origin, otherwise node(2) will be put at (0,0). I would like that someone could explain this strange behaviour.

  • Welcome to TeX.SX! You can certainly remove a few things from your example (like \usepackage{comment}, at the very least—cf. tips here). The reference point of a tikzpicture is not necessarily at (0,0). In order allow us to most efficiently solve your actual problem, you should tell us whether you want something placed relatively to the center of the physiclal page, or to the center of the page body (where normal (La)TeX text goes—not the same thing). – frougon Jun 12 '19 at 12:32
  • I want the node placed at the centre of the page body, what I do not understand is the seemingly erratic behaviour of the \node position, I expected the given coordinates to be independent of any other command contrary to what happens here: adding node (1) affects the positioning of node (2) – Richard Jun 12 '19 at 13:13
  • Please see my answer below. – frougon Jun 12 '19 at 21:37
1

This will place a node at the middle of the current page (you need to compile twice):

\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}

\begin{document}

\lipsum[1]

\begin{tikzpicture}[remember picture, overlay]
\node[draw] at (current page.center) {Here I am!};
\end{tikzpicture}

\lipsum[2]


\end{document}

Note the that TikZ picture is placed outside the normal text flow. You can replace current page.center with e.g. current page.north west to get the upper left hand corner of the page instead.

  • Thaks a lot, very useful all your comments – Richard Jun 13 '19 at 8:54
  • Please note that text area (page body) is not the same as physical page, that's why I asked for clarification of the desired result here. – frougon Jun 13 '19 at 9:14
1

The behavior you observed is perfectly normal. To understand it, I suggest you to read section Creating a Picture Using an Environment of the TikZ & PGF Manual (for the manual corresponding to PGF/TikZ 3.1.3 [current], pages 126 and 127 should be most interesting to you).

Basically, a tikzpicture environment produces a box for TeX, similar to a character box or a box created with the \includegraphics command (not to be confused with the figure environment). The size of this box is determined by what you draw inside the tikzpicture environment: the bounding box of the tikzpicture is, by default, a rectangle with sides parallel to the page edges that is just large enough to hold everything drawn in the environment (the TikZ & PGF Manual mentions that there may be little variations due to curve control points and stuff like that which aren't drawn yet contribute to the bounding box, but this is clearly not the issue here). Unless you use the baseline option, the baseline of the created box coincides with the lower side of the rectangle I just described.

Thus, if you only draw your node (2), the whole tikzpicture is just a small box that is large enough to hold this node—it is not significantly larger than an ordinary character box (there is some padding by default around the node contents, but nothing comparable to your \textwidth or \textheight). It gets placed by TeX the same way as if you had typed an A (for instance) instead of the whole tikzpicture. The fact that you set up the TikZ origin so that (0.5\textwidth,-0.5\textheight) is at the center of your little node doesn't matter in any way. That is why I said in my comment that the reference point of a tikzpicture is not necessarily at (0,0). The coordinates don't matter, except:

  • for relative positioning of elements inside the tikzpicture;

  • if you use the baseline option, the y coordinates do matter (baseline=y0 makes the baseline of the tikzpicture coincide with the line of equation y=y0 relative to the TikZ origin, see the manual section I mentioned above for details).

When you have both nodes, the situation is wholly different: the smallest enclosing rectangle has approximate dimensions 0.5\textwidth×0.5\textheight: it is not a small rectangle of comparable size to a glyph in size \normalsize anymore! So, in some way, your node (1) pushes node (2) downwards and rightwards, because of the rules I explained for the bounding box and baseline of the tikzpicture, and TeX rules concerning boxes in a paragraph (paragraph consisting of only one box here, plus the indentation box in your example). The box is so high that TeX's rule concerning \topskip places a zero-length vertical glue between the top of the text area and the top of the tikzpicture. However, in your example, the left side of the tikzpicture box was at \parindent from the left margin, not zero. Besides, your (0,0) origin is located at the center of node (1), whereas it is the top edge of (1) that coincides with the top margin because of what I said regarding \topskip.

Here is code that uses your method but corrects all these little defects to place the center of node (2) precisely at the center of the text area:

\documentclass{article}
\usepackage{tikz}

% Shows the limits of the text area (among others)
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{blue!30}}

\begin{document}

\noindent
\begin{tikzpicture}
  \node[minimum width=0, minimum height=0, inner sep=0, outer sep=0] (1)
    at (0,0) {};
  \node[draw] (2) at (0.5\textwidth,-0.5\textheight)
    {center of text area};
\end{tikzpicture}

\end{document}

Manual placement

This is perfectly accurate, but places a very large box on the page, which may be inconvenient if you intended to also typeset text in the whole text area. Here is a variation on the previous method that takes no space (note the \topskip offset, necessary because the box has zero height this time and therefore has its baseline at \topskip below the top of the text area):

\documentclass{article}
\usepackage{tikz}

% Shows the limits of the text area (among others)
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{blue!30}}

\begin{document}

\noindent
\begin{tikzpicture}[overlay]
  \node[minimum width=0, minimum height=0, inner sep=0, outer sep=0] (1)
    at (0,0) {};
  \node[draw] (2) at (0.5\textwidth,-0.5\textheight+\topskip)
    {center of text area};
\end{tikzpicture}

\end{document}

(no screenshot, as it would be strictly identical to the previous one)

But there is an easier method with the tikzpagenodes package:

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

% Shows the limits of the text area (among others)
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{blue!30}}

\begin{document}

\begin{tikzpicture}[remember picture, overlay]
  \coordinate (center)
    at ($(current page text area.south west) !0.5!
         (current page text area.north east)$);
  \node[draw, red!40!black] (label) at (center) {center of text area};
  \draw[blue!30] (current page text area.south west)
              -- (current page text area.north east)
                 (current page text area.north west)
              -- (current page text area.south east);
\end{tikzpicture}

\end{document}

(this requires two compilation runs because of the remember picture mechanism necessary for tikzpagenodes to work properly)

Technique with the tikzpagenodes package

Finally, we can use both methods on the same page to prove that they give exactly the same result (compile this twice; you'll only see one boxed text at the center, but it is actually drawn from two places in two different colors!):

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

% Shows the limits of the text area (among others)
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{blue!30}}

\begin{document}

\noindent
\begin{tikzpicture}[overlay]
  \node[minimum width=0, minimum height=0, inner sep=0, outer sep=0] (1)
    at (0,0) {};
  \node[draw, blue] (2) at (0.5\textwidth,-0.5\textheight+\topskip)
    {center of text area};
\end{tikzpicture}

\begin{tikzpicture}[remember picture, overlay]
  \coordinate (center)
    at ($(current page text area.south west) !0.5!
         (current page text area.north east)$);
  \node[draw, red!40!black] (label) at (center) {center of text area};
  \draw[blue!30] (current page text area.south west)
              -- (current page text area.north east)
                 (current page text area.north west)
              -- (current page text area.south east);
\end{tikzpicture}

\end{document}

Notes:

  • This requires two compilation runs for the same reason as given above.

  • No screenshot, as it would be strictly identical to the previous one, since the second tikzpicture is drawn on top of the first one.

  • Impressive long explanations. +1 – Sebastiano Jun 12 '19 at 21:43
  • 1
    Thanks, Sebastiano. :-) – frougon Jun 12 '19 at 21:44
  • @Richard I've made a little correction that might have hampered understanding: “Thus, if you only draw your node (2) (...)” (the sentence used to mistakenly mention node (1) in this place). – frougon Jun 13 '19 at 9:40

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.