# How to draw the Mean Value Theorem graphic with TikZ?

(Edited 2014-03-23) Can anyone give a TikZ solution to my question?

I want to add an illustration of the Mean Value Theorem (Lagrange) like this:

\begin{center}
{\Huge \shadowbox{\textbf{Teorema del Valor Medio (Lagrange)}}}
\end{center}

$\frac{{f(b) - f(a)}}{{b - a}} = f'(c)$


Basically, I need the axis with the x and y labels, the function, the secant, the tangent and something that is missing in the picture: f(a), f(b) and f(c).

I made the picture that I want to make with TikZ with GeoGebra:

• Also did you search the site? tex.stackexchange.com/search?q=tangent+curve Especially tex.stackexchange.com/a/99086/3235 – percusse Mar 22 '14 at 18:39
• Any solutions with TikZ? – Daniel Benigni Mar 23 '14 at 23:34
• Without any try yourself at all, don't expect any. – Svend Tveskæg Mar 24 '14 at 1:19
• Of course I'm trying. But this site is for sharing knowledge and if someone has the answer before, what's wrong about asking? And supose I do not want to work, your answer will serve not only for me, it will be available for the entire world. – Daniel Benigni Mar 24 '14 at 1:33
• I think you have misunderstood me; I'm not trying to offend you. I' just saying that your should give it a try yourself; post whatever code you have got so far. (If the question has been answered before, you can find the answer by searching the page.) – Svend Tveskæg Mar 24 '14 at 1:39

My try with MetaPost, mostly for fun since there are already very fine solutions above. The main macro, find_all_direction_points, based on the directiontime MetaPost macro, theoretically returns every point whose tangents share the same direction, and the number of these points.

The following LaTeX code uses the gmp package as interface for Metapost and is to be typeset with the shell-escape option activated.

\documentclass[12pt]{scrartcl}
\usepackage[latex, shellescape]{gmp}
\gmpoptions{everymp={input latexmp;
setupLaTeXMP(options="12pt", textextlabel=enable, mode=rerun);}}
\begin{document}
\begin{mpost*}[mpmem=metafun]
% Macro that finds all points of p where the tangents share the same direction v
vardef find_all_direction_points(expr p, v)(suffix C, n) =
save s, q; path q; q = p;
n:= 0;
s = directiontime v of p;
forever:
exitunless s<>-1;
n := n+1;
C[n] := point s of q;
q := subpath(s+epsilon, infinity) of q;
s := directiontime v of q;
endfor;
enddef;
% Axes, graph, tangents and secant definitions
u := 2cm; xmin := -0.5; xmax := 6; ymin := -0.5; ymax := 4.5;
pair A, B, C; A = (1, 3); B = (5, 1);
pair C[], v;
v = unitvector(B-A);
path p, secant; p = A{dir 70} ..  B{dir 60}; secant = A--B;
find_all_direction_points(p, B-A)(C,n);
% Function graph, and secant
draw p scaled u ;
draw secant scaled u withcolor red;
% Tangent drawing
for k= 1 upto n:
draw (C[k]-v -- C[k] + v) scaled u withcolor green;
draw C[k] scaled u withpen pencircle scaled 3bp;
endfor;
% axes and locations
drawarrow (xmin*u, 0) -- (xmax*u, 0) ;
drawarrow (0, ymin*u) -- (0, ymax*u) ;
for M = A, B, C1:
draw (u*xpart M, 0) -- u*M -- (0, u*ypart M) dashed evenly;
endfor;
% Labels
label.bot("$a$", (u*xpart A, 0)); label.bot("$b$", (u*xpart B, 0));
label.bot("$c$", (u*xpart C1, 0)); label.bot("$x$", (xmax*u, 0));
label.lft("$f(a)$", (0, u*ypart A)); label.lft("$f(b)$", (0, u*ypart B));
label.lft("$f(c)$", (0, u*ypart C1)); label.lft("$y$", (0, ymax*u));
label.top("Tangent at $c$", C1*u) rotatedaround (C1*u, angle(B-A));
label.bot("Secant", u*0.4[A,B]) rotatedaround (u*0.4[A,B], angle(B-A));
label.bot("Another tangent", C2*u) rotatedaround (C2*u, angle(B-A));
tN := 0.45; pair N; N = point tN along p;
label.top("$y=f(x)$", u*N) rotatedaround(u*N, angle(direction tN of p));
\end{mpost*}
\end{document}


With a new method in which the abscissa c is automatically determined without having to evaluate derivative of f(x) by hand. Is it nice?

\documentclass[pstricks,border=12pt]{standalone}

\def\f(#1){((#1)*(#1-5)*(#1-6)/4+1.5*(#1)-5)}
\def\m(#1,#2){(\f(#2)-\f(#1))/(#2-#1)}
\def\fp(#1){Derive(1,\f(#1))}% f'(x)

\def\L#1{\uput[-90](#1|0,0){$#1\mathstrut$}\uput[180](0,0|#1){$f(#1)$}\psCoordinates[linestyle=dashed,linecolor=gray](#1)}

\begin{document}

\begin{pspicture}[algebraic,saveNodeCoors,PointSymbol=none,PointName=none](-1,-1)(8,8)
\psaxes[labels=none,ticks=none]{->}(0,0)(-.5,-.5)(7.5,7.5)[$x$,0][$y$,90]
\pstGeonode(*1 {\f(x)}){a}(*6.5 {\f(x)}){b}
\makeatletter\pst@Verb{/ax N-a.x def /bx N-b.x def}\makeatother
\psplot[linecolor=blue]{ax}{bx}{\f(x)}
\pstInterFF{\m(ax,bx)}{\fp(x)}{4}{temp}
\pstGeonode(*N-temp.x {\f(x)}){c}
\pcline[nodesep=-1,linecolor=green](a)(b)
\psxline[linecolor=red](c){.1(a)-.1(b)}{.1(b)-.1(a)}
\psset{linecolor=gray,linestyle=dashed}
\foreach \i in {a,b,c}{\L{\i}}
\end{pspicture}

\end{document}


• what???.. you put in the 5.3 by hand for the c location? you lower your standards compared to tex.stackexchange.com/questions/167238/… ;-) – user4686 Mar 23 '14 at 20:43
• ah! that was earlier! sorry you have increased your standards, great job ;-) – user4686 Mar 23 '14 at 20:48
• @jfbu: (-: and :-) – kiss my armpit Mar 24 '14 at 0:56

A PSTricks solution:

\documentclass{article}

\usepackage{xfp}

\newcommand*\Function[1]{\fpeval{(-3*(#1)^3+45*(#1)^2-189*(#1))/65+7}}
\newcommand*\ParallelPoint{\fpeval{5+sqrt(7)}}                         % need to calculate yourself
\newcommand*\ParallelTangent[1]{\fpeval{(-27*(#1)+395+42*sqrt(7))/65}} % need to calculate yourself
\begin{document}

\begin{pspicture}(-0.8,-0.4)(10.9,5.9)
{\psset{linestyle = dashed}
\psline[linecolor = blue](1,\Function{1})(0,\Function{1})
\psline[linecolor = blue](10,\Function{10})(0,\Function{10})
\psline[linecolor = orange](1,0)(1,\Function{1})
\psline[linecolor = orange](10,\Function{10})(10,0)
\psline[linecolor = green!60](10,\ParallelTangent{10})(10,\Function{10})
\psline[linecolor = green!60](\ParallelPoint,0)(\ParallelPoint,\Function{\ParallelPoint})(0,\Function{\ParallelPoint})}
\psline[linecolor = orange]{->}(1,\Function{1})(10,\Function{10})
\pcline[linestyle = none, offset = -9pt](1,\Function{1})(10,\Function{10})
\ncput[nrot = :U]{Secant}
\psline[linecolor = green!60]{->}(5,\ParallelTangent{5})(10,\ParallelTangent{10})
\psaxes[labels = none, ticks = none]{->}(0,0)(-0.2,-0.2)(10.5,5.5)[$x$,0][$y$,90]
\psplot[algebraic, linecolor = blue]{1}{10}{(-3*x^3+45*x^2-189*x)/65+7}
\psdots(1,\Function{1})(10,\Function{10})
\uput[270](3,\Function{3}){$y = f(x)$}
\uput[180](5,\ParallelTangent{5}){Tangent at $c$}
\uput[270](1,0){$a$}
\uput[150](0,\Function{1}){$f(a)$}
\uput[270](\ParallelPoint,0){$c$}
\uput[210](0,\Function{\ParallelPoint}){$f(c)$}
\uput[270](10,0){$b$}
\uput[180](0,\Function{10}){$f(b)$}
\end{pspicture}

\end{document}


• Nice output, but there is a lot of hardcoding in the input... Can it be reduced? – jub0bs Mar 22 '14 at 23:15
• @Jubobs See updated answer. Do you think it can be improved further? – Svend Tveskæg Mar 23 '14 at 0:01
• Difficult to say, since I don't know PStricks, but it looks much better :) – jub0bs Mar 23 '14 at 0:02

Here's a figure from my calculus lecture notes:

\documentclass[preview,margin=10pt]{standalone}
\usepackage{tikz}
\tikzset{point/.style={circle,draw=black,inner sep=0pt,minimum size=3pt}}
\usepackage{caption}
\usepackage{subcaption}
\begin{document}
\begin{figure}
\newcommand{\thescale}{0.5}
\centering
\subcaptionbox{one choice for $x_0$}{
\begin{tikzpicture}[scale=\thescale*1.2]
\draw[thick] (1,1) node[point,fill=black] (a) {} parabola bend (3,3) (4,2.5) node[point,fill=black] (b) {};
\draw[thick] (1,1) -- (4,2.5);
\draw (1,1+9/8) -- (4,2.5+9/8) coordinate (topright);
\node[point,fill=black] (x0) at (2.5,2.875) {};

\coordinate (origin) at (0,0);
\draw[<->] (topright -| origin) -- (origin) -- (origin -| topright) -- +(1,0);
\draw[dotted,very thick] (a) -- (a|-origin) node[below,black] {$a$};
\draw[dotted,very thick] (b) -- (b|-origin) node[below] {$b$};
\draw[dashed] (x0) -- (x0|-origin) node[below] {$x_0$};
\end{tikzpicture}
}
\subcaptionbox{two choices for $x_0$}{
\begin{tikzpicture}[scale=\thescale]
\begin{scope}
\clip (-3,-2) rectangle (3,2);
\draw[thick,smooth,domain=-3:3] plot (\x,{\x^3/3 - \x});
\end{scope}
\node[point,fill=black] (a) at (-2,-2/3) {};
\node[point,fill=black] (b) at (2,2/3) {};
\draw[thick] (a) -- (b);
\coordinate (origin) at (-4,-3);
\coordinate (topright) at (4,2);
\draw[<->] (topright -| origin) -- (origin) -- (origin -| topright);
\draw[dotted,very thick] (a) -- (a|-origin) node[below] {$a$};
\draw[dotted,very thick] (b) -- (b|-origin) node[below] {$b$};

\node[point,fill=black] (x0) at ({-2/sqrt(3)},{(1/3)*(-2/sqrt(3))^3+2/sqrt(3)}) {};
\draw (x0) +(-1,-1/3) -- +(1,1/3);
\node[point,fill=black] (x1) at ({2/sqrt(3)},{(1/3)*(2/sqrt(3))^3-2/sqrt(3)}) {};
\draw (x1) +(-1,-1/3) -- +(1,1/3);
\draw[dashed] (x0) -- (x0 |- origin) node[below]{$x_0$};
\draw[dashed] (x1) -- (x1 |- origin) node[below]{$x_1$};
\end{tikzpicture}
}
\subcaptionbox{\centering infinitely many choices for $x_0$}{
\begin{tikzpicture}[scale=\thescale/1.2]
\draw[thick,smooth] plot coordinates{(-2,-1) (-1.75,0) (-1,1) (0,2) (1,3) (2,4) (3,4.74) (4,5)} ++(1,0) coordinate (topright);
\coordinate (origin) at (-3,-2);
\draw[<->] (origin|-topright) -- (origin) -- (origin-|topright);
\node[point,fill=black] (a) at (-2,-1) {};
\node[point,fill=black] (b) at (4,5) {};

\draw[very thick, dotted] (a) -- (a|-origin) node[below] {$a$};
\draw[dotted,very thick] (b) -- (b|-origin) node[below] {$b$};

\draw[thin] (-2,0) -- (4,6);
\draw[ultra thick] (0,2) -- (1,3);

\draw[dashed] (0,2) -- (0,-2);
\draw[dashed] (0.5,2.5) -- (0.5,-2);
\draw[dashed] (1,3) -- (1,-2);
\end{tikzpicture}
}
\end{figure}
\end{document}


The result:

Is this a hack? It feels like a hack...

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}[thick]
\path ( 1,4)        node[coordinate] (a1) {}
(10,5)        node[coordinate] (b1) {}
(a1) ++(0,-2) node[coordinate] (a2) {}
(b1) ++(0,-2) node[coordinate] (b2) {};

\path[draw,green] (a1) -- (b1);

\path[draw,red] (a2) --
node[coordinate,pos=0.05] (c1) {}
node[coordinate,pos=0.2 ] (c2) {}
node[coordinate,pos=0.4 ] (c3) {}
(b2);

\draw[densely dashed] (a1)
.. controls +(0,0) and  (c1)   .. (c2)
.. controls  (c3)  and +(-2,2) .. (b1);

\foreach \point/\text in {a1/a , b1/b , c2/c}
\draw[dotted]
let \p1 = (\point)
in
(0  ,\y1) node[anchor=east ] {$f(\text)$}
-- (\p1)
-- (\x1,0  ) node[anchor=north] {$\text$};

\draw[->] (-1.5, 0  ) -- (11,0  ) node[anchor=south east] {\textsf{x}};
\draw[->] (   0,-1.5) -- ( 0,6.5) node[anchor=north west] {\textsf{y}};

\end{tikzpicture}
\end{document}


It works by making use of control points. From the manual:

One or two "control points" are needed. The math behind them is not quite trivial, but here is the basic idea: Suppose you are at point x and the first control point is y. Then the curve will start "going in the direction of y at x," that is, the tangent of the curve at x will point toward y. (Section 2.4, Emphasis added)

Output:

• It's not really a hack; TikZ has no convenient method for computing the tangent line to a path, so almost any TikZ solution involves constructing the path in such a way that you know its tangent at the point in question. I did this by using a formula for the curve and differentiating it by hand, which is less flexible than what you have here. – Charles Staats Mar 26 '14 at 21:28
• Incidentally, in the \foreach loop, you want c2/c rather than c1/c. – Charles Staats Mar 26 '14 at 21:29
• Well spotted. Fixed! – jja Mar 27 '14 at 0:40