You need to take precautions to use nesting tikzpicture
but but it is doable.
You need to also take certain precautions to work with tikzpicture
inside tikzpicture
or with scope
inside tikzpicture
. Everything depends on circumstances and what you want to do but I think there is always a way to deal.
I work on the next document for another question. The problem here is to place automatically the heart and I need to use an extern node '(txt)' to place a node inside the tikzpicture inside a node. Well Tikz is magic and do that without problem
\documentclass{scrartcl}
\usepackage[paperwidth=8cm,
paperheight=8cm,
margin=0cm,
left=0cm,
bottom=0mm]{geometry}
%\PassOptionsToPackage{dvipsnames,svgnames}{xcolor}
\usepackage{tikz}
\begin{document}
\pagestyle{empty}
\setlength{\parindent}{0em}
\tikzset{text style/.style={align = center,
text width = \textwidth}}
\newcommand\mytext{The life that I have \\
Is all that I have \\
And the life that I have \\
Is yours. \\
The love that I have \\
Of the life that I have \\
Is yours and yours and yours. \\
A sleep I shall have \\
A rest I shall have \\
Yet death will be but a pause.\\
For the peace of my years \\
In the long green grass \\
Will be yours and yours and yours.}
\null\vfill
\begin{tikzpicture}[remember picture]
\node[text style,color=red] (txt) {\mytext};
\node at (txt.center)
{\begin{tikzpicture}[fill = red]
\pgftransformscale{.025}
\pgfpathmoveto{\pgfqpoint{3600 pt}{3350 pt}}
\pgfpathcurveto{\pgfqpoint{3580 pt}{4270 pt}}
{\pgfqpoint{870 pt}{6400 pt}}
{\pgfqpoint{990 pt}{7860 pt}}%
\pgfpathcurveto{\pgfqpoint{1040 pt}{8430 pt}}
{\pgfqpoint{1590 pt}{9060 pt}}
{\pgfqpoint{2200 pt}{9060 pt}}%
\pgfpathcurveto{\pgfqpoint{3610 pt}{9050 pt}}
{\pgfqpoint{3600 pt}{7720 pt}}
{\pgfqpoint{3600 pt}{7720 pt}}%
\pgfpathcurveto{\pgfqpoint{3600 pt}{7720 pt}}
{\pgfqpoint{3580 pt}{9050 pt}}
{\pgfqpoint{4990 pt}{9060 pt}}%
\pgfpathcurveto{\pgfqpoint{5600 pt}{9060 pt}}
{\pgfqpoint{6150 pt}{8430 pt}}
{\pgfqpoint{6200 pt}{7860 pt}}%
\pgfpathcurveto{\pgfqpoint{6320 pt}{6400 pt}}
{\pgfqpoint{3610 pt}{4270 pt}}
{\pgfqpoint{3600 pt}{3350 pt}}%
\pgfpathclose
\pgfusepath{clip,fill,stroke}%
%
\node[white,
anchor = north west,
text style] at (txt.north west) {\mytext};
\end{tikzpicture}};
\end{tikzpicture}
\vfill
\end{document}
Update I added inside a new tikpicture inside a node inside a tikzpicture inside a node inside the first tikzpicture with opacity , filling.
I created the ant.pgf from the ant of the pst-fun with some difficulties because original picture use rlineto
and rcurveto
and I don't know if it's possible with pgf.
% http://altermundus.com/SandBox/ant1.pgf
\documentclass{scrartcl}
\usepackage[paperwidth=8cm,
paperheight=8cm,
margin=0cm,
left=0cm,
bottom=0mm]{geometry}
\PassOptionsToPackage{dvipsnames,svgnames}{xcolor}
\usepackage{tikz}
\makeatletter
\newcommand{\callornament}[1]{%
\begingroup
\def\i{\pgfusepath{clip}}%
\let\o\pgfpathclose
\let\s\pgfusepathqfillstroke
\def\p ##1##2{\pgfqpoint{##1bp}{##2bp}}%
\def\m ##1 ##2 {\pgfpathmoveto{\p{##1}{##2}}}%
\def\l ##1 ##2 {\pgfpathlineto{\p{##1}{##2}}}%
\def\r ##1 ##2 ##3 ##4 {\pgfpathrectangle{\p{##1}{##2}}{\p{##3}{##4}}}%
\def\c ##1 ##2 ##3 ##4 ##5 ##6 {%
\pgfpathcurveto{\p{##1}{##2}}{\p{##3}{##4}}{\p{##5}{##6}}}%
\@@input #1\relax
\endgroup}
\makeatother
\begin{document}
\pagestyle{empty}
\setlength{\parindent}{0em}
\tikzset{text style/.style={align = center,
text width = \textwidth}}
\newcommand\mytext{The life that I have \\
Is all that I have \\
And the life that I have \\
Is yours. \\
The love that I have \\
Of the life that I have \\
Is yours and yours and yours. \\
A sleep I shall have \\
A rest I shall have \\
Yet death will be but a pause.\\
For the peace of my years \\
In the long green grass \\
Will be yours and yours and yours.}
\null\vfill
\begin{tikzpicture}[remember picture]
\node[text style,color=red] (txt) {\mytext};
\node (h) at (txt.center)
{\begin{tikzpicture}[fill = red]
\pgftransformscale{.025}
\pgfpathmoveto{\pgfqpoint{3600 pt}{3350 pt}}
\pgfpathcurveto{\pgfqpoint{3580 pt}{4270 pt}}
{\pgfqpoint{870 pt}{6400 pt}}
{\pgfqpoint{990 pt}{7860 pt}}%
\pgfpathcurveto{\pgfqpoint{1040 pt}{8430 pt}}
{\pgfqpoint{1590 pt}{9060 pt}}
{\pgfqpoint{2200 pt}{9060 pt}}%
\pgfpathcurveto{\pgfqpoint{3610 pt}{9050 pt}}
{\pgfqpoint{3600 pt}{7720 pt}}
{\pgfqpoint{3600 pt}{7720 pt}}%
\pgfpathcurveto{\pgfqpoint{3600 pt}{7720 pt}}
{\pgfqpoint{3580 pt}{9050 pt}}
{\pgfqpoint{4990 pt}{9060 pt}}%
\pgfpathcurveto{\pgfqpoint{5600 pt}{9060 pt}}
{\pgfqpoint{6150 pt}{8430 pt}}
{\pgfqpoint{6200 pt}{7860 pt}}%
\pgfpathcurveto{\pgfqpoint{6320 pt}{6400 pt}}
{\pgfqpoint{3610 pt}{4270 pt}}
{\pgfqpoint{3600 pt}{3350 pt}}%
\pgfpathclose
\pgfusepath{clip,fill,stroke}%
%
\node[white,
anchor = north west,
text style] at (txt.north west) {\mytext};
\node at (txt.center){\tikz \pgftransformscale{.0125}%
\pgfsetfillcolor{MidnightBlue}%
\pgfsetfillopacity{.5}%
\callornament{ant1.pgf} ;};
\end{tikzpicture}};
\end{tikzpicture}
\vfill
\end{document}
I just had a similar question marked as a duplicate of this one. Here is the link. Unfortunately, the answer posted here was not marked as an answer and OP indicated it as not working. Credit for this approach goes to @symbol-1.
As noted by @percusse here and @cfr and @symbol-1 in the link, the result will be viewer dependent. Examples of viewer differences provided below the code.
Here is modified from the OP and @percusse's answer using transparency group=knockout
in the scope
environment options:
\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}
\begin{document}
\begin{tikzpicture}
\path[pattern=crosshatch dots light steel blue](-2,-2) rectangle (2,2);
\begin{scope}[transparency group=knockout]
\draw (-2,0) to node(aaaaa){} (2,0);
\path (aaaaa) node[fill,opacity=0,text opacity=1]{aaaaa};
\end{scope}
\end{tikzpicture}
\end{document}
You can change the background to anything you like and no other changes are necessary. If you change the text to be longer/short, the background opacity will resize accordingly - i.e. no changes other than the label name.
In some PDF viewers (e.g. SumatraPDF, TeXworks previewer, etc.):
In other PDF viewers (e.g. Adobe Acrobat):
The PDF is the same in both cases. I simply took a screenshot of it opened in two different PDF viewers. It seems the background is affected as well, but the focus here is the transparency.
Also, here is an example of an additional node with text going vertically to illustrate what happens with transparency group=knockout
with multiple nodes:
\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}
\begin{document}
\begin{tikzpicture}
\path[pattern=crosshatch dots light steel blue](-2,-2) rectangle (2,2);
\begin{scope}[transparency group=knockout]
\draw (-2,0) to node(aaaaa){} (2,0);
\path (aaaaa) node[fill,opacity=0,text opacity=1]{aaaaa};
\draw (0,-2) to node(bbbbb){} (0,2);
\path (bbbbb) node[fill,opacity=0,text opacity=1]{\rotatebox[origin=c]{90}{bbbbb}};
\draw (-2,-0.35) to node(ccccc){} (2,-0.35);
\path (ccccc) node[fill=red,text opacity=1]{ccccc};
\end{scope}
\end{tikzpicture}
In some PDF viewers (e.g. SumatraPDF, TeXworks previewer, etc.):
In other PDF viewers (e.g. Adobe Acrobat):
You will notice that whichever item is last with opacity=0
takes precedence over the previous item(s). If you flip the aaaaa
and bbbbb
lines and nodes (i.e bbbbb
occurs first), for example, you'll see this (in the conforming PDF viewers):
opacity=0
also takes precedence over other items which do not have opacity. For example, if we move the ccccc
node/lines first within the tikzpicture
, here is the result:
Just remember! If your picture is very complicated and you open it in an old or (transparency) non-conforming PDF viewer, it will not be what you expect.
If you have many nodes with transparency and you do not like the overlapping issue, you will need to adjust the order of the nodes, xshift
and yshift
, and/or place the nodes in different positions completely.
Best Answer
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:
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
pgfscope
s.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:
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 thetikz-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.