0

I was experimenting with the potential of a TikZ node to populate in it as many items as possible to make it intricate. Generally, the contents increase the node size when they exceed its minimum height and width.

However when I try to embed TikZ overlay on a graphic image inside the node (suppose), the overlay works fine, but its content does not seem to affect the size of the node to which it belongs as you can see in the following figure as compiled from the given MWE following the figure.

output

As you can see, the text 'sample 1' appears out of the node region when its presence was supposed to increase the region's area to contain it.

The reason I am using the node this way is because I am using this node as part of a larger diagram and would relate other pieces of the diagram with this node.

Hence, how can I make TikZ overlay force node to increase its size?

\documentclass{article}

\usepackage[margin=1in]{geometry}

\usepackage{tikz}
\usepackage{graphicx}
\usepackage{xcolor,colortbl,ctable}
\usepackage{lmodern}

\definecolor{DarkPink}{rgb}{0.82,0.445,0.668}
\definecolor{LightPink}{rgb}{0.91,0.80,0.863}
\definecolor{Pink}{rgb}{0.871,0.664,0.793}

\begin{document}

\begin{tikzpicture}
\node[gray,fill=gray!10!white,rectangle,draw,thick,densely dashed,rounded corners=10pt,minimum size=1cm,inner sep=10pt,font=\sffamily,align=center] at (0,0){
                \includegraphics[height=3cm,width=3cm]{example-grid-100x100pt}\\[10pt]
                \begin{tikzpicture}[remember picture, overlay]
                    \draw[red, ultra thick,densely dotted,rounded corners=0pt] (1.25,3.35) node[yshift=2cm](a){sample 1} rectangle (2.5,4.8);
                    \draw[blue, ultra thick,densely dotted,rounded corners=0pt] (2.65,4.7) rectangle (4.2,1.85);
                \end{tikzpicture}
                {\renewcommand{\arraystretch}{1.25}
                \begin{tabular}{!{\color{white}\vrule}c!{\color{white}\vrule}c!{\color{white}\vrule}}
                    \arrayrulecolor{white}\hline
                    \rowcolor{DarkPink}
                    \textcolor{white}{\textbf{Data Set 1}} & \textcolor{white}{\textbf{Data Set 2}}\\
                    \arrayrulecolor{white}
                    \rowcolor{LightPink}
                    \specialrule{2pt}{0pt}{0pt}
                    \color{black}80\% from $v_1$ & \color{black}20\% from $v_1$\\
                    \arrayrulecolor{white}\hline
                    \rowcolor{Pink}
                    \color{black}80\% from $v_2$ & \color{black}20\% from $v_2$\\
                    \arrayrulecolor{white}\hline
                    \rowcolor{LightPink}
                    \color{black}80\% from $v_3$ & \color{black}20\% from $v_3$\\
                    \arrayrulecolor{white}\hline
                    \rowcolor{Pink}
                    \color{black}80\% from $v_4$ & \color{black}20\% from $v_4$\\
                    \arrayrulecolor{white}\hline
                \end{tabular}}
            };
\end{tikzpicture}

\end{document}
5
  • 2
    I don't really understand your issue, since you used a \draw command inside which you drew a node with node[yshift=2cm](a){sample 1}. It seems that the behaviour of this node is perfectly accurate to what you asked for. Now, what you did wrong is you nested tikzpictures, which is not meant to be and could lead to unpredictable behaviours.
    – SebGlav
    Mar 6, 2022 at 20:45
  • @SebGlav I used yshift there just to illustrate where I wanted the text to appear. However making a separate node with that same text in the same place will not also affect the size of outer node. I am aware that using tikzpicture inside nodes will yield unpredictable results. However using tikzpicture in usual way inside node doesn't seem to cause much problems for me. The only issue is with this overlay.
    – SolidMark
    Mar 6, 2022 at 20:52
  • I could arbitrarily change the minimum height and width of the node to cover the spaces if I wanted, but I was hoping for shortcuts.
    – SolidMark
    Mar 6, 2022 at 20:54
  • 2
    By definition, overlay means that the bounding box is not updated, that's sort of the point of it ... Excerpt from the manual (page 259 of the manual for 3.1.9a): "The effect of this option is that everything within the current scope is not taken into consideration when the bounding box of the current picture is computed." Mar 6, 2022 at 21:04
  • Is there any alternative to this? Is there 'overlay' that does update bounding box?
    – SolidMark
    Mar 6, 2022 at 21:07

1 Answer 1

2

In general, don't put a tikzpicture inside a node. See e.g. Proper nesting of tikzpicture environments: Reset all PGF values to their defaults

Perhaps you could place the components first and then draw the frame last, using the backgrounds library and its on background layer key. Or alternatively use a matrix to place the components. The dotted boxes are drawn using the corner of the node containing the image in both cases.

Not sure if these will work for your situation, but you can have a look at the examples below.

enter image description here

\documentclass{article}

\usepackage[margin=1in]{geometry}

\usepackage{tikz}
\usepackage{colortbl,ctable}
\usepackage{lmodern}
\usetikzlibrary{positioning, fit, backgrounds}

\definecolor{DarkPink}{rgb}{0.82,0.445,0.668}
\definecolor{LightPink}{rgb}{0.91,0.80,0.863}
\definecolor{Pink}{rgb}{0.871,0.664,0.793}

\begin{document}

\begin{tikzpicture}[font=\sffamily]
\node [inner sep=0] (img) {\includegraphics[height=3cm,width=3cm]{example-grid-100x100pt}};\\[10pt]

\node [below=2mm of img]{
                {\renewcommand{\arraystretch}{1.25}
                \begin{tabular}{!{\color{white}\vrule}c!{\color{white}\vrule}c!{\color{white}\vrule}}
                    \arrayrulecolor{white}\hline
                    \rowcolor{DarkPink}
                    \textcolor{white}{\textbf{Data Set 1}} & \textcolor{white}{\textbf{Data Set 2}}\\
                    \arrayrulecolor{white}
                    \rowcolor{LightPink}
                    \specialrule{2pt}{0pt}{0pt}
                    \color{black}80\% from $v_1$ & \color{black}20\% from $v_1$\\
                    \arrayrulecolor{white}\hline
                    \rowcolor{Pink}
                    \color{black}80\% from $v_2$ & \color{black}20\% from $v_2$\\
                    \arrayrulecolor{white}\hline
                    \rowcolor{LightPink}
                    \color{black}80\% from $v_3$ & \color{black}20\% from $v_3$\\
                    \arrayrulecolor{white}\hline
                    \rowcolor{Pink}
                    \color{black}80\% from $v_4$ & \color{black}20\% from $v_4$\\
                    \arrayrulecolor{white}\hline
                \end{tabular}}
            }; 
            
            \node [anchor=south west, red] at (img.north west) {Sample 1};
            \draw [red, densely dotted, thick] (img.north west) ++(3mm,-2pt) rectangle +(1cm,-1cm);
            \draw [blue, densely dotted, thick] (img.north west) ++(13mm,-4pt) rectangle +(1cm,-1.2cm);

% draw the frame box last 
\scoped[on background layer]            
   \node [fit=(current bounding box), gray,fill=gray!10!white,rectangle,draw,thick,densely dashed,rounded corners=10pt,minimum size=1cm,inner sep=5pt,font=\sffamily,align=center] {};            

\end{tikzpicture}


\begin{tikzpicture}

\matrix [
  every outer matrix/.style={
     gray,fill=gray!10!white, draw, thick,
     densely dashed, rounded corners=10pt,
     inner sep=5pt
   },
   font=\sffamily,align=center,
   ampersand replacement=\&]
{
\node [red] {Sample 1}; \\ 
\node [inner sep=0] (img) {\includegraphics[height=3cm,width=3cm]{example-grid-100x100pt}};\\
\node {
                {\renewcommand{\arraystretch}{1.25}
                \begin{tabular}{!{\color{white}\vrule}c!{\color{white}\vrule}c!{\color{white}\vrule}}
                    \arrayrulecolor{white}\hline
                    \rowcolor{DarkPink}
                    \textcolor{white}{\textbf{Data Set 1}} & \textcolor{white}{\textbf{Data Set 2}}\\
                    \arrayrulecolor{white}
                    \rowcolor{LightPink}
                    \specialrule{2pt}{0pt}{0pt}
                    \color{black}80\% from $v_1$ & \color{black}20\% from $v_1$\\
                    \arrayrulecolor{white}\hline
                    \rowcolor{Pink}
                    \color{black}80\% from $v_2$ & \color{black}20\% from $v_2$\\
                    \arrayrulecolor{white}\hline
                    \rowcolor{LightPink}
                    \color{black}80\% from $v_3$ & \color{black}20\% from $v_3$\\
                    \arrayrulecolor{white}\hline
                    \rowcolor{Pink}
                    \color{black}80\% from $v_4$ & \color{black}20\% from $v_4$\\
                    \arrayrulecolor{white}\hline
                \end{tabular}}
            }; \\ % end also the last row with \\
      };

       \draw [red, densely dotted, thick] (img.north west) ++(3mm,-2pt) rectangle +(1cm,-1cm);
       \draw [blue!50, densely dotted, thick] (img.north west) ++(14mm,-4pt) rectangle +(1cm,-1.2cm);
\end{tikzpicture}
\end{document}
2
  • I am not sure why, but using the first set of codes inside scope instead of tikzpicture makes the gray box extend to adjacent scope as well which was not what I intended. I want to limit the box only inside the scope environment.
    – SolidMark
    Mar 8, 2022 at 16:54
  • Ok so I managed to solve this problem by the use of local bounding box in scope option and then using it in fit.
    – SolidMark
    Mar 8, 2022 at 17:00

You must log in to answer this question.

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