4

I guess this was already asked here, but I cannot find it. I need to draw some rectangles, and need to position some text within them. The tricky thing now is that I'd like to position them relatively to the size of the rectangle (like specifying in normal latex \hspace{0.5\textwidth} (e.g. position the text at the middle of the rectangle (in terms of the y-coordinate) but at 0.2 the width of the rectangle (in terms of the x-coordinate))

Is something like this possible and if yes, how?

2
  • Could you please explain your question a bit more? If you draw the rectangles with explicit coordinates, then there is no question since you know the coordinates. So this is likely a rectangle that is drawn without explicit coordinates such as the boundary of a node. Can you please clarify how the rectangle is generated?
    – user194703
    May 16, 2020 at 22:47
  • Well actually ther are drawn with explicit coordinates (see \draw (8,0) rectangle (0,1) (2,0.5) node {text} but when having to draw many of these rectangles which have a different size, its much more conveniant if you can say the coordinates of the text should be (0.3 \rectangleWidth | 0.5\ rectangleHeight).
    – atticus
    May 16, 2020 at 22:56

2 Answers 2

4

Here are two more options to specify the relative percentage of both x and y axis:

  • Option 1: Put the node at coordinate (<xpos> |- <ypos>), where each of <xpos> and <ypos> has form of {$ <pathway calc> $}. A variant of this option which allows lighter input is also provided.
  • Option 2: Use let path operation to get the width and height of rectangle in \x{<node name>} and \y{<node name>}. This is similar to the answer by Schrödinger's cat, but without introducing an explicit new scope.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\tikzset{
  relative at/.style n args = {3}{
    at = {({$(#1.west)!#2!(#1.east)$} |- {$(#1.south)!#3!(#1.north)$})}
  }
}

\begin{document}
\begin{tikzpicture}
  % used to indecate the relative position
  \draw[help lines, dashed, ystep=0.3] (0, 0) grid (10, 3);
  
  % define a node "rect" with size of the (bounding box of drawn) rectangle
  \draw[local bounding box=rect, thick, red] (0, 0) rectangle (10, 3);
  
  % use partway mordifiers <coord1>!<num>!<coord2> of coordinate calculation, 
  % see tikz manual sec. 13.5.3
  \node at ($ (rect.west)!0.2!(rect.east) $) {0.2x, 0.5y};

  % Option 1: use path operation |-, see manual sec. 13.3.1 and 14.2.2
  \node 
    at ({$(rect.west)!0.7!(rect.east)$} |- {$(rect.south)!0.8!(rect.north)$})
    {0.7x, 0.8y};

  % Option 1 variant: simplify input by using new tikz option "relative at"
  \node[relative at={rect}{0.5}{0.5}] {0.5x, 0.5y};

  % Option 2: use let operation, see manual sec. 14.5
  \path 
    let
      \p{rect} = ($ (rect.north east) - (rect.south west)$) 
    in
      [x=\x{rect}, y=\y{rect}, shift=(rect.south west)] 
      node at (.3, .2) {0.3x, 0.2y};
\end{tikzpicture}
\end{document}

enter image description here

3
  • To be honest, I'm not quite sure what your doing, especially what value (rect.west) represents. But in general I think this is somehow what I was looking for (just being able to specify somehow the partway of the y-Value would be nice)
    – atticus
    May 16, 2020 at 22:59
  • 1
    @atticus I've rewritten my answer to allow specifying both x and y percentages. To answer your question about (rect.west): firstly local bounding box=rect creates a node named rect with size of the rectangle (0, 0) to (10, 3); then (rect.west) specifies the anchor west of node rect, and finally that anchor is used as coordinates. The section 3 Tutorial: A Petri-Net for Hagen of tikz manual has a gentle intro to node usages. May 17, 2020 at 0:40
  • Thanks, that's just what I needed. When trying to se multiple objects into that rectangle, I think it might be worth using schrödingers solution, but with only one textfield I think this should be enough. Thanks again for your help!
    – atticus
    May 17, 2020 at 0:56
4

TikZ has a specific mechanism for that: local bounding boxes and local frames (or local coordinate systems).

  1. Use a local bounding box to get the corners of the rectangle.1
  2. Install a frame with x={(bottom right)-(bottom left)},y={(top left-bottom left)},shift={(bottom left)} where the precise naming of the anchors is detailed in the code below.

Here is an example.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
 % store the rectangle in a local bounding box
 \draw[local bounding box=rect]  (8,1)  rectangle (0,2);
 % install a local coordinate system
 \begin{scope}[x={($(rect.south east)-(rect.south west)$)},
    y={($(rect.north west)-(rect.south west)$)},
    shift={(rect.south west)}]
  \node at (0.3,0.5) {here};
 \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

As you can see, in the scope the coordinate (0.3,0.5) means at 30% of the rectangle width and 50% of the rectangle height.

Obviously this can be used for different shapes, too. One can also introduce rotated coordinate systems and so on, but the above is a very basic example.

1The other answer, which I see only now, has also named the local bounding box rect. However, this answer differs in the installation of a local coordinate system.

5
  • Yes, you really install a local coordinate system, the other answer is what the tikz manual calls "partway modifiers" (see section 13.5.3). Honestly I'd prefer muzimuzhi's idea, since it is a bit more readable. However, if "partway modifiers" do not allow modifications in both directions (in 90° angle), I think yours offers more functionality.
    – atticus
    May 16, 2020 at 23:23
  • 2
    @atticus Yes, it's perfectly fine to prefer one way over the other. However, I prefer this way since this is what is used a lot in pgfplots and in general TikZ introduces local coordinate systems all over such as in path pictures, comoving frames in decorations etc. It depends on how much stuff you need to put into these local frames.
    – user194703
    May 16, 2020 at 23:32
  • Hm, yes I think this is true too, making your own coordinate system is in many situations very convenient, but mostly when, as you already mentioned, putting much stuff into the local frame. In my case I think I'll stick to the other solution if it allows me to specify the y coordinate as well. Otherwise I'll come back to this solution ;)
    – atticus
    May 16, 2020 at 23:43
  • 2
    @atticus Well, now the other answer is also using the [x=\x{rect}, y=\y{rect}, shift=(rect.south west)] method which I was proposing. In this scheme it is harder to manage multiple separate paths.
    – user194703
    May 17, 2020 at 2:06
  • Ok, thanks I'll keep that in mind but actually I think I'll stick to variant 1 (since this just about positioning some text and not 5 different objects).
    – atticus
    May 17, 2020 at 11:31

You must log in to answer this question.

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