37

Sometimes, nesting tikzpicture environments seems inevitable, e.g., if you want a node to contain a TikZ picture on its own. (Is it?) However, nesting tikzpicture environments is problematic, also because the inner environment inherits all TikZ attributes from the surrounding tikzpicture environment.

In a comment to a similar question, Martin Scharrer has suggested that

a command [that resets all TikZ/PGF attributes] would be very difficult to maintain, because all TikZ attributes would need to be set with it explicitly.

Is there a way, with the current implementation, to save/restore all of TikZ/PGF's internal state, in order to apply it to a nested tikzpicture environment? If not, what would be really necessary to implement a "clean start with default values" for nested tikzpicture environments? Any thoughts?

8
  • I put a comment on tikzpicture in node of another tikzpicture: how to screen of from inheriting style? because right of = is not inherited but it's right= of. Commented Mar 9, 2012 at 11:24
  • 2
    The clean start like Martin has wrote is to use a box. Commented Mar 9, 2012 at 11:31
  • Where did Martin write about the "clean start"?
    – krlmlr
    Commented Mar 9, 2012 at 11:55
  • In the question that Altermundus linked. It the {lrbox}part of Martin’s code
    – Tobi
    Commented Mar 9, 2012 at 11:59
  • 2
    @Turion To use positioning library between groups of tikz objects ; To build a tree within each node is a group of tikz objects ; etc. Commented Jul 29, 2012 at 15:08

2 Answers 2

23

Since Joseph has posted a "Not exactly an answer", I'm going to post my "not exactly an answer" answer as well. The reason that this is "not exactly an answer" is because I don't think that the question is the right way around. The question asks how to protect an inner tikzpicture from an outer one. My "answer" to that is:

  1. You don't want to.
  2. If you do, use a box.

The reason for the first is that in all likelihood you want some things to be inherited, most likely due to size. You might also want to inherit a colour. For this sort of partial inheritance, the best approach is to ensure that the inner tikzpicture explicitly sets those values that it doesn't want to inherit and then leaves the rest alone. This is the same as the normal scoping behaviour of TeX groups and pgfscopes.

The real problem with inner and outer tikzpictures is not protecting the inner from the outer, but protecting the outer from the inner. There are certain parts of a tikzpicture that are globally set because there are certain pieces of information that need to be shifted out of certain internal groupings and it is just so much easier to do this via setting global macros. The ones that I've encountered are:

  1. The bounding box of a picture.
  2. The coordinates of a node.

There may be others. The question What are most important variables set at the beginning of a tikzpicture? of a scope? was asked to gather this information. With bounding boxes, see https://tex.stackexchange.com/a/46792/86 and for nodes, see tikz : how to refer to a node, in nested nodes (there are plenty of other examples).

There is some code that fixes both of these problems. It's called the subpicture package and is part of the (excellent) tikz-qtree package (which is probably why not many people have heard of it - I only know because I was digging through that code to answer other questions on this site). This is also why this is "not quite an answer": I've never tried to use that code by itself so don't know how it would work outside of the tikz-qtree package. But then, I'm one of the staunchest "Don't nest tikzpictures" advocates around. But if I ever did have to nest tikzpictures, that would be the way that I would do it.

What I do know about it is that internally, it does use boxes. But it saves the bounding box and node information so that these are still accessible to the outer tikzpicture. So it is the best of both worlds in that sense.

1
  • My use case nesting tikzpictures is when I use the PGF backend from matplotlib and I want to include the resulting file in a larger tikz picture. I do like and use PGFPlots, but there are cases when I prefer or must use matplotlib.
    – tsj
    Commented Oct 14, 2020 at 19:33
29

Not exactly an answer, but the nearest I can get. TeX's approach to grouping means that you cannot easily isolate the 'inner' environment from the 'outer' one. The best approach is therefore to typeset the inner code first, by storing it in a box, then using the box in the 'outer' code

\newsavebox{\mybox}
\sbox{\mybox}{%
   \begin{tikzpicture}
     % Inner picture
   \end{tikzpicture}
 }
\begin{tikzpicture}
  % Outer picture
  % to include somewhere
  \usebox{\mybox}
\end{tikzpicture}
2
  • With this approach is it possible to define a \newcommand{\test}[1]{... #1} for the inner picture to use latter in the outer picture?
    – cacamailg
    Commented Apr 11, 2013 at 10:36
  • @cacamailg No, as this is just the same as simply inserting the code. TeX's grouping does not work in the same way as functional programming languages, so using \newcommand makes no odds here.
    – Joseph Wright
    Commented Apr 11, 2013 at 12:17

You must log in to answer this question.

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