13

I want to plot graphs like this and embed them as Tikz or Pstricks code in my handouts. I know that there are software such as Ipe, LaTeXDraw etc. But none of them can satisfy me. Because Ipe doesn't give me code and LaTeXDraw doesn't give smooth curves. What is the easiest way to plot graphs like this?
Please keep in mind that the smoothness of the curve is very important to me. enter image description here

4
  • 3
    Do you know (or can you fake) a formula for the curve?
    – Joseph Wright
    Commented Feb 20, 2013 at 13:28
  • @JosephWright No, the curve doesn't have any formula. In fact, this is the geometric representation of the Rolle's Theorem in mathematics. Commented Feb 20, 2013 at 13:33
  • 1
    In fact, this kind of curve is most easily drawn using Metapost. If nobody comes up with an answer, I'll try, but no sooner than Friday (I'm very busy today and won't have internet access tomorrow).
    – mbork
    Commented Feb 20, 2013 at 16:37
  • 1
    I suggest you include in your picture an inflection point with null derivative, to remark that horizontal tangents does not necessarily correspond to relative extrema. Commented Mar 17, 2014 at 9:23

4 Answers 4

18

I don’t know how exact the curve should be but if the shapt isn’t that important you could use the bend or the in and out options to draw.

The first thing is to set up a TikZ environment and draw the axes. Use \draw to draw a line, ad the tip with -> and the label with a node.

\documentclass{article}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
    % Axes
    \draw [->] (-1,0) -- (11,0) node [right] {$x$};
    \draw [->] (0,-1) -- (0,6) node [above] {$y$};
    % Origin
    \node at (0,0) [below left] {$0$};
\end{tikzpicture}
\end{document}

axes

The next thing could be the start, end and extreme points using coordinates

    % Points
    \coordinate (start) at (1,-0.8);
    \coordinate (c1) at (4,3);
    \coordinate (c2) at (6,2);
    \coordinate (c3) at (8,4);
    \coordinate (end) at (10.5,-0.8);
    % show the points
    \foreach \n in {start,c1,c2,c3,end} \fill [blue] (\n) circle (1pt) node [below] {\n};

points

Then join the single points with \draw and the to construction, where you can give the in and out angles to reach a point.

    % join the coordinates
    \draw [thick] (start) to[out=70,in=180] (c1) to[out=0,in=180]
        (c2) to[out=0,in=180] (c3) to[out=0,in=150] (end);

curve

Now add the dashed lines and the tangents using a \foreach loop through c1, c2 and c3. The letoperation allows to use components of a coordinate, but need the calc library (add \usetikzlibrary{calc} to the preamble).

    % add tangets and dashed lines
    \foreach \c in {c1,c2,c3} {
        \draw [dashed] let \p1=(\c) in (\c) -- (\x1,0);
        \draw ($(\c)-(0.75,0)$) -- ($(\c)+(0.75,0)$);
    }

tangets

An as the last thing add the labels using nodes again.

    \foreach \c in {1,2,3} {
        \draw [dashed] let \p1=(c\c) in (c\c) -- (\x1,0) node [below] {$c_\c$};
        \draw ($(c\c)-(0.75,0)$) -- ($(c\c)+(0.75,0)$) node [midway,above=4mm] {$f'(c_\c)=0$};
    }

To get a and b use the intersections library and name the x axis and the curve with name path. Then use the intersection to add the nodes as shown in the following full example.

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc,intersections}

\begin{document}
\begin{tikzpicture}
    % Axes
    \draw [->, name path=x] (-1,0) -- (11,0) node [right] {$x$};
    \draw [->] (0,-1) -- (0,6) node [above] {$y$};
    % Origin
    \node at (0,0) [below left] {$0$};
    % Points
    \coordinate (start) at (1,-0.8);
    \coordinate (c1) at (3,3);
    \coordinate (c2) at (5.5,1.5);
    \coordinate (c3) at (8,4);
    \coordinate (end) at (10.5,-0.8);
    % show the points
%   \foreach \n in {start,c1,c2,c3,end} \fill [blue] (\n)
%       circle (1pt) node [below] {\n};
    % join the coordinates
    \draw [thick,name path=curve] (start) to[out=70,in=180] (c1) to[out=0,in=180]
        (c2) to[out=0,in=180] (c3) to[out=0,in=150] (end);
    % add tangets and dashed lines
    \foreach \c in {1,2,3} {
        \draw [dashed] let \p1=(c\c) in (c\c) -- (\x1,0) node [below] {$c_\c$};
        \draw ($(c\c)-(0.75,0)$) -- ($(c\c)+(0.75,0)$) node [midway,above=4mm] {$f'(c_\c)=0$};
    }
    % add a and b
    \path [name intersections={of={x and curve}, by={a,b}}] (a) node [below left] {$a$}
        (b) node [above right] {$b$};
\end{tikzpicture}
\end{document}

full image

The shape of the curve may be improved by using the controls construction instead of to, e.g.

\draw [thick,name path=curve] (start) 
    .. controls +(70:1) and +(180:0.75) .. (c1)
    .. controls +(0:0.75) and +(180:1) .. (c2)
    .. controls +(0:1) and +(180:1) .. (c3)
    .. controls +(0:1) and +(150:1) .. (end);

improved curve

Have a look at the TikZ manual for mor information ;-) …


It is also possible to use the plot operation as Harish Kumar shows but in this cas you can’t be sure that f'(c_n) = 0 and it needs mor manual calculations etc. to get the right points …

\draw [thick, name path=curve] plot[smooth, tension=.7]
    coordinates{(start) (c1) (c2) (c3) (end)};

plot operation

2
  • 1
    Nice answer so far. I want to add that you could take a look at pgfplots. It is based on TikZ but offers many possibilities to plot great graphs.
    – partial81
    Commented Feb 20, 2013 at 14:12
  • 1
    I know pgfplots but I don’t know the function of the curve to plot ;-)
    – Tobi
    Commented Feb 20, 2013 at 14:14
14
\documentclass{article}
\usepackage{tikz}
\begin{document}
  \begin{tikzpicture}
     \draw [->] (-1,0) -- (11,0) node [right] {$x$};
     \draw [->] (0,-1) -- (0,6) node [above] {$y$};
     \node at (0,0) [below left] {$0$};
     \draw  plot[smooth, tension=.7] coordinates{(1.5,-0.5) (3,3) (5,1.5)  (7.5,4) (10,-1)};
     \node at (1.75,-0.25) {$a$};
     \node at (9.5,-0.25) {$b$};
     \draw[dashed] (3.2,3.05) -- (3.2,0);
     \draw[dashed] (4.9,1.5) -- (4.9,0);
     \draw[dashed] (7.3,4.05) -- (7.3,0);
     \node at (3.2,-0.25) {$c_{1}$};
     \node at (4.9,-0.25) {$c_{2}$};
     \node at (7.3,-0.25) {$c_{3}$};
     \draw (2.5,3.05) -- (4,3.05);
     \draw (4,1.5) -- (6,1.5);
     \draw (6.5,4.05) -- (8.25,4.05);
     \node at (3.2,3.5) {$f'(c_{1})=0$};
     \node at (4.9,2.2) {$f'(c_{2})=0$};
     \node at (7.3,4.5) {$f'(c_{3})=0$};
     \node at (9.5,2.5) {$y=f(x)$};
\end{tikzpicture}
\end{document}

enter image description here

4
  • But the plot operation can’t ensure a horizontal tangent, can it? (See the last part of my answer, please)
    – Tobi
    Commented Feb 20, 2013 at 14:28
  • @Tobi: Here nothing is automatic as it is just a picture. All values of c1, c2 and c3 are manually added.
    – user11232
    Commented Feb 20, 2013 at 14:30
  • @HarishKumar Thank you so much for the great line \draw plot[smooth, tension=.7] coordinates{(1.5,-0.5) (3,3) (5,1.5) (7.5,4) (10,-1)}; Commented Feb 20, 2013 at 14:42
  • @VahidDamanafshan: You have to be careful with the smooth option, though, as it usually overshoots the specified y coordinate (it does in this code, for example)
    – Jake
    Commented Feb 20, 2013 at 14:52
7

Here my method. I drew a lot of graphs like this for my students when I was a math's teacher.

First I used a fine tool like Maple or Maxima to get a fine function and to solve special equations. I think it's easier to know the equation to add some objects.

For example here I used f(x) =-x^4+10x^3-35x^2+50.5x-23.5. Then I used my personal tool tkz-fct.

Advantage it was my tool and I don't have to lose time to re-create code. Disadvantage the syntax is not TikZ'syntax and sometimes I need to add some tikz's code.

With the equation you can use the powerful tool : pgfplot

\documentclass[]{scrartcl}
\usepackage{tkz-fct}
\thispagestyle{empty}        

\begin{document} 

   \begin{tikzpicture} [xscale=2]
     \tkzInit[xmin = 0, xmax = 5,ymin = -1, ymax = 5]
     \tkzDrawXY[noticks] 
     \tkzFct[domain = 0:5]{(-1)*x**4+10*x**3-35*x**2+50.5*x-23.5}   
     \tkzfctset{tan style/.style={-,>=latex,blue}}  
        \foreach \x/\n in {1.43579/c1,2.3992/c2,3.6650/c3} {%
                    \tkzDrawTangentLine[kr=.5,kl=.5](\x) 
                    \draw[dashed] (tkzPointResult)-|(\x,0) node[below right]{$\n$};
                    \node[above=8pt] at (tkzPointResult){$f'(\n)=0$};
                    \tkzDrawPoint(tkzPointResult)}  
      \foreach \x/\n in {0.8746/a,4.2769/b} {%
                       \tkzDefPointByFct[draw](\x)
                       \node[below right] at (tkzPointResult){$\n$};}   
      \end{tikzpicture}

\end{document}   

enter image description here

2
  • In my opinion, the function should be a polynomial of order 5 because the most right part seems to be concave upward (see the questioner's graph). Commented Feb 21, 2013 at 9:31
  • 1
    Yes you are right but it's not really important here and it's easy to change Commented Feb 21, 2013 at 9:39
7

It needs the newest pst-eucl.sty which is version 1.49.

enter image description here

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add,pst-eucl}

\def\f(#1){((#1-1)*(#1-2)*(#1-4)*(#1-7)*(#1-9)/80+2)}
\def\fp(#1){Derive(1,\f(x))}% first derivative


\begin{document}
\begin{pspicture}[algebraic,saveNodeCoors,PointNameSep=7pt,PointSymbol=none,PosAngle=-90,CodeFig=true](-0.75,-0.75)(9,4.5)
% Determine the x-intercepts
\pstInterFF[PosAngle=-45]{\f(x)}{0}{0}{a}
\pstInterFF[PosAngle=-135]{\f(x)}{0}{8}{b}
% Determine the abscissca of critical points
\pstInterFF{\fp(x)}{0}{1.5}{c_1}
\pstInterFF{\fp(x)}{0}{3}{c_2}
\pstInterFF{\fp(x)}{0}{5.5}{c_3}
% Determine the turning points
\pstGeonode
[
    PointName={f'(c_1)=0,f'(c_2)=0,f'(c_3)=0},
    PosAngle=90,
    PointNameSep={7pt,16pt,7pt},
]
    (*N-c_1.x {\f(x)}){C_1}
    (*N-c_2.x {\f(x)}){C_2}
    (*N-c_3.x {\f(x)}){C_3}
% Draw auxiliary dashed lines
\bgroup
    \psset{linestyle=dashed,linecolor=gray}
    \psline(c_1)(C_1)
    \psline(c_2)(C_2)
    \psline(c_3)(C_3)
\egroup
% Draw the tangent line at the turning points
\psline([nodesep=-0.5]C_1)([nodesep=0.5]C_1)
\psline([nodesep=-0.5]C_2)([nodesep=0.5]C_2)
\psline([nodesep=-0.5]C_3)([nodesep=0.5]C_3)
% Plot the function
\psplot[plotpoints=100]{0.4}{8.2}{\f(x)}
% Attach the function label
\rput(*7.5 {\f(x)}){$y=f(x)$}
% Draw the coordinate axes
\psaxes[labels=none,ticks=none]{->}(0,0)(-0.5,-0.5)(8.5,4)[$x$,0][$y$,90]
\end{pspicture}
\end{document}
6
  • 2
    Sorry, but this is ridiculous. You could post this as answer answer to any question! Tobi's first revision does at least have some specifics already. Commented Feb 20, 2013 at 13:53
  • @Hendrik Vogt, Please, take it easy, it's a work in progress...
    – La Raison
    Commented Feb 20, 2013 at 14:30
  • @HendrikVogt: See meta.tex.stackexchange.com/q/1860/4918 ;-)
    – Tobi
    Commented Feb 20, 2013 at 14:35
  • 2
    @LaRaison: Hendrik posted his comment when the answer consisted only of the sentence "Please wait, building in progress..."
    – Jake
    Commented Feb 20, 2013 at 14:37
  • @Tobi: Thanks for the link! I see that you followed very closely the suggestions of the accepted answer :-) Commented Feb 20, 2013 at 15:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .