2

I need to generate a figure comprising 3 successive tikz pictures with vertical spacing in between. I've tried the following code:

\begin{figure}[h]
\caption{Cross-Validation with Three-Segmented Training Dataset}
\vspace{0.5 cm}
\begin{tikzpicture}
\node[text width=3cm] (Iteration 1)
    {Iteration 1};
  \node [draw, 
    minimum width = 2cm, 
    minimum height = 1cm,
    fill = green!30!, right = 0.5cm of Iteration 1, rectangle] (Segment 1) {Training};
  \node [draw, 
    minimum width = 2cm, 
    minimum height = 1cm, fill = green!30!, rectangle, right = 0.1cm of Segment 1] (Segment 2) {Training};
  \node [draw, 
    minimum width = 2cm, 
    minimum height = 1cm, fill = red!30!, rectangle, right = 0.1cm of Segment 2] (Segment 3) {Testing};
\end{tikzpicture}
\vspace{0.25 cm}
\begin{tikzpicture}
\node[text width=3cm] (Iteration 2)
    {Iteration 2};
  \node [draw, 
    minimum width = 2cm, 
    minimum height = 1cm,
    fill = red!30!, right = 0.5cm of Iteration 2, rectangle] (Segment 1) {Testing};
  \node [draw, 
    minimum width = 2cm, 
    minimum height = 1cm, fill = green!30!, rectangle, right = 0.1cm of Segment 1] (Segment 2) {Training};
  \node [draw, 
    minimum width = 2cm, 
    minimum height = 1cm, fill = green!30!, rectangle, right = 0.1cm of Segment 2] (Segment 3) {Training};
\end{tikzpicture}
\vspace{0.25 cm}
\begin{tikzpicture}
\node[text width=3cm] (Iteration 3)
    {Iteration 3};
  \node [draw, 
    minimum width = 2cm, 
    minimum height = 1cm,
    fill = green!30!, right = 0.5cm of Iteration 3, rectangle] (Segment 1) {Training};
  \node [draw, 
    minimum width = 2cm, 
    minimum height = 1cm, fill = red!30!, rectangle, right = 0.1cm of Segment 1] (Segment 2) {Testing};
  \node [draw, 
    minimum width = 2cm, 
    minimum height = 1cm, fill = green!30!, rectangle, right = 0.1cm of Segment 2] (Segment 3) {Training};
\end{tikzpicture}
\centering
\end{figure}

but the attached output is not correct. Why are the \vspace{0.25cm} commands not working in between the first and second tikz pictures (Iteration 1 and Iteration 2 respectively) as desired? Please offer the easiest/simplest solution. Thank you in advance.

4 Answers4

3

tikzpicture are positioned like letters and you have

a \vspace{0.25cm} b\vspace{0.25cm} c\vspace{0.25cm} d\vspace{0.25cm} e

in such a line a b c d e gets typeset as usual and possibly broken in to lines, and then after linebreaking the \vspace are added after the line in which they "naturally" fall.

Which is why all your vspace are acting at the same place. You want a paragraph break after each pair

a b

\vspace{0.25cm}

c d

\vspace{0.25cm}

e f

It is almost always best to use \vspace in vertical mode, so after a blank line. The behaviour when used in horizontal mode is predictable but not usually as desired.

David Carlisle
  • 757,742
2

Please offer the easiest/simplest solution.

Here are two solution I find easier than what you're trying to do.

In both the whole diagram is actualy just one TikZ picture so we can use TikZ to control the distance between everything.

The first one uses a matrix of nodes from the matrix library, the second one uses the chains library.

I'm also using the caption package to specify the distance between captions and content of the float as well as its position (so that the distance is inserted in the correct place).

Depending on your document class, better solution might exist because they bring their own control over float and caption management.

Code

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{chains, matrix}

\usepackage[skip=.25cm, figureposition=above]{caption} \tikzset{every matrix/.append style={% no padding around matrices every outer matrix/.append style={inner sep=+0pt, outer sep=auto}}} \begin{document} \begin{figure} \caption{Cross-Validation with Three-Segmented Training Dataset} \centering \tikz \matrix[ matrix of nodes, row sep = .25cm, column sep = .50cm, nodes={ draw, minimum width = 2cm, minimum height = 1cm, }, column 1/.style={ nodes = path only, % disables any drawing, filling etc text width = 3cm, }, tr/.style={fill=green!30}, te/.style={fill=red!30}, ]{ Iteration 1 & |[tr]| Training & |[tr]| Training & |[te]| Testing \ Iteration 2 & |[te]| Testing & |[tr]| Training & |[tr]| Training \ Iteration 3 & |[tr]| Training & |[te]| Testing & |[tr]| Training \ }; \end{figure}

\begin{figure} \caption{Cross-Validation with Three-Segmented Training Dataset} \centering \tikz[ node distance = .25cm and .50cm, start chain = rows going below, minimum height = 1cm, % valid for all nodes iter node/.style={ path only, text width = 3cm, }, ing node/.style={ draw, minimum width = 2cm }, tr/.style={ing node, fill=green!30, node contents=Training}, te/.style={ing node, fill= red!30, node contents= Testing}, ] \foreach[count=\i] \List in {{tr, tr, te}, {te, tr, tr}, {tr, te, tr}} \node[on chain=rows, iter node] {Iteration \i} [start branch=\i- going base right] node foreach \st in \List [on chain=rows/\i-, \st]{}; \end{figure} \end{document}

Qrrbrbirlbel
  • 119,821
1

This uses \lineskip to add the spacing between tikzpictures.

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{figure}[h] \setlength{\lineskip}{0.25cm}% \caption{Cross-Validation with Three-Segmented Training Dataset}

\begin{tikzpicture} \node[text width=3cm] (Iteration 1) {Iteration 1}; \node [draw, minimum width = 2cm, minimum height = 1cm, fill = green!30!, right = 0.5cm, rectangle] (Segment 1) at(Iteration 1.east) {Training}; \node [draw, minimum width = 2cm, minimum height = 1cm, fill = green!30!, rectangle, right = 0.1cm] (Segment 2) at (Segment 1.east) {Training}; \node [draw, minimum width = 2cm, minimum height = 1cm, fill = red!30!, rectangle, right = 0.1cm] (Segment 3) at (Segment 2.east) {Testing}; \end{tikzpicture} \begin{tikzpicture} \node[text width=3cm] (Iteration 2) {Iteration 2}; \node [draw, minimum width = 2cm, minimum height = 1cm, fill = red!30!, right = 0.5cm, rectangle] (Segment 1) at(Iteration 2.east) {Testing}; \node [draw, minimum width = 2cm, minimum height = 1cm, fill = green!30!, rectangle, right = 0.1cm] (Segment 2) at(Segment 1.east){Training}; \node [draw, minimum width = 2cm, minimum height = 1cm, fill = green!30!, rectangle, right = 0.1cm] (Segment 3) at(Segment 2.east) {Training}; \end{tikzpicture} \begin{tikzpicture} \node[text width=3cm] (Iteration 3) {Iteration 3}; \node [draw, minimum width = 2cm, minimum height = 1cm, fill = green!30!, right = 0.5cm, rectangle] (Segment 1) at(Iteration 3.east) {Training}; \node [draw, minimum width = 2cm, minimum height = 1cm, fill = red!30!, rectangle, right = 0.1cm] (Segment 2) at(Segment 1.east) {Testing}; \node [draw, minimum width = 2cm, minimum height = 1cm, fill = green!30!, rectangle, right = 0.1cm] (Segment 3) at(Segment 2.east){Training}; \end{tikzpicture} \centering \end{figure}

\end{document}

John Kormylo
  • 79,712
  • 3
  • 50
  • 120
0

Using \centering at the end is certainly not the best idea.

You want three paragraphs and to set the lineskip equal to the distance between the rectangles, namely 0.1cm.

You also want to avoid repetitive tasks and define styles.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage{caption}

\captionsetup[figure]{position=top}

\begin{document}

\begin{figure}[htp] \centering

\caption{Cross-Validation with Three-Segmented Training Dataset}

\setlength{\lineskip}{0.1cm} \tikzset{ segmented/.style={draw,minimum width=2cm,minimum height=1cm,rectangle}, G/.style={fill=green!30}, R/.style={fill=red!30}, }

\begin{tikzpicture} \node[text width=3cm] (Iteration 1) {Iteration 1}; \node[segmented,G,right = 0.5cm of Iteration 1] (Segment 1) {Training}; \node[segmented,G,right = 0.1cm of Segment 1] (Segment 2) {Training}; \node[segmented,R,right = 0.1cm of Segment 2] (Segment 3) {Testing}; \end{tikzpicture}

\begin{tikzpicture} \node[text width=3cm] (Iteration 2) {Iteration 2}; \node[segmented,R,right = 0.5cm of Iteration 2] (Segment 1) {Testing}; \node[segmented,G,right = 0.1cm of Segment 1] (Segment 2) {Training}; \node[segmented,G,right = 0.1cm of Segment 2] (Segment 3) {Training}; \end{tikzpicture}

\begin{tikzpicture} \node[text width=3cm] (Iteration 3) {Iteration 3}; \node[segmented,G,right = 0.5cm of Iteration 3] (Segment 1) {Training}; \node[segmented,R,right = 0.1cm of Segment 1] (Segment 2) {Testing}; \node[segmented,G,right = 0.1cm of Segment 2] (Segment 3) {Training}; \end{tikzpicture}

\end{figure}

\end{document}

enter image description here

I'd not set the width for the left parts and instead set inner sep=0pt.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage{caption}

\captionsetup[figure]{position=top}

\begin{document}

\begin{figure}[htp] \centering

\caption{Cross-Validation with Three-Segmented Training Dataset}

\setlength{\lineskip}{0.1cm} \tikzset{ segmented/.style={draw,minimum width=2cm,minimum height=1cm,rectangle}, G/.style={fill=green!30}, R/.style={fill=red!30}, }

\begin{tikzpicture} \node[inner sep=0pt] (Iteration 1) {Iteration 1}; \node[segmented,G,right = 0.5cm of Iteration 1] (Segment 1) {Training}; \node[segmented,G,right = 0.1cm of Segment 1] (Segment 2) {Training}; \node[segmented,R,right = 0.1cm of Segment 2] (Segment 3) {Testing}; \end{tikzpicture}

\begin{tikzpicture} \node[inner sep=0pt] (Iteration 2) {Iteration 2}; \node[segmented,R,right = 0.5cm of Iteration 2] (Segment 1) {Testing}; \node[segmented,G,right = 0.1cm of Segment 1] (Segment 2) {Training}; \node[segmented,G,right = 0.1cm of Segment 2] (Segment 3) {Training}; \end{tikzpicture}

\begin{tikzpicture} \node[inner sep=0pt] (Iteration 3) {Iteration 3}; \node[segmented,G,right = 0.5cm of Iteration 3] (Segment 1) {Training}; \node[segmented,R,right = 0.1cm of Segment 1] (Segment 2) {Testing}; \node[segmented,G,right = 0.1cm of Segment 2] (Segment 3) {Training}; \end{tikzpicture}

\end{figure}

\end{document}

enter image description here

egreg
  • 1,121,712