# programmatically drawing sinusoids with tikz

Here's eight full oscillations of a sine wave:

Here's the code:

\documentclass{standalone}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\draw[gray!20] (0,-2) grid (32,2); %Grid
\draw[black,-] (0, 0)  --  (32,0); %X-Axis
\draw[black,-] (0,-2)  --  (0 ,2); %Y-Axis
\draw[blue]    (0 ,0)              %Origin
%Sine-Wave%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sin (1 ,2) cos (2 ,0) sin (3 ,-2) cos (4 ,0) sin (5 ,2) cos (6 ,0) sin (7 ,-2) cos (8 ,0)
sin (9 ,2) cos (10,0) sin (11,-2) cos (12,0) sin (13,2) cos (14,0) sin (15,-2) cos (16,0)
sin (17,2) cos (18,0) sin (19,-2) cos (20,0) sin (21,2) cos (22,0) sin (23,-2) cos (24,0)
sin (25,2) cos (26,0) sin (27,-2) cos (28,0) sin (29,2) cos (30,0) sin (31,-2) cos (32,0);
\end{tikzpicture}

\end{document}


My question isn't necessarily about sine waves or trigonometric functions. It's more about writing algorithms with LaTeX and using it like a real programming language.

Notice how I manually specified 32 pairs of coordinates and referred to both sin & cos 16 times just to draw 8 iterations of the same curve? Say, I want to generate a series of different standalone waves that are similar but different to this one. I don't want to have to type in every single coordinate every time, I want to automate all the boring, repetitive stuff.

Now, I don't need somebody to just draw it for me and dump the code, but rather share and explain the different tricks & techniques you can use to solve it in a programmatic way. A lot of us aren't aware of the tools at our disposal. The goal is to show the rest of us how to approach and solve these problems on our own so we can learn to do it for ourselves.

• nice question, better to use for loops? – Raaja Aug 5 at 5:32
• Also consider accepting answers to your past questions, if you find them to be useful. – Raaja Aug 5 at 5:50
• Re "...so we can learn to do it for ourselves": You can't be serious. Don't you want to be spoon-fed like everybody else? – Peter Mortensen Aug 5 at 16:43
• @tjt263 did you got your answer for this question? if not, please explain what you miss, and if you did, please accept an answer that suits you the most. – Raaja Aug 17 at 6:31

For drawing of your sinus function I would use plot macro:

\documentclass[tikz, margin=3mm]{standalone}

\begin{document}
\begin{tikzpicture}
\draw[gray,thin] (0,-2) grid[xstep=pi/2,ystep=1] (8*pi,2); %Grid
\draw   (0, 0)  --  (8*pi,0)  %X-Axis
(0,-2)  --  (0 ,2);   %Y-Axis
% Sine-Wave, \x r means to convert '\x' from degrees to radians
\draw[blue] plot[domain=0:16*pi, samples=320] (0.5*\x,{2*sin(\x r)});
\end{tikzpicture}
\end{document}


Edit:

• TikZ provide macro plot for drawing of function. Its use is described in section 22.5 Plotting a Function, pp 339 in the TikZ & PGF Manual (version 3.1.4a).

• Since I define domain in radians, to argument of sin function is add r: sin(\x r), which make conversion of function argument from radians to degrees.

• in defining domain is used small trick. Since domain of eight function intervals is longer than text width, domain is shortened to half (to 16*pi and the same time the widths of intervals is shortened to0.5*\x (this double the function frequency):

\draw[blue] plot[domain=0:16*pi, samples=320] (0.5*\x,{2*sin(\x r)});

• That drawn function is smooth, I used 20 samples per radian (all together 320 samples)

• How does it work? – voices Aug 5 at 8:41
• @tjt263, I add some explanation. I hope to understand you the MWE, – Zarko Aug 5 at 12:36

Giving frequency, period and amplitude of sine wave with color as options in pic set. The grid is drawn according to the frequency, period and amplitude values. foreach loop in tikzset is started with zero, and the frequency is drawn with 0 to f-1. Drawing the sinusoid is based on TiKz fundamentals.

\documentclass[tikz,border=10pt]{standalone}
\tikzset{%
pics/sw/.style args={color=#1,f=#2,p=#3,a=#4}{%
code={%
\def\f{#2}%Frequency
\def\p{#3}%Period
\def\a{#4}%Amplitude
\draw[gray!20] (0,-\a) grid (\p*\f,\a); %Grid
\draw[black,-] (0, 0)  --  (\p*\f,0); %X-Axis
\draw[black,-] (0,-\a)  --  (0 ,\a); %Y-Axis
\pgfmathsetmacro{\k}{#2-1}
\foreach \t in{0,1,...,\k}{
\draw[thick,#1] ({\t*\p},0) sin (#3/4+\t*\p,#4)cos(#3/2+\t*\p,0)sin(#3*3/4+\t*\p,-#4)cos(#3+\t*\p,0);%
}%
}
}
}
\begin{document}
\begin{tikzpicture}
\pic {sw={color=blue,f=8,p=4,a=2}};
\end{tikzpicture}

\end{document}


For f=8, p=4 and a=2: \pic {sw={color=blue,f=8,p=4,a=2}};

For f=4, p=5 and a=3: \pic {sw={color=red,f=4,p=5,a=3}};

\documentclass[tikz,border=10pt]{standalone}
\tikzset{%
pics/sw/.style args={color=#1,f=#2,p=#3,a=#4}{%
code={%
\def\f{#2}%Frequency
\def\p{#3}%Period
\def\a{#4}%Amplitude
\draw[gray!50] (0,-\a) grid (\p*\f,\a); %Grid
\pgfmathsetmacro{\n}{#2*#3}
\foreach \x in{0,1,...,\n}{
\node at (\x,0)[below right]{\x};}
\draw[black,->] (0, 0)  --  (\p*\f+1,0)node[above]{$x$}; %X-Axis
\draw[black,->] (0,-\a)node[left]{-$#4$}  --  (0 ,\a+1)node[right]{$y$}; %Y-Axis
\node at (0,\a)[left]{$#4$};
\pgfmathsetmacro{\k}{#2-1}
\foreach \t in{0,1,...,\k}{
\draw[ultra thick,#1] ({\t*\p},0) sin (#3/4+\t*\p,#4)cos(#3/2+\t*\p,0)sin(#3*3/4+\t*\p,-#4)cos(#3+\t*\p,0);%
}%
\node at (\n/2,\a+1){$y=\sin\,x$};%
}
}
}
\begin{document}
\begin{tikzpicture}
\pic {sw={color=cyan,f=6,p=4,a=3}};
\end{tikzpicture}

\end{document}


• Would you like to shed some light on what we're looking at here? I think I like where you're going with this one, but I understand very little of it. – voices Aug 5 at 12:54
• I edited my answer. But my English is not good. I couldn't fully explain the code. Sorry. – ferahfeza Aug 5 at 13:11
• @tjt263 this is a very good answer indeed ;) – Raaja Aug 5 at 14:43
• @ferahfeza You can (as I always do) use an automatic translator like deepl.com – AndréC Aug 5 at 16:06
• @AndréC, thank you. I will try. – ferahfeza Aug 5 at 17:41

A very crude starting point with foreach loops. Not elegant (IMO), but gives one possibility.

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\draw[gray!20] (0,-2) grid (32,2); %Grid
\draw[black,-] (0, 0)  --  (32,0); %X-Axis
\draw[black,-] (0,-2)  --  (0 ,2); %Y-Axis
%% incorporating @marmot's (user121799) suggestion
\draw[blue] foreach \x in {1,5,...,29} { ({\x-1} ,0) sin ({\x} ,2) cos ({\x+1} ,0) sin ({\x+2}, -2) cos ({\x+3} ,0)};
\end{tikzpicture}
\end{document}


Nevertheless, I am pretty sure, you can do much more than this :)

• \draw[blue] foreach \x in {1,5,9,...,29} { ({\x-1} ,0) sin ({\x} ,2) cos ({\x+1} ,0) sin ({\x+2}, -2) cos ({\x+3} ,0)};` to make it one uninterrupted path. – user121799 Aug 5 at 6:59
• @user121799 Nice idea, I will incorporate that :) – Raaja Aug 5 at 7:28
• 1,5,..., 29 is enough ^^ – Black Mild Aug 5 at 7:42
• @BlackMild thanks edited as per your suggestion :) – Raaja Aug 5 at 8:06
• You only need the one loop? – voices Aug 5 at 8:49