5

I am trying to draw a figure will 6 separate time lines that I want to display and have them all align at the zero point. I draw them all at the y=0, but I would like to y-shift the entire time lines so I don't need to calculate the y-shift when drawing each line.

In the attached example how can I y-shift the entire second time line up the page by 1cm to not overlay the first timeline but keep the same x coordinates?

\documentclass[a4paper,11pt]{report}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\node[anchor=east] at (-1,0) {\textless Long Label \textgreater};
\draw (-1,0) -- node[fill=white,rotate=90,inner sep=-1.25pt,outer sep=0,anchor=center]{$\approx$} (0,0);
\draw [-latex] (-1,-10pt) -- (-1,0);
\node at (-1,-3ex) {0};
\foreach \x in {0,1,3,5,9,13,14,15} {        
\pgfmathsetmacro\result{\x * 4 + 104}
\coordinate (A\x) at ($(0,0)+(\x*0.85cm,0)$) {};
\draw [-latex] ($(A\x)-(0,10pt)$) -- ($(A\x)$)  ;
  \node at ($(A\x)+(0,-3ex)$) {\pgfmathprintnumber{\result}};
}
\draw (0,0) -- (19,0);
\draw (19,0) -- node[fill=white,rotate=90,inner sep=-1.25pt,outer sep=0,anchor=center]{$\approx$} (20,0);
\draw [-latex] (20,-10pt) -- (20,0);
\node at (20,-3ex) {264};

% How Do I yshift this down 1 cm to keep alignment

\node[anchor=east] at (-1,0) {\textless L2 \textgreater};
\draw (-1,0) -- node[fill=white,rotate=90,inner sep=-1.25pt,outer sep=0,anchor=center]{$\approx$} (0,0);
\draw [-latex] (-1,-10pt) -- (-1,0);
\node at (-1,-3ex) {0};
\foreach \x in {0,3,4,5,9,13} {        
\pgfmathsetmacro\result{\x * 4 + 104}
\coordinate (A\x) at ($(0,0)+(\x*0.85cm,0)$) {};
\draw [-latex] ($(A\x)-(0,10pt)$) -- ($(A\x)$)  ;
  \node at ($(A\x)+(0,-3ex)$) {\pgfmathprintnumber{\result}};
}
\draw (0,0) -- (19,0);
\draw (19,0) -- node[fill=white,rotate=90,inner sep=-1.25pt,outer sep=0,anchor=center]{$\approx$} (20,0);
\draw [-latex] (20,-10pt) -- (20,0);
\node at (20,-3ex) {264};

\end{tikzpicture}


\end{document}
0

1 Answer 1

6

Quick fix

To move around several paths, you can place them in a scope environment, and add yshift, xshift or shift in the optional argument to the environment, e.g.

\begin{scope}[yshift=-1cm]
  % all the code for one of the lines
\end{scope}

That said, by modifying the code used to draw one such line, you can both get more concise code, and code that perhaps is easier to modify.

Suggestion for new code

I'll add a bunch of explanations and stuff first, if you want, just skip right to the code in the end.

Drawing the arrows with numbers

In your code you do this in three steps. First calculate the position, then draw the arrow, and finally print the number. The first simplification you could do is to add the node in the `\draw, i.e.

\draw [-latex] ($(A\x)-(0,10pt)$) node[below] {\pgfmathprintnumber{\result}} -- ($(A\x)$);

This is still more verbose than necessary. By using relative coordinates, you don't actually need to use the syntax from the calc library at all, you could say

\draw [latex-] (A\x) -- ++(0,-10pt) node[below] {\pgfmathprintnumber{\result}};

Note that I draw the line in the opposite direction, and add the arrowhead to the start of the path.

You still have the \coordinate calculation on the line before though. By making use of the pin syntax for nodes you can do everything in just one line:

\node [inner sep=0pt, pin={[pin edge={latex-,black},pin distance=10pt]below:\pgfmathprintnumber{\result}}] at (\x*0.85cm,0) {};

First, the coordinate in your code was ($(0,0)+(\x*0.85cm,0)$), which is of course the same as just (\x*0.85cm,0). The inner sep declaration means that the node will have no padding around it's content. The pin operation adds a label to a node with a line drawn from the node to the label. pin edge is the style of the line, pin distance is self explanatory, below means that the pin is drawn below the node.

Now, in the code below I do this a bit differently. Instead of specifying the coordinate explicitly, I add the node at a specific position along the line, using the syntax

\node[arrownumber={$\result$}] at ($(linestart)!<fraction>!(lineend)$) {};

Here arrownumber is a custom style that does the pin stuff mentioned above, and the argument ({$\result$}) is the pin text. linestart and lineend are nodes added at the start and end of the complete line, and <fraction> is a number between 0 and 1 that is calculated in the \foreach loop.

The discontinuity symbols

You draw the line in three separate segments, adding a node at each breakpoint. You could do it as just one line, and add the nodes at specific positions, e.g.

\draw (0,0) node[left]{<long label>} -- ++(21,0)
  node[breakline,pos=0.5/21]{$\approx$}
  node[breakline,pos=20.5/21]{$\approx$};

Here I've added the label on the left in the same line. breakline is a custom style that does exactly what you had used, i.e. breakline/.style={fill=white,rotate=90,inner sep=-1.25pt,outer sep=0,anchor=center}.

However, the rendering of the symbol is not perfect, as the line doesn't perfectly hit the \approx. As an alternative I've used a custom direction, borrowing and adapting the code from https://tex.stackexchange.com/a/22379/586. This allows me to say

\draw[interrupt={0.5/21}{20.5/21}] (0,0) -- ++ (21,0);

where 0.5/21 and 20.5/21 are the relative positions along the line where the breakpoints are added.

Other comments

With the help of techniques like those described above, you can end up with a sequence of commands where the y coordinate is only specified once, in the left point of the line. Hence, adding more of these at different y coordinates becomes easy, as you just copy the code and change one number.

In the code below I've also taken it one step further, and put everything in a macro, so that you can say

\drawmyline[length of line]{<x-values>}{<start position>}{<left label>}

The length of the line is optional. <x-values> is the comma separated list of x-values used in the loop. <start position>} is a coordinate of the form x,y, and <left label> is the text added on the left side.

The code and output

enter image description here

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.markings}
\usepackage[T1]{fontenc}

\newcommand\drawmyline[4][21]{%
\draw[interrupt={0.5/21}{20.5/21}] (#3)
  node[left]{#4}
  -- ++(#1,0)
  node[arrownumber={$0$},pos=0](linestart){}
  node[arrownumber={$264$},pos=1](lineend){};

\foreach \x in {#2} {
 \pgfmathsetmacro\result{int(\x * 4 + 104)}
 \pgfmathsetmacro\MarkPos{(1+\x*0.85)/21}
 \node[arrownumber={$\result$}] at ($(linestart)!\MarkPos!(lineend)$) {};
}
}

\tikzset{
arrownumber/.style={
    inner sep=0pt,
    pin={[pin edge={latex-,black},pin distance=10pt,font=\footnotesize]below:#1}},
interrupt/.style 2 args={
    postaction={
        decorate,
        decoration={markings,
                    mark= at position #1 
                          with
                          {
                            \fill[white] (-0.05,0.2) to[out=250,in=70] (-0.05,-0.2) --
                                  (0.05,-0.2) to[out=70,in=250] (0.05,0.2);
                            \draw (-0.05,0.2) to[out=250,in=70] (-0.05,-0.2) 
                                  (0.05,-0.2) to[out=70,in=250] (0.05,0.2);
                          },
                    mark= at position #2
                          with
                          {
                            \fill[white] (-0.05,0.2) to[out=250,in=70] (-0.05,-0.2) --
                                  (0.05,-0.2) to[out=70,in=250] (0.05,0.2);
                            \draw (-0.05,0.2) to[out=250,in=70] (-0.05,-0.2) 
                                  (0.05,-0.2) to[out=70,in=250] (0.05,0.2);
                          }
                    }
                }
}}



\begin{document}
\begin{tikzpicture}

%\drawmyline[length of line]{x-values}{start position}{left label}

\drawmyline{0,1,3,5,9,13,14,15}{0,0}{long label}

\drawmyline{0,3,4,5,9,13}{0,-1}{longer label}


% this is the same code used in the \drawmyline macro
\draw[interrupt={0.5/21}{20.5/21}] (0,-2)
  node[left]{<long label>}
  -- ++(21,0)
  node[arrownumber={$0$},pos=0](linestart){}
  node[arrownumber={$264$},pos=1](lineend){};

\foreach \x in {0,1,3,5,9,13,14,15} {
 \pgfmathsetmacro\result{int(\x * 4 + 104)}
 \pgfmathsetmacro\MarkPos{(1+\x*0.85)/21}
 \node[arrownumber={$\result$}] at ($(linestart)!\MarkPos!(lineend)$) {};
}

\end{tikzpicture}
\end{document}

You must log in to answer this question.

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