I want to use the \draw command in conjunction with relative coordinates in order to plot a slope triangle underneath a tangent to a graph, but the following syntax does not yield the desired result:

\draw [color=red] (-1,4) -- ++(0,-1) -- ++(0.5,0);

Instead, the result I obtain is the following:

enter image description here

Here is the complete code:





[declare function={
f(\x) = \x^3 - 5*\x;
derf(\x) = 3*\x^2 - 5;
g(\x,\y) = derf(\y)*(\x-\y) + f(\y);
    axis x line=center,
    axis y line=center,
    xlabel style={below right},
    ylabel style={above left},
    \addplot [domain=-3:3,smooth,thick, color=black, name path=p1] {f(x)} node[above right, xshift=-9mm] {$y=f(x)$};
    \addplot [only marks,mark=*] coordinates { (\z1,{f(\z1)}) };
    \addplot [domain=-3.1:-2.1, color=black] { g(x,\z1) };
    \draw [dashed] (\z1,0) -- (\z1,{f(\z1)});
    \draw (\z1,2pt) -- (\z1,-2pt) node[above] {$x_1$};
    \addplot [only marks,mark=*] coordinates { (\z2,{f(\z2)}) };
    \addplot [domain=-2.3:0.3, color=black] { g(x,\z2) };
    \draw [dashed] (\z2,0) -- (\z2,{f(\z2)});
    \draw (\z2,2pt) -- (\z2,-2pt) node[below] {$x_2$};
    \draw [color=red] (-1,4) -- ++(0,-1) -- ++(0.5,0);
    \addplot [only marks,mark=*] coordinates { (\z3,{f(\z3)}) };
    \addplot [domain=0.8:2.8, color=black] { g(x,\z3) };
    \draw [dashed] (\z3,0) -- (\z3,{f(\z3)});
    \draw (\z3,2pt) -- (\z3,-2pt) node[above] {$x_3$};


I am quite new to Tikz and Pgfplots and perhaps I just made a silly mistake. In any case, I would be really grateful if someone would help me fix this.

Apart from this I would also really appreciate any suggestions or advice to improve the code, simplify it and clean it up where possible. For example, I was wondering if the three blocks of code to plot the tangent lines could be replaced by just one block, using a common variable taking three different values instead of defining the three variables \z1, \z2, \z3separately.

Many thanks in advance!

  • Would you be interested by a simple pstricks solution?
    – Bernard
    Aug 19 at 14:50
  • 1
    Welcome to TeX.SX! Please make your code compilable (if possible), or at least complete it with \documentclass{...}, the required \usepackage's, \begin{document}, and \end{document}. That may seem tedious to you, but think of the extra work it represents for TeX.SX users willing to give you a hand. Help them help you: remove that one hurdle between you and a solution to your problem. Aug 19 at 15:17
  • this answer and other answers in that post may be helpful tex.stackexchange.com/a/514500/140722 tex.stackexchange.com/questions/219747/…
    – Black Mild
    Aug 19 at 15:33
  • also this one tex.stackexchange.com/questions/461573/…
    – Black Mild
    Aug 19 at 15:38
  • @Bernard Yes, absolutely. But being a beginner, I don't know what you mean by pstricks. Is it a package?
    – Apollo13
    Aug 19 at 20:05

Your code does not compile, so I offer only a one line solution instead of compilable code:

\draw [red] (-1,4) -- ++(axis direction cs:0,-1) -- ++(axis direction cs:0.5,0);  %ok now




    declare function={
    f(\x) = \x^3 - 5*\x;
    derf(\x) = 3*\x^2 - 5;
    g(\x,\xzero) = derf(\xzero)*(\x-\xzero) + f(\xzero);
    axis x line=center, axis y line=center,
    xtick=\empty, ytick=\empty,
    xlabel={$x$}, ylabel={$y$},
    xlabel style={below right}, ylabel style={above left},
    xmin=-3.5, xmax=3.5,
    ymin=-15, ymax=15,
    xtick={x1, x2, x3}, xticklabel=\empty
    \draw[dashed] (x1,0) node[above] {\footnotesize $x_1$} -- (x1,{f(x1)});
    \addplot[domain=-3.1:-2.1] { g(x,x1) };
    \draw plot[mark=*, mark size=1.5pt] coordinates { (x1,{f(x1)}) };

    \draw[dashed] (x2,0) node[below] {\footnotesize $x_2$} -- (x2,{f(x2)});
    \draw [red] (x2,{f(x2)}) -- ++(axis direction cs:0,-1) -- ++(axis direction cs:{-1/derf(x2)},0);
    \addplot[domain=-1.8:-0.2] { g(x,x2) };
    \draw plot[mark=*, mark size=1.5pt] coordinates { (x2,{f(x2)}) };
    \draw[dashed] (x3,0) node[above] {\footnotesize $x_3$} -- (x3,{f(x3)});
    \addplot[domain=1.2:2.3] { g(x,x3) };
    \draw plot[mark=*, mark size=1.5pt] coordinates { (x3,{f(x3)}) };
    \addplot [domain=-3:3,smooth,thick] {f(x)} node[above] {\footnotesize $y=f(x)$};



  • Thank you very much! Do you have any idea why my code did not work? I have edited my post to include the preamble.
    – Apollo13
    Aug 19 at 20:02
  • P.S. If you have any suggestions with regards to the second part of my question, I would be very grateful!
    – Apollo13
    Aug 19 at 20:03
  • Always keep your code minimal and relevant to your problem. You should especially not include any packages in the preamble that is not needed. I wrote my answer before your edit. Right now, your code is not compiling for me because of \tikzexternalize. Externalisation is not relevant for your problem! Aug 19 at 21:04
  • I will look at your code a little later Aug 19 at 21:04
  • Thank you! If you find the time, I would much appreciate that! P.S. If I delete \tikzexternalize from the preamble, I still get the same problem... By the way, I'm using overleaf.
    – Apollo13
    Aug 20 at 5:40

For fun, a code with pstricks, which defines a \psplotTangentcommand:

\documentclass[svgnames, border=6pt]{standalone}


\psset{linejoin=1, arrowinset=0.12, yunit=0.25cm, labelsep=3pt}
\psaxes[ticks=none, labels=none]{->}(0,0)(-3.5,-15)(3.5,15)[$x$,-110][$y$,-135]%
\psplot[linewidth=1.2pt, linecolor=RoyalBlue, plotpoints=500, plotstyle=curve, algebraic]{-3.5}{3.5}{x^3-5*x}
\foreach \x in {-2.6,-1,1.8}{\psplotTangent[algebraic, linewidth=0.6pt]{\x}{2}{x^3-5*x}}
\foreach \x/\y in {-2.6/-4.58,-1/4,1.8/-3.17}{\psset{linestyle=dashed, dash=3pt 2pt, linewidth=0.4pt} \psline{*-}(\x, \y)(\x, 0)}
\uput[u](-2.6, 0){\footnotesize$-2.6$}\uput[d](-1, 0){\footnotesize$-1$}%
\uput[u](1.8, 0){\footnotesize$1.8$}


enter image description here

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.