# Plot construction for a velocity vs position graph. Interpolation for phase-diagram construction?

I need to plot a few graphs. First is of the function

    $$x(t)= -e^{ -(0.1 \ {s}^{-1}) t} \cos \left( ( 0.995 \ {rad} / \mathrm{s})t \right)$$


and of $\dot{x}$ (time derivative function)

$$\dot{x}(t)= e^{-(0.1 \ {s}^{-1}) t}\left[(0.1 \ {s}^{-1}) \cos \left( ( 0.995 \ {rad} / \mathrm{s})t \right)+ ( 0.995 \ {rad} / \mathrm{s})\sin ( ( 0.995 \ {rad} / \mathrm{s})t )\right] .$$


I have so far made their individual plots by doing the following

    \begin{figure}[ht]
\centering
\caption{ The plots of the position and speed versus time (underdamped oscillator).}
\begin{tikzpicture}[scale=1.9]
\begin{axis}[
axis lines = left,
xlabel = {$t$, $\left[\text{s} \right]$},
%ylabel = {$a(t)$, $\left[\text{m/s}^2 \right]$},
grid=major,
ymin=-1,
ymax=1,
]
domain=0:60,
samples=300,
color=YellowGreen,
thick,
]
{2.71828^(-0.1*x)*cos(deg(0.995*x-3.1415))};
\addlegendentry{\tiny $x(t)$, , $\left[\text{cm} \right]$}
domain=0:60,
samples=300,
color=TealBlue,
thick,
]
{-2.71828^(-0.1*x)*((0.1*cos(deg(0.995*x-3.1415))+0.995*sin(deg(0.995*x-3.1415))) };
\addlegendentry{\tiny $\dot{x}(t)$,  $\left[\text{cm/s} \right]$}
\end{axis}
\end{tikzpicture}
\end{figure}


with the resulting graph

What remains a problem: question 1. The second plot I need is the phase diagram, i.e. $\dot{x}(t)$ vs $x(t)$ plot, which I am not sure how to construct. I was thinking sampling/point-harvesting of the function $x(t)$ and $\dot{x}(t)$ to then use those points for interpolation-construction of the phase diagram might be somehow implemented? However, I could not find a lot of information about these kinds of things on latex forums. My boyfriend has made his graphs with python, so I know the phase diagram must look like the following

But I was hoping to there is some way of making the graphs using latex alone. Any ideas?

What remains a problem: question 2. I also was wondering if there is any way of determining how many times does the system cross the $x=0$ line before the amplitude falls below $10^{-2}$ of its maximum value, but if it is possible to do only using latex commands to output this number.

• The first question can be answered by : use a parametric plot of the two you already have. The second one can be either done analytically or with the intersections.
– user194703
Apr 25, 2020 at 19:23

Apparently Bamboo and I had very similar ideas. This one also counts the intersections you are asking for in the second part of the question. (There was a lot of cleaning involved, many changes are very similar to Bamboo's nice answer.)

\documentclass{article}
\usepackage{geometry}
\usepackage[fleqn]{amsmath}
\usepackage{siunitx}
\usepackage[dvipsnames]{xcolor}
\usepackage{pgfplots}
\pgfplotsset{compat=1.17}
\begin{document}
$$x(t)= -\mathrm{e}^{ -(\SI{0.1}{\per\second}) t}\, \cos \left( ( \SI{0.995}{\radian\per\second})t \right)$$
and of $\dot{x}$ (time derivative function)
$$\dot{x}(t)= \mathrm{e}^{-(\SI{0.1}{\per\second}) t} \left[(\SI{0.1}{\per\second}) \cos \left( (\SI{0.995}{\radian\per\second})t \right) + ( \SI{0.995}{\radian\per\second})\sin ( ( \SI{0.995}{\radian\per\second})t )\right] .$$

\begin{figure}[ht]
\centering
\caption{The plots of the position and speed versus time (underdamped oscillator).}
\begin{tikzpicture}[scale=1.6]
\begin{axis}[declare function={%
pos(\x)=exp(-0.1*\x)*cos(deg(0.995*\x-pi));%
posdot(\x)=-exp(-0.1*\x)*((0.1*cos(deg(0.995*\x-pi))+0.995*sin(deg(0.995*\x-pi)));
},
axis lines = left,
xlabel = {$t$, $\left[\text{s} \right]$},
%ylabel = {$a(t)$, $\left[\text{m/s}^2 \right]$},
grid=major,
ymin=-1,
ymax=1,
legend style={font=\footnotesize}
]
domain=0:60,
samples=300,
color=YellowGreen,
thick,
]
{pos(x)};
\addlegendentry{$x(t)~\left[\si{\centi\meter}\right]$}
domain=0:60,
samples=300,
color=TealBlue,
thick,
]
{posdot(x)};
\addlegendentry{$\dot{x}(t)~ \left[\si{\centi\meter\per\second} \right]$}
\end{axis}
\end{tikzpicture}
\end{figure}

\begin{figure}[ht]
\centering
\begin{tikzpicture}[scale=1.6]
\begin{axis}[declare function={%
pos(\x)=exp(-0.1*\x)*cos(deg(0.995*\x-pi));%
posdot(\x)=-exp(-0.1*\x)*((0.1*cos(deg(0.995*\x-pi))+0.995*sin(deg(0.995*\x-pi)));
},
axis lines = left,
xlabel = {$x(t)~ \left[\si{\centi\meter} \right]$},
ylabel = {$\dot x(t)~ \left[\si{\centi\meter\per\second} \right]$},
grid=major,
ymin=-1,
ymax=1,
xmax=0.75
]
domain=0:60,
samples=601,
color=blue,
thick,smooth
]({pos(x)},{posdot(x)});
domain=0:60,
samples=601,
draw=none]({pos(x)},{posdot(x)});
\path[name path=axis]
(0,1) -- (0,{abs(pos(0))/100})
(0,-1) -- (0,{-abs(pos(0))/100})
;
\path[name intersections={of=phase and axis,total=\t}]
\pgfextra{\xdef\MyNumIntersections{\t}};
\end{axis}
\end{tikzpicture}
\caption{Phase space diagram. The phase curve intersects
$\MyNumIntersections$
times with the $x=0$ axis before reaching 0.01 times its maximal value.}
\end{figure}
\end{document}


Note:

1. I kept the declarations of functions local since it is somewhat harder to redeclare them, though not impossible. That is, if you declare pos(\x) globally, you cannot easily declare another function of this name.
2. pgf knows the values of pi and e, and you can use the exp function.
3. I compute the intersection with an invisible, non smooth plot because the intersection number is never completely trustable, and becomes more shaky for smooth plots.

ADDENDUM: Just for fun: this uses Bamboo's nice idea of installing a filter for computing the intersections in the first plot, where the result is much more reliable. The good news is that the number 14 gets confirmed, so the above seems to give the right number (accidentally or not). The analytic result is int(10*ln(100))=14, so all good. In this version, I also removed the \left and \rights as proposed by Bamboo. Anyway, the point is that computing the intersections in the first plot should be very reliable, in the second plot I am not so sure.

\documentclass{article}
\usepackage{geometry}
\usepackage[fleqn]{amsmath}
\usepackage{siunitx}
\usepackage[dvipsnames]{xcolor}
\usepackage{pgfplots}
\pgfplotsset{compat=1.17}
\begin{document}
$$x(t)= -\mathrm{e}^{ -(\SI{0.1}{\per\second}) t}\, \cos \left( ( \SI{0.995}{\radian\per\second})t \right)$$
and of $\dot{x}$ (time derivative function)
$$\dot{x}(t)= \mathrm{e}^{-(\SI{0.1}{\per\second}) t} \left[(\SI{0.1}{\per\second}) \cos \left( (\SI{0.995}{\radian\per\second})t \right) + ( \SI{0.995}{\radian\per\second})\sin ( ( \SI{0.995}{\radian\per\second})t )\right] .$$

\begin{figure}[ht]
\centering
\caption{The plots of the position and speed versus time (underdamped oscillator).}
\begin{tikzpicture}[scale=1.6]
\begin{axis}[declare function={%
pos(\x)=exp(-0.1*\x)*cos(deg(0.995*\x-pi));%
posdot(\x)=-exp(-0.1*\x)*((0.1*cos(deg(0.995*\x-pi))+0.995*sin(deg(0.995*\x-pi)));
},
axis lines = left,
xlabel = {$t~ [\text{s} ]$},
%ylabel = {$a(t)$, $\left[\text{m/s}^2 \right]$},
grid=major,
ymin=-1,
ymax=1,
legend style={font=\footnotesize}
]
domain=0:60,
samples=300,
color=YellowGreen,
thick,
]
{pos(x)};
\addlegendentry{$x(t)~[\si{\centi\meter}]$}
domain=0:60,
samples=300,
color=TealBlue,
thick,
]
{posdot(x)};
\addlegendentry{$\dot{x}(t)~ [\si{\centi\meter\per\second} ]$}
x filter/.expression={abs(pos(x))<abs(pos(0))/100 ? nan :x},
domain=0:60,
samples=300,
draw=none]
{pos(x)};
\path[name path=axis] (0,0) -- (60,0);
\path[name intersections={of=x and axis,total=\t}]
foreach \X in {1,...,\t} {(intersection-\X) node[red,circle,inner sep=1.2pt,fill]{}}
(60,-1) node[above left,font=\footnotesize,
align=right,text width=6.5cm]{$x(t)$ intersects $\t$ times
with the $x=0$ axis before dropping below $1\%$ of its initial amplitude.};
\end{axis}
\end{tikzpicture}
\end{figure}

\begin{figure}[ht]
\centering
\begin{tikzpicture}[scale=1.6]
\begin{axis}[declare function={%
pos(\x)=exp(-0.1*\x)*cos(deg(0.995*\x-pi));%
posdot(\x)=-exp(-0.1*\x)*((0.1*cos(deg(0.995*\x-pi))+0.995*sin(deg(0.995*\x-pi)));
},
axis lines = left,
xlabel = {$x(t)~ [\si{\centi\meter}]$},
ylabel = {$\dot x(t)~ [\si{\centi\meter\per\second} ]$},
grid=major,
ymin=-1,
ymax=1,
xmax=0.75
]
domain=0:60,
samples=601,
color=blue,
thick,smooth
]({pos(x)},{posdot(x)});
domain=0:60,
samples=601,
draw=none]({pos(x)},{posdot(x)});
\path[name path=axis]
(0,1) -- (0,{abs(pos(0))/100})
(0,-1) -- (0,{-abs(pos(0))/100})
;
\path[name intersections={of=phase and axis,total=\t}]
\pgfextra{\xdef\MyNumIntersections{\t}};
\end{axis}
\end{tikzpicture}
\caption{Phase space diagram. The phase curve intersects
$\MyNumIntersections$
times with the $x=0$ axis before reaching 0.01 times its maximal value.}
\end{figure}
\end{document}


• I did not know how to extract the count of intersections from the tikzpicture, now I do ! Apr 25, 2020 at 20:20

Here is a somewhat cleaner version of you code along with the parametric plot mentioned by @Schrödinger's cat.

Note the use of the siunitx package for the typesetting of units. Also, \left[... \right] are really not necessary in such a situation. Finally, I declared your functions explicitely to ease their use with the tikz declare function setting.

EDIT An updated version plotting the intersections and drawing a node in the parametric plot using this information. Note that I use a x filter to discard low amplitude results in this plot which is noticeably different from Schrödinger's cat approach.

\documentclass[tikz,dvipsnames,border=3.14mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usepackage{siunitx}

\usetikzlibrary{intersections}

\tikzset{
declare function={
f(\t) = 2.71828^(-0.1*\t)*cos(deg(0.995*\t-3.1415));
df(\t) = -2.71828^(-0.1*x)*((0.1*cos(deg(0.995*x-3.1415))+0.995*sin(deg(0.995*x-3.1415)));
},
}

\begin{document}
\begin{tikzpicture}[scale=1.9]
\begin{axis}[
axis lines = left,
xlabel = {$t \quad [\si{\second}]$},
grid=major,
ymin=-1,
ymax=1,
legend cell align=left,
legend style={font=\small},
domain=0:60,
samples=300,
]
\addlegendentry{$x(t) \quad [\si{\centi\meter}]$}
\addlegendentry{$\dot{x}(t) \quad [\si{\meter\per\second}]$}
\end{axis}
\end{tikzpicture}

\begin{tikzpicture}[scale=1.9]
\begin{axis}[
axis lines = left,
xlabel = {$x(t) \quad [\si{\centi\meter}]$},
ylabel = {$\dot{x}(t) \quad [\si{\centi\meter\per\second}]$},
grid=major,
ymin=-1,
ymax=1,
legend cell align=left,
legend style={font=\small},
domain=0:60,
samples=300,
x filter/.expression={abs(x)>1e-2 ? x : nan)},
clip=false,
]
\path[name path=yzeroline] (\pgfkeysvalueof{/pgfplots/xmin},0) -- (\pgfkeysvalueof{/pgfplots/xmax},0);
\path[name intersections={of=paramplot and yzeroline,total=\totalintersects}]
foreach \nb in {1,...,\totalintersects}{
node[circle,fill=red, inner sep=1pt] at (intersection-\nb){}
}
node[draw,fill=white,anchor=south west,outer sep=0pt] at (rel axis cs:0.01,0.01) {Number of intersections : \totalintersects}
;
\end{axis}
\end{tikzpicture}
\end{document}


• According to my understanding you need to count a different number of intersections: "how many times does the system cross the $x=0$" (and not $\dot x=0$). Also, I think it is better to remove the backslash from \foreach in \foreach \nb in {1,...,\totalintersects}.
– user194703
Apr 25, 2020 at 20:26
• It may be less direct than your approach, but basically I am filtering all values of the plot of x below 1e-2 so I think it should be quite equivalent. Otherwise, I agree on the \foreach part, while I am not sure what that changes. Can you tell ? Apr 25, 2020 at 20:31
• What I wanted to say is that you highlight the intersections with the horizontal axis, i.e. \dot x=0. But the OP is asking for the intersections with the axis x=0, which is the vertical axis in the plot. As for the x filter. I think this is a great idea for the plot you compute the intersections with, but maybe less so for the plot you show because this just cuts the plot off at these values. (Of course, the OP may want to cut the plot off, but I thought they only want to disregard the intersections below a threshold while still plotting the phase curve.)
– user194703
Apr 25, 2020 at 20:35
• @Schrödinger'scat Indeeeeed, I missed that one, I will correct this at once ! Thanks. Regarding the x filter, I figured as low amplitude values are of lesser interest to the OP, one could discard them. But I guess it's a matter of personal opinion, so it's good we proposed two different approaches. Apr 25, 2020 at 20:41