17

I have to draw the probability distribution function (PDF) in the following MWE multiple times in a figure as well as across multiple figures. I have read the following questions:

and think that I would like to avoid nesting if possible. This is a simple MWE and for this specific problem, I could use absolute positioning of all the elements. But it is cumbersome. Another option is prepare a PDF file and include the image in a node. Is there a better option?

\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
  \begin{tikzpicture}[node distance=2em]
    \node(pdf){
      \begin{tikzpicture}
          \draw [step=0.25cm,lightgray,very thin] (0,0) grid (2.5,1.5);
          \draw [draw,->,ultra thick] (0,0.0) -- (0,1.5);
          \draw [draw,->,ultra thick] (0,0.0) -- (2.5,0);
          \draw [fill=blue!20!white,ultra thick,overlay] (0.2,0) ..controls
          (0.5,2.2) and (1,0.1) .. (2,0);
      \end{tikzpicture}
    };  
    \node [rectangle,draw, right=of pdf] (cfd) {Nonlinear Flow Solution};
    \path[draw,->] (pdf) -- (cfd); 
  \end{tikzpicture}
\end{document}
devendra
  • 2,818

2 Answers2

13

The simplest way IMHO is to typeset the inner tikzpicture in a savebox outside the other tikzpicture and then use the box inside the node. This way no settings of the parent tikzpicture will be picked up, because the inner one is already rendered.

\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{positioning}

\newsavebox\mybox

\begin{document}

  \begin{lrbox}{\mybox}
      \begin{tikzpicture}
          \draw [step=0.25cm,lightgray,very thin] (0,0) grid (2.5,1.5);
          \draw [draw,->,ultra thick] (0,0.0) -- (0,1.5);
          \draw [draw,->,ultra thick] (0,0.0) -- (2.5,0);
          \draw [fill=blue!20!white,ultra thick,overlay] (0.2,0) ..controls
          (0.5,2.2) and (1,0.1) .. (2,0);
      \end{tikzpicture}
  \end{lrbox}
  \begin{tikzpicture}[node distance=2em]
    \node(pdf){\usebox\mybox};
    \node [rectangle,draw, right=of pdf] (cfd) {Nonlinear Flow Solution};
    \path[draw,->] (pdf) -- (cfd); 
  \end{tikzpicture}
\end{document}

If you want to do this using a macro:

\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{positioning}

\newsavebox\mybox
\begin{lrbox}{\mybox}
      \normalfont% to ensure that the font is fully set up
      \begin{tikzpicture}
          \draw [step=0.25cm,lightgray,very thin] (0,0) grid (2.5,1.5);
          \draw [draw,->,ultra thick] (0,0.0) -- (0,1.5);
          \draw [draw,->,ultra thick] (0,0.0) -- (2.5,0);
          \draw [fill=blue!20!white,ultra thick,overlay] (0.2,0) ..controls
          (0.5,2.2) and (1,0.1) .. (2,0);
      \end{tikzpicture}
\end{lrbox}
\newcommand\mypdfimage{\usebox\mybox}


\begin{document}

  \begin{tikzpicture}[node distance=2em]
    \node(pdf){\mypdfimage};
    \node [rectangle,draw, right=of pdf] (cfd) {Nonlinear Flow Solution};
    \path[draw,->] (pdf) -- (cfd); 
  \end{tikzpicture}

And again:

  \begin{tikzpicture}[node distance=2em]
    \node(pdf){\mypdfimage};
    % [..]
  \end{tikzpicture}
\end{document}

But here the macro is just a short-cut, you can use \usebox\mybox directly if you don't mind.

Martin Scharrer
  • 262,582
  • Can the lrbox be included in preamble as a newcommand with \AtBeginDocument? – devendra Jan 04 '13 at 11:02
  • @devendra: lrbox can be used inside the preamble, too, but you might want to add \normalfont in front of it to ensure that the normal font is already set up. It can also be used inside \AtBeginDocument{..} as long as you don't have any special content, like verbatim material, which isn't allowed in a macro argument. Not sure what you mean with "as a newcommand". – Martin Scharrer Jan 04 '13 at 11:07
  • Thank you. I was thinking of defining a new macro named \pdffigure and use it in all the figures. I will also have to look into scaling this box for different figures. – devendra Jan 04 '13 at 11:11
  • @devendra: You should place the lrbox environment inside a macro definition then. Simply use \usebox\mybox everywhere or define a macro which contains these two. Note that you will need a separate saveboxes if you want to have multiple inner pictures. – Martin Scharrer Jan 04 '13 at 11:23
11

If your situation is that the subpicture is specified first then you can use the fit library together with the current bounding box to put a node around the subpicture.

\documentclass{report}
%\url{http://tex.stackexchange.com/q/89264/86}
\usepackage{tikz}
\usetikzlibrary{positioning,fit}

\begin{document}
  \begin{tikzpicture}[node distance=2em]
          \draw [step=0.25cm,lightgray,very thin] (0,0) grid (2.5,1.5);
          \draw [draw,->,ultra thick] (0,0.0) -- (0,1.5);
          \draw [draw,->,ultra thick] (0,0.0) -- (2.5,0);
          \draw [fill=blue!20!white,ultra thick,overlay] (0.2,0) ..controls
          (0.5,2.2) and (1,0.1) .. (2,0);
\node[fit=(current bounding box)] (pdf) {};
    \node [rectangle,draw, right=of pdf] (cfd) {Nonlinear Flow Solution};
    \path[draw,->] (pdf) -- (cfd); 
  \end{tikzpicture}
\end{document}

tikz subpicture using fit

If not, there is an equally simple alternative (which I just found out about from digging in the code) which allows you to define a node around a given scope. Simply put the local bounding box=<name> key on a scope and it will define a rectangular node around that scope.

\documentclass[border=10]{standalone}
%\url{http://tex.stackexchange.com/q/89264/86}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
  \begin{tikzpicture}[node distance=2em]
\begin{scope}[local bounding box=pdf]
          \draw [step=0.25cm,lightgray,very thin] (0,0) grid (2.5,1.5);
          \draw [draw,->,ultra thick] (0,0.0) -- (0,1.5);
          \draw [draw,->,ultra thick] (0,0.0) -- (2.5,0);
          \draw [fill=blue!20!white,ultra thick,overlay] (0.2,0) ..controls
          (0.5,2.2) and (1,0.1) .. (2,0);
\end{scope}
    \node [rectangle,draw, right=of pdf] (cfd) {Nonlinear Flow Solution};
    \path[draw,->] (pdf) -- (cfd); 
  \end{tikzpicture}
\end{document}

One difference is that the node specified by the scope is "tight" around its contents:

TikZ subnode with scope

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
  • In the second approach, does the scope environment take scale option? – devendra Jan 04 '13 at 11:06
  • @devendra No idea - try it and see! – Andrew Stacey Jan 04 '13 at 11:08
  • It works fine. I think that the second approach is better with a macro written to automate the process across all the figures. – devendra Jan 04 '13 at 11:15
  • 1
    I cannot place the pdf node relative to another node using scope. Say I wanted to place another pdf to the right of the text box then I cannot use right=of cfd. I tried. Without the possibility of relative node placement, this approach is of limited use. – devendra Jan 07 '13 at 15:11
  • @devendra I have some code to fix that in my TeX-SX answer directory but I can't locate the question to which it pertains (and it might not pertain to any question - I also use that directory as "scratch"). Worth another question ... – Andrew Stacey Jan 07 '13 at 19:39
  • 1
    Solved the problem by using \matrix environment. No need for positioning library usage. Thank you. – devendra Jan 07 '13 at 20:20