import numpy as np
import matplotlib.pyplot as plt

#plt.xkcd()
fig = plt.figure( figsize=(2.5,3.4) )
ax = fig.add_subplot(1, 1, 1)

# parabula:
x1 = -0.2
x2 = 0.9
x = np.linspace(x1, x2, 200)
y = x*x
ax.set_xlim(x1, x2)
ax.set_ylim(-0.2, 0.7)
ax.plot(x, y, c='b', lw=4, zorder=0)
# secant:
x = np.asarray([0.1, 0.7])
y = x*x
ax.set_xticks(x)
ax.set_yticks(y)
ax.set_xticklabels(['$x$','$x+\Delta x$'])
ax.set_yticklabels(['',''])
ax.scatter(x, y, c='#CC0000', edgecolor='none', s=150, zorder=10)
# function values:
ax.plot([x[0], x[0], x1],[-0.2, y[0], y[0]], '--k', lw=1, zorder=6)
ax.plot([x[1], x[1], x1],[-0.2, y[1], y[1]], '--k', lw=1, zorder=6)
ax.text(x1+0.05, y[0]+0.05, '$f(x)$', zorder=6)
ax.text(x1+0.05, y[1]+0.05, '$f(x+\Delta x)$', zorder=6)
# slope triangle:
ax.plot([x[0], x[1], x[1]],[y[0], y[0], y[1]], '-k', lw=2, zorder=7)
ax.text(np.mean(x), y[0]-0.08, '$\Delta x$', ha='center', zorder=7)
ax.text(x[1]+0.05, np.mean(y), '$f(x+\Delta x)-f(x)$', va='center', rotation='vertical', zorder=7)
# secant line:
m = np.diff(y)/np.diff(x)
xl = [x1, x2]
yl = m*(xl-x[0])+y[0]
ax.plot(xl, yl, c='#CC0000', lw=3, zorder=7)

# derivative:
md = 2.0*x[0]
yl = md*(xl-x[0])+y[0]
ax.plot(xl, yl, c='#FFFF66', lw=3, zorder=5)

# limit:
for ml in np.linspace(md, m, 5)[1:] :
    yl = ml*(xl-x[0])+y[0]
    xs = 0.5*(ml+np.sqrt(ml*ml-4.0*(ml*x[0]-y[0])))
    ax.scatter([xs], [xs*xs], c='#FFCC00', edgecolor='none', s=80, zorder=3)
    ax.plot(xl, yl, c='#FFCC00', lw=2, zorder=3)

plt.tight_layout();
plt.savefig('derivative.pdf')
#plt.show();
