# Plot from scratch (without explicit data)

I'm trying to draw a plot which I've been given in a scan:

What is the correct way to plot a custom shaped curve --- a freehand tool counterpart. I used quick curve but it's hard to tell extremum from an inflection point.

\begin{figure}
\centering
\bt[xscale=0.03,yscale=0.03]
%\draw (0,0) grid[step=10](200,120);
\coordinate(a) at (0,0);
\coordinate(b) at (20,0);
\coordinate(c1) at (25,2);
\coordinate(c) at (30,10);
\coordinate(d) at (48,50);
\coordinate(ce) at (65,90);
\coordinate(e) at (80,110);
\coordinate(f) at (90,100);
\coordinate(g1) at (89,98);
\coordinate(g) at (93,95);
\coordinate(h) at (100,103);
\coordinate(ci) at (102,103);
\coordinate(i) at (130,100);
\coordinate(cj) at (165,96.6);
\coordinate(j) at (170,95);
\coordinate(ccl) at (172,90);
\coordinate(cl) at (198,5);
\coordinate(l) at (200,0);
\coordinate(m) at (206,-10);
\coordinate(n) at (218,0);
\coordinate(o) at (222,8);
\coordinate(cp) at (232,-3);
\coordinate(p) at (240,0);
\coordinate(r) at (248,0);
\coordinate(z) at (260,0);
\draw[>=latex,->](0,-18)--(0,128)node[left]{$U$};
\draw[>=latex,->](0,0)--(270,0)node[right]{$t$};
\draw[red,semithick] (a)--(b);
\draw[red,semithick] (b) to%
[quick curve through={(c1)(c)(d)(ce)(e)(f)(g)(h)(ci)(i)}] (cj);
\draw[red,semithick] (cj) to%
[quick curve through={(j)(ccl)(cl)(l)(m)(n)(o)(cp)(p)(r)}] (z);
\et
\caption{Charakterystyczne parametry przebiegów impulsowych}
\label{rys:przebiegimpulsowy}
\end{figure}


The result is very prone errors when any of the points is moved even a bit. Is there a better way to do that?

• Could you please include your preamble as well? – Alenanno Oct 20 '13 at 22:34
• I understand, that the question is general, but in this case one can probably obtain an expansion into a Fourier series. Which (Polish) book is the source of this picture? I hope that it contains an additional information. – Przemysław Scherwentke Oct 21 '13 at 4:07

I would do it using the the to[in=,out=,looseness=] operation, that way you need to specify coordinates and slopes, the looseness is an optional parameter that is 1 if not specifically set. Here's my first try with wildly guessing points. By the way: as it is, your curve is not a function of time as it reverses: \coordinate(f) at (90,100);comes before \coordinate(g1) at (89,98);, I changed that.

## Code

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{arrows}

\begin{document}

\newcounter{myc}

\newcommand{\setinitialcoordinates}[3]% x, y, slope in degrees
{   \xdef\lastx{#1}
\xdef\lasty{#2}
\xdef\lastslope{#3}
}

\newcommand{\drawpiece}[4][1]%[looseness] target x, target y, target slope
{   \pgfmathsetmacro{\colo}{mod(\value{myc},4)*20+20}
\stepcounter{myc}

\pgfmathsetmacro{\inslope}{mod(#4+180,360)}

\draw (\lastx,\lasty) to[out=\lastslope,in=\inslope,looseness=#1] (#2,#3);
%\draw[red!\colo!blue] (\lastx,\lasty) to[out=\lastslope,in=\inslope,looseness=#1] (#2,#3);

\xdef\lastx{#2}
\xdef\lasty{#3}
\xdef\lastslope{#4}
}

\begin{tikzpicture}[x={(0:0.03cm)},y={(90:0.03cm)}]
\draw[step=10,densely dotted, thin,gray] (0,0) grid (260,110);
\draw[-stealth,thick] (-5,0) -- (265,0) node[right] {$t$};
\draw[-stealth,thick] (0,-5) -- (0,115) node[left] {$U$};

\setinitialcoordinates{0}{0}{0}

\begin{scope}[red,very thick]
\drawpiece{20}{0}{0}
\drawpiece{25}{2}{45}
\drawpiece{30}{10}{70}
\drawpiece{48}{50}{80}

\drawpiece{65}{90}{70}
\drawpiece{80}{110}{0}
\drawpiece{89}{100}{-60}
\drawpiece{90}{98}{-30}

\drawpiece{93}{95}{0}
\drawpiece{100}{103}{3}
\drawpiece{102}{103}{0}
\drawpiece{130}{100}{-2}

\drawpiece{165}{96.6}{-10}
\drawpiece{170}{95}{-30}
\drawpiece{172}{90}{-70}
\drawpiece[0.2]{198}{5}{-85}

\drawpiece{200}{0}{-60}
\drawpiece{206}{-10}{0}
\drawpiece{218}{0}{60}
\drawpiece{222}{8}{0}

\drawpiece{232}{-3}{0}
\drawpiece{240}{0}{-5}
\drawpiece{248}{0}{1}
\drawpiece{260}{0}{0}
\end{scope}
\end{tikzpicture}

\end{document}


## Edit 1

The first attempt does not look to well, but I think mainly because I used all the points you provided. It looks a lot better if you just use the extrema and the knee:

## Code 1

\begin{tikzpicture}[x={(0:0.03cm)},y={(90:0.03cm)}]
\draw[step=10,densely dotted, thin,gray] (0,0) grid (260,110);
\draw[-stealth,thick] (-5,0) -- (265,0) node[right] {$t$};
\draw[-stealth,thick] (0,-5) -- (0,115) node[left] {$U$};

\setinitialcoordinates{0}{0}{0}

\begin{scope}[red,very thick]
\drawpiece{20}{0}{0}
\drawpiece[0.5]{80}{110}{0}
\drawpiece{93}{95}{0}
\drawpiece{102}{103}{0}

\drawpiece[0.5]{165}{96.6}{-10}

\drawpiece[0.3]{206}{-10}{0}
\drawpiece[0.7]{222}{8}{0}
\drawpiece{232}{-5}{0}
\drawpiece{248}{2}{0}
\drawpiece{260}{0}{0}
\end{scope}
\end{tikzpicture}


## Output 1

As you mentioned that your current solution is very sensitive to small changes, here's the same thing just with different x coordinates and a different knee angle:

## Code 2

\begin{tikzpicture}[x={(0:0.03cm)},y={(90:0.03cm)}]
\draw[step=10,densely dotted, thin,gray] (0,0) grid (260,110);
\draw[-stealth,thick] (-5,0) -- (265,0) node[right] {$t$};
\draw[-stealth,thick] (0,-5) -- (0,115) node[left] {$U$};

\setinitialcoordinates{0}{0}{0}

\begin{scope}[red,very thick]
\drawpiece{20}{0}{0}
\drawpiece[0.5]{60}{110}{0}
\drawpiece{110}{95}{0}
\drawpiece{120}{103}{0}

\drawpiece[0.5]{140}{96.6}{-40}

\drawpiece[0.3]{170}{-10}{0}
\drawpiece[0.7]{200}{8}{0}
\drawpiece{220}{-5}{0}
\drawpiece{240}{2}{0}
\drawpiece{260}{0}{0}
\end{scope}
\end{tikzpicture}


I realize this is not a LaTeX-only solution, and so it may be unsatisfactory, but I had to do this recently with a similar plot and this is what I did.

I used pgfplots to define a piecewise function whose pieces were minimal degree interpolating polynomials satisfying the constraints that I wanted (go through a point, have a certain derivative at a point, etc). Unfortunately, I don't know how to get the interpolating polynomials from within tike/pgfplots . . . you could use an external applet, python, mathematica, etc.

The result looked pretty good:

\documentclass{article}
\usepackage{pgfplots}

\begin{document}

\pgfmathdeclarefunction{MyF}{1}{%
\pgfmathparse{%
(and (1 , #1<=5)*(3.-0.5*#1-2.24667*#1^2+2.93766*#1^3-1.55322*#1^4+0.413019*#1^5-0.0534444*#1^6+0.00265741*#1^7))   +%
(and (5<#1 , #1<7)*(4))     +%
(and (7<=#1 , #1<12)*(131.4-156.613*#1+54.0096*#1^2-7.99267*#1^3+0.538*#1^4-0.0135556*#1^5))    +%
(and (12<=#1 , 1)*(1))  %
}%
}

\begin{center}
\begin{tikzpicture}
\begin{axis}[axis lines = middle,minor tick num = 1, grid = both, xlabel = $t$, ylabel = $x$, no markers, smooth,xmin=0, xmax=14, ymin=-6, ymax=6, samples = 100, thick]