# Automate derivative representation in TikZ

I am to begin to write some lecture notes for my students and I will have to do multiple diagrams like the one shown below to represent the simple notion of derivatives graphically. The problem I face is to find a way to automate the creation of such figures. For example, what am looking for is:

1. Define a function f(x) (in TikZ of course)
2. Declare the x-coordinates of two points, say x1 and x2. Now these two coordinates can be used to calculate their corresponding y coordinates and the distances shown in the triangle.

Thus am looking for something like, \derivative{x*x}{x1}{x2}. I don't know how the domain can be incorporated but I guess that can be done later.

\documentclass[letterpaper]{article}
\usepackage{fullpage}
\usepackage{amsmath,amssymb,enumitem}
\usepackage[dvipsnames]{xcolor}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows}

\pdfpageheight\paperheight
\pdfpagewidth\paperwidth
\parindent0pt

\begin{document}
\begin{tikzpicture}[line cap=round,line join=round,>=stealth',x=1.0cm,y=1.0cm,domain=-0.5:2.25]
\draw[->,color=black] (-1,0) -- (4,0);
\foreach \x in {1,2,3}
\draw[shift={(\x,0)},color=black] (0pt,2pt) -- (0pt,-2pt) node[below] {\footnotesize $\x$};
\draw[color=black] (4,0) node [right] { $x$};
\draw[->,color=black] (0,-1) -- (0,5);
\foreach \y in {1,2,3,4}
\draw[shift={(0,\y)},color=black] (2pt,0pt) -- (-2pt,0pt) node[left] {\footnotesize $\y$};
\draw[color=black] (0,5) node [above] { $y$};
\draw[color=red,<->] plot[id=quad] function{x*x} node[right] {$f(x) =x^2$};
\fill[black] (0.5,0.25) circle (1.25pt);
\fill[black] (1.5,2.25) circle (1.25pt);
\draw (0.5,0.25)--(1.5,2.25)--(1.5,0.25)--cycle;
\draw[|-|,yshift=-0.25cm] (0.5,0.25)--(1.5,0.25);
\draw[yshift=-0.25cm](1,0.25) node[fill=white] {1};
\draw[|-|,xshift=0.25cm] (1.5,0.25)--(1.5,2.25);
\draw[xshift=0.25cm] (1.5,1.25) node [fill=white] {2};
\end{tikzpicture}
\end{document}


Image of the result:

-

You can use pgfplots for this. I've written a new macro \derivative{<pgfmath function>}{<label>}{<x1>}{<x2>}{<point legend>} that can be used inside a pgfplots axis. It draws a plot of the function, which is specified using pgfmath syntax as a function of \x, and a straight line connecting the function points at two specified x values. It also adds a label to the plot, which is specified using the second argument, and a legend listing the two points, which has to be supplied in the fifth argument. You can influence the legend position and appearance using point legend/.style={<options>} in the axis options, and the position and appearance of the point labels using point 1/.style and point 2/.style.

For example

\begin{axis}[
azetinaplot,
domain=-0.5:2.5, samples=100,
xmin=-1, xmax=3,
point legend/.style={ at={(rel axis cs:1.1,0.5)}},
point 1/.style={anchor=south east}, point 2/.style={anchor=south east}
]
\derivative{\x^2}{$f(x)=x^2$}{1}{2}{$P_1=(1\,,\,1)$\\$P_2=(2\,,\,4)$}
\end{axis}


would yield

The azetinaplot style is defined here as

\pgfplotsset{
azetinaplot/.style={
width=7cm,
height=7cm,
axis lines=middle,
xlabel=$x$,
ylabel=$y$,
enlarge y limits,
clip=false
}
}


Another example:

\begin{axis}[
azetinaplot,
domain=-20:370, samples=100,
xmin=-20, xmax=370,
point 1/.append style={anchor=south east},
point 2/.append style={anchor=east}]
\derivative{sin(\x)}
{$f(x)=\sin(x)$}
{290}{340}
{$P_1=(290\,,\,-0.94)$\\$P_2=(340\,,\,-0.34)$}
\end{axis}


would yield

Here's the complete code:

\documentclass{article}
\usepackage{pgfplots}
\usetikzlibrary{matrix}

\begin{document}

\pgfplotsset{point legend/.style={},
point 1/.style={anchor=south},
point 2/.style={anchor=south}
}
\newcommand{\derivative}[5]{
\begin{scope}[declare function={f(\x)=#1;}]
\addplot [thick, red, latex-latex] {f(x)} node [anchor=west] {#2};
\addplot [black, mark=*] coordinates {(#3,{f(#3)}) (#4,{f(#4)})}
node [pos=0,/pgfplots/point 1] {$P_1$}
node [pos=1,/pgfplots/point 2] {$P_2$};
\pgfplotsextra{
\pgfmathsetmacro\first{f(#3)}
\pgfmathsetmacro\second{(f(#4)}
\pgfmathsetmacro\xdiff{#4-#3}
\pgfmathsetmacro\ydiff{f(#4)-f(#3)}
\draw (axis cs:#3,\first) -| (axis cs:#4,\second);
\draw [|-|,yshift=-2ex] (axis cs:#3,\first) -- node [inner sep=1pt,fill=white] {\pgfmathprintnumber{\xdiff}} (axis cs:#4,\first);
\draw [|-|,xshift=2ex] (axis cs:#4,\first) -- node [inner sep=1pt, fill=white] {\pgfmathprintnumber{\ydiff}} (axis cs:#4,\second);
\matrix at (rel axis cs:1,1) [matrix of nodes,/pgfplots/point legend] {#5\\};
}
\end{scope}
}

\pgfplotsset{
azetinaplot/.style={
width=7cm,
height=7cm,
axis lines=middle,
xlabel=$x$,
ylabel=$y$,
enlarge y limits,
clip=false
}
}

\begin{tikzpicture}
\begin{axis}[
azetinaplot,
domain=-20:370, samples=100,
xmin=-20, xmax=370,
point 1/.append style={anchor=south east},
point 2/.append style={anchor=east}]
\derivative{sin(\x)}
{$f(x)=\sin(x)$}
{290}{340}
{$P_1=(290\,,\,-0.94)$\\$P_2=(340\,,\,-0.34)$}
\end{axis}
\end{tikzpicture}
\end{document}

-
Can you declare a label for the x and y coordinates of the two points used, say P_1 and P_2 or the like and create some form of a legend on a corner (right maybe) specifying the coordinates of these two points? –  azetina May 12 '12 at 22:46
@azetina: Do you want to specify the labels "statically", so do you want to write P_2=(2,4), or do you want the y-coordinate to be calculated automatically? –  Jake May 12 '12 at 22:56
The first option P_2=(2,4). Though this would be as a legend and only P_2 would appear beside the specific point. This of course is just aesthetics for the displayed figure. –  azetina May 12 '12 at 23:13
Could you elaborate on this part: at={(rel axis cs:1.1,0.5)} and how to interpret it as this I suppose controls the position of the legend, right? –  azetina May 12 '12 at 23:18
@azetina: I've edited my answer, the points will now be labeled and the legend text is supplied using an additional argument. (rel axis cs:<x>,<y>) is the relative axis coordinate system: (rel axis cs:0,0) is the bottom left corner of the plot area, (rel axis cs:1,1) is the top right. The value I used, (rel axis cs:1.1,0.5) is in the vertical centre of the plot, slightly outside the right border of the plot area. –  Jake May 13 '12 at 7:48

Only for information because you don't use tkz-fct. it was my first package and now I think it's preferable to use he excellent package pgfplots.

I created a new macro \derivative. This macro is not complete because it's only to information but it's possible to add labels etc. The calculation are obtained with fp : the tangent, the slope, the coordinates for the point on the curve.

\documentclass{article}
\usepackage{tkz-euclide}
\usetkzobj{all}
\usepackage{tkz-fct}
\usetikzlibrary{calc}

\begin{document}
\tkzfctset{tan style/.style={-,>=latex,blue}}

\def\alpha{3}

\newcommand\derivative[4]{%
\tkzDefPointByFct[draw](#1) \tkzGetPoint{start}
\tkzDefPointByFct[draw](#2) \tkzGetPoint{end}
\draw[thin,|-|,yshift=-3pt] (start) -- node[black,fill=white,below] {#3}(start-|end);
\draw[thin,|-|,xshift=3pt] (start-|end) -- node[black,fill=white,right] {#4}(end);
\draw[thin] (start) --(end);
}

\begin{tikzpicture}[scale=2]
\tkzInit[xmin=-1,xmax=4.5,ymax=3]
\tkzClip[space=1]
\tkzAxeXY
\tkzFct[domain=.1:5,samples=200,id=ln,line width=0.5pt,color=red]{log(x)+1}
\tkzDrawTangentLine[kl=1,kr=5](1)
\derivative{1}{4}{$\Delta x$}{$\Delta y$}
\tkzText[draw=red,fill = red!20](4,2.75){$f(x)=\ln(x)+1$}
\tkzText[blue,draw,fill = blue!20](2.8,3.5){$g(x)=x$}
\end{tikzpicture}

\end{document}


It's possible to make an animated sequence to show how to build the tangent line but you can see the pdf only with adobe reader.

First you need to create a file tgt.tex (it's possible to use beamer). A good idea now it's to use the new macro \derivative

\documentclass{article}
\usepackage{tkz-euclide}
\usetkzobj{all}
\usepackage{tkz-fct}
\usetikzlibrary{calc}

\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{5pt}%

\begin{document}

\tkzfctset{tan style/.style={-,>=latex,blue}}

\foreach \alpha in {4,3.8,...,1}{
\begin{tikzpicture}[scale=2]
\tkzInit[xmin=-2,xmax=6,ymin=-1,ymax=3.5]
\tkzClip[space=1]
\tkzDrawX[noticks,label={}]
\tkzDrawY[noticks,label={}]
\tkzFct[domain=.1:5,samples=200,id=ln,line width=0.5pt,color=red]{log(x)+1}
\tkzDrawTangentLine[kl=1,kr=5](1)
\tkzDefPointByFct[draw](1) \tkzGetPoint{A}
\tkzLabelPoint[above left](A){$A$}
\tkzPointShowCoord[xlabel=$a$,ylabel=$f(a)$](A)
\tkzDefPointByFct[draw](\alpha)\tkzGetPoint{M}
\tkzLabelPoint(M){$M$}
\tkzPointShowCoord[xlabel=$a+h$,noxdraw,ylabel=$f(a+h)$](M)
\tkzDefPoint(\alpha,\alpha){M'}
\tkzDrawPoint(M')
\tkzLabelPoint[above left](M'){$M'$}
\tkzPointShowCoord[ylabel=$f'(a)\times h+f(a)$](M')
\end{tikzpicture}
}
\end{document}


You get this

Then you can create an animated tangent line with

\documentclass{article}
\usepackage{animate}
\begin{document}

\begin{center}
\animategraphics[palindrome]{12}{tgt}{}{}
\end{center}

\end{document}


I have always the same problem to create the animated gif sorry :(

-
Do we need to have gnuplot to compile the second code? BTW for conversion into gif this link tex.stackexchange.com/a/23728/11232 may be useful. You have to install image magick and give convert -verbose -delay 50 -loop 0 -density 300 <file>.pdf <file>.gif. –  Harish Kumar May 13 '12 at 7:39
Actually with tkz-fct you need gnuplot to draw the curves but I work on a new version to work only with tikz. You don't need gnuplot to the last code with animate but gnuplot is necessary to get tgt.pdf. With some complex functions you need to use gnuplot with pgfplots too. –  Alain Matthes May 13 '12 at 7:41
I'm not really sure for the next version because pgfplots is a very fine tool and perhaps it's a waste of time to work on a new version. Perhaps only for the fun. –  Alain Matthes May 13 '12 at 7:48
Oh, That is the one I don't have. Waiting for your new version eagerly. –  Harish Kumar May 13 '12 at 7:48
Oh. I see. That is true. –  Harish Kumar May 13 '12 at 7:48