# improving TikZ coordinate system/ voltage curve

I'm somewhat new to TikZ (this is my second TikZ picture so far :) )

It looks pretty much how I want it to look like, but I guess the code could be optimized. I have to draw quite a few similar voltage curves, so it would be nice if you could help me to optimize it!

Please note: The difference between the time tics and the visual appearance of the curve is on purpose!

Thanks!

\documentclass{article}
\usepackage{tikz}
\usepackage{verbatim}
\usepackage[active,tightpage]{preview}

\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{10pt}

\begin{document}
\begin{tikzpicture}

% horizontal axis
\draw[->] (0,0) -- (6.5,0) node (xaxis) [anchor=north] {t};

% vertical axis
\draw[->] (0,0) -- (0,2.5) node (yaxis) [anchor=east] {U};

% line
\draw[dotted] (1,0) coordinate (a) -- (1,1);
\draw[dotted]   (2,0) -- (2,2)
(4,0) -- (4,2)
(5,0) -- (5,1)
(6,0) -- (6,1);

% labels time
\draw   (0.5,1) node[anchor=north] {$t_0$}
(1.5,1) node[anchor=north] {$t_r$}
(3,1) node[anchor=north] {$t_1$}
(4.5,1) node[anchor=north] {$t_f$}
(5.5,1) node[anchor=north] {$t_2$};

%labels timestep
\draw   (0,0) node[anchor=north] {0}
(1,0) node[anchor=north] {1}
(2,0) node[anchor=north] {4}
(4,0) node[anchor=north] {10}
(5,0) node[anchor=north] {11}
(6,0) node[anchor=north] {13};

%labels voltage
\draw   (-0.5,1) node {$U_1$}
(-0.5,2) node {$U_2$};

% Us
\draw[thick] (0,1) -- (1,1) -- (2,2) -- (4,2) -- (5,1) -- (6,1);
%\draw[thick] (6,1) sin (7,0) cos (8,1);

\end{tikzpicture}
\end{document}


• Could you better explain what similar voltage curves means? Are all of them based on six coordinates? Are all labels always the same? ... Nov 17, 2016 at 8:27
• @Ignasi: No, they have different numbers of segments. But each segment has to be labled like here. Nov 17, 2016 at 8:47
• Part of the graphs are kind of like in this document: testforce.com/testforce_files/Seminars/… Nov 17, 2016 at 8:48
• Maybe it's possible to define the points and generate the labels and vertical lines out of it :) Nov 17, 2016 at 8:54

## 2 Answers

May be following code helps. It reduces all voltage line drawing to one foreach loop where each element consists in four values x coordinate/y coordinate/time label/segment label. Initial point coordinates are hidden inside initially parameter.

\documentclass[tikz,border=10pt]{standalone}

\begin{document}
\begin{tikzpicture}

% horizontal axis
\draw[->] (0,0) -- (6.5,0) node (xaxis) [anchor=north] {t};

% vertical axis
\draw[->] (0,0) node[below]{0} -- (0,2.5) node (yaxis) [anchor=east] {U};

\foreach \x/\y/\t/\l [remember=\x as \lastx (initially 0),
remember=\y as \lasty (initially 1)] in
{1/1/1/$t_0$,2/2/4/$t_r$,4/2/10/$t_1$,5/1/11/$t_f$,6/1/13/$t_2$}{
% voltage line
\draw (\lastx,\lasty)--(\x,\y);
% vertical reference
\draw[dotted] (\x,\y)--(\x,0) node[below] {\t};
% time label
\path (\lastx,1)--node[below] {\l} (\x,1);
}

\path (0,1) node[left] {$U_1$};
\path (0,2) node[left] {$U_2$};

\end{tikzpicture}
\end{document}


• Thank you very much for your help! I appreciate it. This makes it much easier :). Latex and TikZ are just amazing! Nov 18, 2016 at 9:02

I am not quite sure what a voltage curve looks like in general but it seems that you need to specify some (t,U)-coordinates, labels for the t-axis and the subscripts for the regions. I'd use a \foreach loop and throw everything into a macro that accepts the initial voltage and a comma separated list of the "coordinates" for the voltage curve like this:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{verbatim}
\usepackage[active,tightpage]{preview}

\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{10pt}

% \VoltageCurve[#1]{#2}
%    #1 = optional initial voltage (default 1)
%    #2 = comma separated list of t/U/t-label/t-subscript
\newcommand\VoltageCurve[2][1]{%
\begin{tikzpicture}
\draw  (0,0) node[anchor=north] {0};
\def\Umax{#1}
\foreach \t/\U/\tlab/\tsub [remember=\t as \tt (initially 0),
remember=\U as \UU (initially #1)] in {#2} {
\draw  (\t,0) node[anchor=north] {\tlab};
\draw[dotted](\t,0)--(\t,\U);
\draw[thick](\tt,\UU)--(\t,\U);
\node[anchor=north] at ($(\tt,1)!0.5!(\t,1)$) {$t_\tsub$};
\ifnum\U>\Umax\xdef\Umax{\U}\fi% Umax = max{y}
}
% axes
\draw[thin,->] (0,0) -- (\tt+0.5,0) node [anchor=north] {t};
\draw[thin,->] (0,0) -- (0,\Umax+0.5) node[anchor=east] {U};
% labels
\node at (-0.5, #1) {$U_1$};
\node at (-0.5, \Umax) {$U_2$};
\end{tikzpicture}%
}

\begin{document}
\VoltageCurve{1/1/1/0, 2/2/4/r, 4/2/10/1, 5/1/11/f, 6/1/13/2}

\VoltageCurve[2]{1/1/1/0, 2/2/4/r, 5/3/10/1, 7/1/11/f, 8/3/13/2, 9/1/16/z}
\end{document}


Here is the output of my MWE:

A few words of explanation:

• the (forward) slashes separate the variables in the \foreach loop
• the \tt and \UU variables "remember" the previous values of \t and \U, respectively
• \Umax remembers the maximum value of \U for drawing the \U axis
• the \t coordinates are assumed to be increasing
• the optional first argument gives the initial voltage (default 1)
• the first \t-label is assumed to be 0
• to place the t_<sub> label I use \usetikzlibrary{calc} to determine the point half-way in between \tt and t using ($(\tt,1)!0.5!(\t,1)$). It might be better to set the height of these labels to the initial voltage by replacing this with ($(\tt,#1)!0.5!(\t,#1)$).
• Thank you very much for your help! I appreciate it. This makes it much easier :). Latex and TikZ are just amazing! Nov 18, 2016 at 9:03
• The separators in the \foreach are (forward) slashes, not backslashes.
– Emma
Nov 19, 2016 at 4:57