7

I need to create a figure like this:

Enter image description here

And my poor code is the following.

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\draw[rounded corners=15pt]
(10,0) rectangle ++(15,3);
\begin{tikzpicture}
\draw (5,1) circle (1cm);
\end{tikzpicture}
\end{tikzpicture}
\end{document}

But this code does not work since the circle will be outside the rectangle, which I don't want.

So my question is:

Why does this code not work? In other programmes when you put a loop inside a loop it works as expected, but here putting a tikzpicture inside a tikzpicture does not work as I'd expect. That is, how do nested tikzpictures work in TikZ in general?

3
  • 2
    In general, nesting tikzpictures do not work. In some cases, you may get away with it. But you should generally expect it to break.
    – cfr
    May 6, 2016 at 2:19
  • I've tried to edit your question. Could you make sure that I've understood you correctly? I've also retagged it because tikz-pic is not appropriate here, and replaced the misleading use of pic in your question. In TikZ, pics are a specific construct. You aren't using them, so they are irrelevant here.
    – cfr
    May 6, 2016 at 2:24
  • Thanks and appreciate for making the question better and clear.
    – henry
    May 6, 2016 at 2:25

2 Answers 2

9

It is perfectly possible to nest loops. However, nesting tikzpicture environments is known to be hazardous. Although it sometimes works, it should be avoided. Basically, it is expected to break.

What I would do is to draw the circles first and the fit the outer box around them. For example:

\documentclass[border=5pt,tikz,multi]{standalone}
\usetikzlibrary{fit,positioning}
\begin{document}
\begin{tikzpicture}[ultra thick]
  \coordinate (c0) at (0,0);
  \foreach \i [count=\j, evaluate=\j as \k using \j-1, evaluate=\j as \m using { int(mod(\j,5))==0 ? "" : "draw" }, evaluate=\j as \n using { \j>10 ? "20mm" : "10mm" }] in {1,...,11}
  \node (c\j) [right=7.5pt of c\k |- c0, circle, anchor=north west, minimum size=\n, \m] {};
  \node [fit=(c1) (c11), draw, rounded corners=15pt, inner xsep=5mm, minimum height=30mm] {};
\end{tikzpicture}
\end{document}

radio

If you prefer, you can simply draw the circles one-by-one and then draw the box in the same way. Just name the leftmost and rightmost so that you can say fit=(<name 1>) (<name 2>) and all should be well.

In this particular case, you could, if you really wanted, nest the tikzpictures. However, (5,1) is at x=5cm, well to the left of the leftmost border of the box which is at x=10cm. So to put it in the box, you'd need to put it in the box.

You also need to put the tikzpicture inside a node. For example:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fit,positioning}
\begin{document}
\begin{tikzpicture}
  \draw [rounded corners=15pt] (10,0) rectangle ++(15,3);
  \node at (12.5,1.5) {% BREAKAGE EXPECTED !!
    \begin{tikzpicture}% DON"T TRY THIS AT HOME !!
      \draw circle (1cm);
    \end{tikzpicture}
  };
\end{tikzpicture}
\end{document}

circle in box

But there is not much point in courting disaster when it would be much easier to write

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fit,positioning}
\begin{document}
\begin{tikzpicture}
  \draw [rounded corners=15pt] (10,0) rectangle ++(15,3);
  \draw (12.5,1.5) circle (1cm);
\end{tikzpicture}
\end{document}

which produces the same result without the attendant risks and much more easily.

3
  • Nice overview/explanation, however I got one more brain fold when figured out first solution (+1) :-)
    – Zarko
    May 6, 2016 at 4:41
  • @Zarko Are you suggesting it is my solution which requires too much thinking? :-)
    – cfr
    May 6, 2016 at 11:57
  • no, I try to make a joke, that both solutions are similar complicated :-), however you offer more options, answer is more complete and consequently you lead :-) :-). With high respect,
    – Zarko
    May 6, 2016 at 13:13
6

One of many possible solution (considering the first @cfr comment):

\documentclass[border=11mm,
               tikz]{standalone}
\usetikzlibrary{calc}

    \begin{document}
\begin{tikzpicture}[
box/.style = {draw, rounded corners=15pt,
              minimum width=150mm, minimum height=30mm}
                    ]
\node (a)   [box] {};
\foreach \i in {1,...,4}
    \draw ($(a.west)+(1.1*\i,0.5)$) circle (5mm);
\foreach \i in {1,...,4}
    \draw ($(a.west)+(5+1.1*\i,0.5)$) circle (5mm);
\draw ($(a.east)-(2,0)$) circle (10mm);
\end{tikzpicture}
\end{document}

enter image description here

1
  • 3
    This solution requires too much thinking! (+1)
    – cfr
    May 6, 2016 at 3:05

You must log in to answer this question.

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