11

I would like to draw curves that are smooth and have linear segments. These curves are to be used in the graph of one-dimensional functions, x(t). [To be used as position vs time graphs in writing homework problems for introductory physics.] Example:

enter image description here

I would like to draw these plots by specifying that the curve go through particular points with particular tangents. This question very nicely implements exactly what I've described so far Implementing a syntax: Smooth curves with specified points and tangents.

However, my goal is to use these curves in plots of one-dimensional functions x(t) and would really, really like to be able to generate from them curves of the derivative x'(t). Is this feasible within tikz?

(I made the example graph above with pgfplots. The function is a piecewise function I constructed in Mathematica. This approach would certainly work for me, but the process is a bit of a pain. I plan on making sufficiently many problems using graphs similar to this that I would really like something more efficient. The code is below.)

Code

\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{tikzpicture}
\begin{axis}[axis lines = middle,minor tick num = 1, grid = both, xlabel = {$t$\,(\si{s})}, ylabel = {$x$\,(\si{m})}, no markers, smooth,xmin=0, xmax=14, ymin=-6, ymax=6, samples = 100, thick, unit vector ratio = 1]
\addplot +[very thick, domain=0:14] {MyF(x)};
\end{axis}
\end{tikzpicture}

Update Both of the answers below draw the derivative by constructing an explicit mathematical function for original curve, then taking its derivative numerically.

I would really like to avoid constructing an explicit mathematical expression for the original curve because, for graphs like the one above, I find the expressions unwieldy and unnatural to generate. I would much rather generate the original curve via the method outlined in Implementing a syntax: Smooth curves with specified points and tangents or something similar.

My question is: without an explicit mathematical expression for the curve, is it feasible within LaTeX (probably via tikz) to draw the derivative.

For example, given a path

\draw (0,0) .. controls (1,1) and (1,1) .. (2,0);

could you draw its derivative? (Restricting our attention to paths y(x) that are single-valued functions of x).

  • Maybe this question will give some inspiration: tex.stackexchange.com/questions/37866/… – Herr K. Jul 26 '14 at 5:49
  • Do you want a derivative symbolically computed? Numerically computed? – Paul Gaborit Jul 26 '14 at 6:14
  • Can you include the code for this piecewise function? – percusse Jul 26 '14 at 7:30
  • @PaulGaborit I don't care, as long as I can generate a reasonable approximation to curve ( t,x'(t) ) – Chris Chudzicki Jul 26 '14 at 13:12
  • @percusse added – Chris Chudzicki Jul 26 '14 at 13:14
10

The easy way out is to fake the derivative;

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.10}
\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))  %
  }%
}
\pgfmathdeclarefunction{MyFd}{2}{% 
  \pgfmathparse{(MyF(x+#2)-MyF(x))/#2}%
}


\begin{tikzpicture}
\begin{axis}[axis lines = middle,minor tick num = 1, grid = both, xlabel = {$t$\,(\si{s})}, ylabel = {$x$\,(\si{m})}, no markers, smooth,xmin=0, xmax=14, ymin=-6, ymax=6, samples = 100, thick, unit vector ratio = 1]
\addplot +[very thick, domain=0:14] {MyF(x)};
\addplot +[very thick, domain=0:14] {MyFd(x,14/100)};
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

A decoration for TikZ paths. It's relatively accurate but of course, it is depending on sane inputs for the function with not so steep bends.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations,fpu}
\pgfdeclaredecoration{approxderiv}{initial}{%
\state{initial}[width=0.01mm,
                persistent postcomputation={%
                    \def\tempa{0}%
                    \pgfmathsetmacro{\plen}{(\pgfdecoratedpathlength-0.01mm)/500}%
                    \def\myderivlist{}%
                },next state=walkthecurve]{}%do nothing
\state{walkthecurve}[width=\plen pt,
               persistent postcomputation={%
                  \pgfmathparse{(sin(\pgfdecoratedangle))}\xdef\tempb{\pgfmathresult}%
                  \pgfmathparse{abs(cos(\pgfdecoratedangle))*\plen}%
                  \expandafter\xdef\expandafter\myderivlist\expandafter{%
                     \myderivlist --++ ({\pgfmathresult pt},{(\tempb-\tempa)*(1cm)})%It was cm initially afterall
                    }%
                  \xdef\tempa{\tempb}%
               }
            ]{}%do nothing
}
\begin{document}
\begin{tikzpicture}
\draw[style=help lines] (0,-3.5) grid[step=5mm] (6,3.5);
\draw[decoration=approxderiv,postaction=decorate] 
(0,0) .. controls (1,1) and (1,1) .. (2,0) arc (-90:-20:1 and 3) arc (160:120:1.5 and 1) 
-- ++(-70:6) node[pos=0.2,align=center] {slope\\\pgfmathparse{sin(-70)}\pgfmathresult};
\draw[red] (0,0) \myderivlist;
\end{tikzpicture}
\end{document}

enter image description here

  • I've edited the question to hopefully be clearer. I would really like to draw the curve with draw commands which, for such piecewise functions, feel much more natural (and I find much easier). – Chris Chudzicki Jul 26 '14 at 13:50
  • @mrc Can you please put in the syntax you want to use? If you want to use control points then use that one to draw the curve. But then, you don't need pgfplots for this. What would be the scale? What is the initial condition etc. You would need to provide a lot of stuff if you use a line object for a function – percusse Jul 26 '14 at 13:52
6
\documentclass[pstricks,border=15pt,12pt,dvipsnames]{standalone}
\usepackage{pstricks-add}

\psset
{
    algebraic,
    linejoin=2,
    plotpoints=1000,
    xAxisLabel=$t$,
    yAxisLabel=$s(t)$,
    urx=15pt,
    ury=15pt,
    llx=-5pt,
    lly=-5pt,
}

\def\f{IfTE(x<0,-x^2,IfTE(x<2,x,IfTE(x<3,2*x+1,x^2/2)))}

\begin{document}
\pslegend[lt]{%
    \color{NavyBlue}\rule{20pt}{2pt} & \color{NavyBlue} $s(t)$\\
    \color{Red}\rule{20pt}{2pt} & \color{Red} $v(t)$
}
\begin{psgraph}{<->}(0,0)(-3,-4)(5,9){12cm}{!}
    \psset{linewidth=2pt}
    \psplot[linecolor=NavyBlue]{-2}{4}{\f}
    \psplot[linecolor=Red]{-2}{4}{Derive(1,\f)}
\end{psgraph}
\end{document}

enter image description here

Note

Keep in mind that the vertical lines must not be regarded as the part of the graph.

  • 2
    +1, although the function "s(t)" you drew is physically impossible. – Henri Menke Jul 26 '14 at 11:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.