[Tex/LaTex] Globally configure length units in TikZ

tikz-pgftikz-styles

Consider the following MWE:

\documentclass{standalone}
\usepackage{tikz}

\usetikzlibrary{positioning}


\begin{document}

\tikzset{
  x = 1cm,
  y = 1cm,
  node distance = 2,
  auto,
  on grid,
  test/.style =
  {
    draw,
    circle,
    inner sep = 0pt,
    semithick,
    minimum width = 0.5,
  },
  box/.style =
  {
    draw,
    rectangle,
    minimum width = 1,
    minimum height = 1,
    inner sep = 0pt,
  },
}

\begin{tikzpicture}

\node (node1) at (0,0) [label=right:test, test] {};
\node (node2) [below=of node1, label=right:box, box] {};

\node (node3) [right=of node1, label=right:test, test, minimum width = 0.5cm] {};
\node (node4) [below=of node3, label=right:box, box, minimum width = 1cm, minimum height = 1cm] {};

\end{tikzpicture}

\end{document}

In the first two lines of the tikzset statement, I want to set the measurement units to be 1cm, so, according to my oppinion, the test node should be 0.5cm in width (and height, because it is a circle), and the box node should have a side length of 1cm each. However, if we look at the result of the above code

wrong distances

we can clearly see that
a) the nodes seem to be positioned correctly, the appear like there is a 2cm distance between them, as expected;
b) the size of the left two nodes is wrong – I would expect the left two nodes to have the same size as the right two ones, but this isn't the case.

How shall I change my tikzset code to have the correct sizes of the left two nodes? I don't want to use something like

test/.style =
{
  draw,
  circle,
  inner sep = 0pt,
  semithick,
  minimum width = 0.5cm,
},

because I want the node sizes be relative to the node distances and relative to each other. If I would use absolute widths and heights within the style definitions for the nodes, this would be rather unflexible, so I wonder whether it is possible to set the length of "1 unit".

Best Answer

You can define a style unit length that sets a custom length \unitlen usable later in your drawings. I set the default length to 1cm in the following code.

\documentclass[tikz,border=7pt]{standalone}
\usetikzlibrary{positioning}

\newlength\unitlen
\tikzset{
  unit length/.code={\setlength{\unitlen}{#1}},
  unit length = 1cm,
  node distance = 2,
  auto,
  on grid,
  test/.style =
  {
    draw,
    circle,
    inner sep = 0pt,
    semithick,
    minimum width = 0.5\unitlen,
  },
  box/.style =
  {
    draw,
    rectangle,
    minimum width = 1\unitlen,
    minimum height = 1\unitlen,
    inner sep = 0pt,
  },
}
\begin{document}
  \begin{tikzpicture}
    \node (node1) at (0,0) [label=right:test, test] {};
    \node (node2) [below=of node1, label=right:box, box] {};
    \begin{scope}[unit length=.5cm]
      \node (node3) [right=of node1, label=right:test, test] {};
      \node (node4) [below=of node3, label=right:box, box] {};
    \end{scope}
  \end{tikzpicture}
\end{document}

enter image description here

Remarks :

  • The x=1cm and y=1cm are used only for coordinates without units, not for lengths.
  • Another solution is to pass a parameter to your box and test that is a length, with default value of 1cm.