I have a bunch of nodes and would like to size them so that their areas represent some numbers I have (so that if I have two nodes with corresponding values 1 and 2, then the second node's area should be double the first's). I'm trying to achieve this using some combination of minimum size and inner sep, but I've noticed that if I set minimum size to 0pt, then a node with inner sep = 2pt will not be double the area of a node with inner sep = 1pt.
-
3Do they have to be nodes? Whilst nodes are often convenient, it is possible to draw shapes in TikZ without them and it is easier to have direct control if done this way. – Andrew Stacey Mar 19 '12 at 08:31
-
Why isn't there simply an option to set the exact size? That would make it much easier to create perfectly square nodes too... – KasparJohannes Feb 19 '21 at 19:45
3 Answers
For nodes you can set inner sep=0pt and then use minimum size (if the node text is empty or shorter than the declared size) to control the area:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[every node/.style={draw=blue,thick,circle,inner sep=0pt}]
\draw[help lines] (-3,-3) grid (3,3);
\node[minimum size=2cm] (0,0) {};
\node[minimum size=2.828cm] (0,0) {};
\node[minimum size=4cm] (0,0) {};
\end{tikzpicture}
\end{document}

If you want to keep the size fixed independently of the node text, you can set text width (and perhaps also text height):
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[every node/.style={draw=blue,thick,circle,inner sep=0pt}]
\draw[help lines] (-3,-3) grid (3,3);
\node[text width=2cm] (0,0) {};
\node[text width=2.828cm] (0,0) {};
\node[text width=4cm] (0,0) {};
\end{tikzpicture}
\end{document}
As noted by Andrew Stacey, you could use shapes instead of nodes and this gives you the possibility to easily control the shape attributes; here are the same three circles using the circle operation:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[every node/.style={draw=blue,thick,circle,inner sep=0pt}]
\draw[help lines] (-3,-3) grid (3,3);
\draw[blue,thick] (0,0) circle [radius=1cm] ;
\draw[blue,thick] (0,0) circle [radius=1.414cm] ;
\draw[blue,thick] (0,0) circle [radius=2cm] ;
\end{tikzpicture}
\end{document}
- 505,128
I think the following should be working:
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\begin{document}
\pgfmathsetmacro{\nodebasesize}{1} % A node with a value of one will have this diameter
\pgfmathsetmacro{\nodeinnersep}{0.1}
\newcommand{\propnode}[5]{% position, name, options, value, label
\pgfmathsetmacro{\minimalwidth}{sqrt(#4*\nodebasesize)}
\node[#3,minimum width=\minimalwidth*1cm,inner sep=\nodeinnersep*1cm,circle,draw] (#2) at (#1) {#5};
}
\begin{tikzpicture}
\draw[<->] (2,-0.5) -- node[right] {$r=\sqrt{1} \Rightarrow A=\pi(\sqrt{1})^2=\pi$} (2,0.5);
\draw[gray] (2,-0.5) -- (0,-0.5);
\draw[gray] (2,0.5) -- (0,0.5);
\propnode{0,0}{n1}{fill=red,text=blue}{1}{1}
\draw[<->] (2,2-0.707) -- node[right] {$r=\sqrt{2} \Rightarrow A=\pi(\sqrt{2})^2=2\pi$} (2,2+0.707);
\draw[gray] (2,2-0.707) -- (0,2-0.707);
\draw[gray] (2,2+0.707) -- (0,2+0.707);
\propnode{0,2}{n2}{fill=green,text=black}{2}{2}
\draw[<->] (2,4-0.866) -- node[right] {$r=\sqrt{3} \Rightarrow A=\pi(\sqrt{3})^2=3\pi$} (2,4+0.866);
\draw[gray] (2,4-0.866) -- (0,4-0.866);
\draw[gray] (2,4+0.866) -- (0,4+0.866);
\propnode{0,4}{n3}{fill=yellow,text=violet}{3}{3}
\draw[<->] (11,1) -- node[right] {$r=\sqrt{9} \Rightarrow A=\pi(\sqrt{9})^2=9\pi$} (11,4);
\draw[gray] (11,1) -- (9,1);
\draw[gray] (11,4) -- (9,4);
\propnode{9,2.5}{n9}{fill=black,text=white}{9}{9}
\draw[<->] (11,-0.354) -- node[right] {$r=\sqrt{0.5} \Rightarrow A=\pi(\sqrt{0.5})^2=0.5\pi$} (11,0.354);
\draw[gray] (11,-0.354) -- (9,-0.354);
\draw[gray] (11,0.354) -- (9,0.354);
\propnode{9,0}{n05}{fill=pink,text=black}{0.5}{0.5}
\draw[ultra thick,red] (8.5,-0.5) -- (11.5,-0.5);
\end{tikzpicture}\\[2cm]
\pgfmathsetmacro{\nodebasesize}{1} % A node with a value of one will have this diameter
\pgfmathsetmacro{\nodeinnersep}{0.0}
\begin{tikzpicture}
\draw[<->] (2,-0.5) -- node[right] {$r=\sqrt{1} \Rightarrow A=\pi(\sqrt{1})^2=\pi$} (2,0.5);
\draw[gray] (2,-0.5) -- (0,-0.5);
\draw[gray] (2,0.5) -- (0,0.5);
\propnode{0,0}{n1}{fill=red,text=blue}{1}{1}
\draw[<->] (2,2-0.707) -- node[right] {$r=\sqrt{2} \Rightarrow A=\pi(\sqrt{2})^2=2\pi$} (2,2+0.707);
\draw[gray] (2,2-0.707) -- (0,2-0.707);
\draw[gray] (2,2+0.707) -- (0,2+0.707);
\propnode{0,2}{n2}{fill=green,text=black}{2}{2}
\draw[<->] (2,4-0.866) -- node[right] {$r=\sqrt{3} \Rightarrow A=\pi(\sqrt{3})^2=3\pi$} (2,4+0.866);
\draw[gray] (2,4-0.866) -- (0,4-0.866);
\draw[gray] (2,4+0.866) -- (0,4+0.866);
\propnode{0,4}{n3}{fill=yellow,text=violet}{3}{3}
\draw[<->] (11,1) -- node[right] {$r=\sqrt{9} \Rightarrow A=\pi(\sqrt{9})^2=9\pi$} (11,4);
\draw[gray] (11,1) -- (9,1);
\draw[gray] (11,4) -- (9,4);
\propnode{9,2.5}{n9}{fill=black,text=white}{9}{9}
\draw[<->] (11,-0.354) -- node[right] {$r=\sqrt{0.5} \Rightarrow A=\pi(\sqrt{0.5})^2=0.5\pi$} (11,0.354);
\draw[gray] (11,-0.354) -- (9,-0.354);
\draw[gray] (11,0.354) -- (9,0.354);
\propnode{9,0}{n05}{fill=pink,text=black}{0.5}{0.5}
\end{tikzpicture}\\[2cm]
\pgfmathsetmacro{\nodebasesize}{1.5} % A node with a value of one will have this diameter
\pgfmathsetmacro{\nodeinnersep}{0.0}
\begin{tikzpicture}
\propnode{0,0}{n1}{fill=red,text=blue}{1}{1}
\propnode{0,2}{n2}{fill=green,text=black}{2}{2}
\propnode{0,4}{n3}{fill=yellow,text=violet}{3}{3}
\propnode{9,2.5}{n9}{fill=black,text=white}{9}{9}
\propnode{9,0}{n05}{fill=pink,text=black}{0.5}{0.5}
\end{tikzpicture}
\end{document}
Example 1: If your node diameter becomes to small, your nodes will get to big (see red underline)

Example 2: If that occurs, you might decrease the inner sep:

Example 3: Here this helps, but in case it is still not enough, you may increase the base size of the nodes:

Edit 1: I added the option to draw control lines automatically as well as influence the node's font size, so you should be able to choose fitting settings easily:
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{xifthen}
\begin{document}
\pgfmathsetmacro{\nodebasesize}{1} % A node with a value of one will have this diameter
\pgfmathsetmacro{\nodeinnersep}{0.1}
\newcommand{\propnode}[7]{% position, name, options, value, label, show control lines (s for show), font size
\pgfmathsetmacro{\minimalwidth}{sqrt(#4*\nodebasesize)}
\node[#3,minimum width=\minimalwidth*1cm,inner sep=\nodeinnersep*1cm,circle,draw] (#2) at (#1) {#7 #5};
\ifthenelse{\equal{#6}{s}}
{ \draw[gray] ($(#1)+(0,\minimalwidth/2)$) -- ($(#1)+(\minimalwidth/2+1,\minimalwidth/2)$);
\draw[gray] ($(#1)+(0,-\minimalwidth/2)$) -- ($(#1)+(\minimalwidth/2+1,-\minimalwidth/2)$);
\draw[very thick,<->] ($(#1)+(\minimalwidth/2+1,\minimalwidth/2)$) -- ($(#1)+(\minimalwidth/2+1,-\minimalwidth/2)$);
}
{}
}
\begin{tikzpicture}
\propnode{0,0}{n1}{fill=red,text=blue}{1}{1}{s}{}
\propnode{0,2}{n2}{fill=green,text=black}{2}{2}{s}{}
\propnode{0,4}{n3}{fill=yellow,text=violet}{3}{3}{s}{}
\propnode{9,2.5}{n9}{fill=black,text=white}{9}{9}{s}{}
\propnode{9,0}{n05}{fill=pink,text=black}{0.5}{0.5}{s}{}
\end{tikzpicture}\\[2cm]
\pgfmathsetmacro{\nodebasesize}{0.5}
\pgfmathsetmacro{\nodeinnersep}{0.2}
\begin{tikzpicture}
\propnode{0,0}{n1}{fill=red,text=blue}{1}{1}{s}{\tiny}
\propnode{0,2}{n2}{fill=green,text=black}{2}{2}{s}{\tiny}
\propnode{0,4}{n3}{fill=yellow,text=violet}{3}{3}{s}{\tiny}
\propnode{9,2.5}{n9}{fill=black,text=white}{9}{9}{s}{\tiny}
\propnode{9,0}{n05}{fill=pink,text=black}{0.5}{0.5}{s}{\tiny}
\end{tikzpicture}\\[2cm]
\pgfmathsetmacro{\nodebasesize}{0.2}
\pgfmathsetmacro{\nodeinnersep}{0}
\begin{tikzpicture}
\propnode{0,0}{n1}{fill=red,text=blue}{1}{1}{s}{\scriptsize}
\propnode{0,2}{n2}{fill=green,text=black}{2}{2}{s}{\scriptsize}
\propnode{0,4}{n3}{fill=yellow,text=violet}{3}{3}{s}{\scriptsize}
\propnode{9,2.5}{n9}{fill=black,text=white}{9}{9}{s}{\scriptsize}
\propnode{9,0}{n05}{fill=pink,text=black}{0.5}{0.5}{s}{\scriptsize}
\end{tikzpicture}
\end{document}

- 40,123
-
You need to consider the width of the line !
\propnode{0,0}{n1}{fill=red,text=blue,draw=red,line width=8mm}{1}{1}– Alain Matthes Apr 27 '12 at 19:42 -
1In priciple yes, but as a decision:
closed, won't fix. Feel free to improve it though ;) – Tom Bombadil Apr 27 '12 at 20:33
Update
If their areas of the circle nodes represent some numbers with proportionality then you need to know exactly the radius. The radius depends of minimum width and of \pgflinewidth.
we have : radius = (minimum width + line width) / 2 if inner sep = 0pt
In the next example, I choice first minimum width=2cm then minimum width=2cm,line width=5mm and finally line width=5mm,minimum width=2cm-\pgflinewidth with in all cases inner sep= 0 pt.
\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\draw[help lines,step=0.1,,draw=orange] (0,0) grid (8,1);
\draw[help lines] (0,0) grid (8,1);
\node[minimum width=2cm,circle,inner sep=0pt,fill=blue!20,fill opacity=.5]{};
\node[minimum width=2cm,circle,inner sep=0pt,fill=blue!20,fill opacity=.5,
line width=5mm,draw=gray,opacity=.5] at (3,0){};
\node[circle,inner sep=0pt,fill=blue!20,,fill opacity=.5,
line width=5mm,draw=gray,opacity=.5,minimum width=2cm-\pgflinewidth] at (6,0) {};
\end{tikzpicture}
\end{document}

Now if I want to get three circles with areas equal to pi, 2pi and 3pi I created a macro `def\lw{2mm}` to change quickly the line width in all nodes
\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\tikzset{myrad/.style 2 args={circle,inner sep=0pt,minimum width=(2*(sqrt(#1)*1 cm ) - \pgflinewidth,fill=#2,draw=#2,fill opacity=.5,opacity=.8}}
\begin{tikzpicture}
\def\lw{2mm}
\draw[help lines,step=0.1,,draw=orange] (0,0) grid (8,1);
\draw[help lines] (0,0) grid (8,1);
\node[line width=\lw,myrad={1}{blue!20}] at (0,0) {1};
\node[line width=\lw,myrad={2}{red!20}] at (3,0) {2};
\node[line width=\lw, myrad={3}{green!20}] at (7,0) {3};
\end{tikzpicture}
\end{document}
Finally If you want nodes with areas equal to 1 cm^2, 2 cm^2 and 3 cm^2 : I change the line width for the second group of nodes
\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\tikzset{myrad/.style 2 args={circle,inner sep=0pt,minimum width=(2*(sqrt(#1/3.1415)*1 cm ) - \pgflinewidth,fill=#2,draw=#2,fill opacity=.5,opacity=.8}}
\begin{tikzpicture}
\def\lw{2mm}
\draw[help lines,step=0.1,,draw=orange] (0,0) grid (8,1);
\draw[help lines] (0,0) grid (8,1);
\node[line width=\lw,myrad={1}{blue!20}] at (0,0) {1};
\node[line width=\lw,myrad={2}{red!20}] at (3,0) {2};
\node[line width=\lw, myrad={3}{green!20}] at (7,0) {3};
\end{tikzpicture}
\begin{tikzpicture}
\def\lw{5mm}
\draw[help lines,step=0.1,,draw=orange] (0,0) grid (8,1);
\draw[help lines] (0,0) grid (8,1);
\node[line width=\lw,myrad={1}{blue!20}] at (0,0) {1};
\node[line width=\lw,myrad={2}{red!20}] at (3,0) {2};
\node[line width=\lw, myrad={3}{green!20}] at (7,0) {3};
\end{tikzpicture}
\end{document}

Update of my first answer
To avoid this kind of problem, we can use circles instead of circle nodes. But we need to adjust the radius wit the pgflinewidth. In the next example,I want a radius = 2cm so I need to use : radius=2cm-0.5\pgflinewidth. Then I need to create a node with the same dimensions.
Like the question about node and rectangle here, we can associate a node to the shape
The main problem : we can't use scale but it's more easy to place a label.
\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\tikzset{set node/.style={insert path={%
\pgfextra{%
\node[inner sep=0pt,outer sep = 0pt,draw=black, % draw= none only to show what I do
circle,
minimum width=2*\pgfkeysvalueof{/tikz/x radius}+0.5\pgflinewidth](#1) {};
}}}}
\begin{tikzpicture}
\draw[help lines] (-3,-3) grid (3,3);
\draw[blue,line width=5mm,opacity=.2] (0,0) circle [radius=2cm-0.5\pgflinewidth,set node=C1] ;
\draw[thick,->] (3,-3) -- (C1.east);
\end{tikzpicture}
\end{document}
- 95,075