{
 "metadata": {
  "name": "",
  "signature": "sha256:eb3ec13cb8ee2c6e4f84dcc0ae5f1565a4a274204f44284f3f998619466985e1"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from __future__ import absolute_import"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 1
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from bokeh.document import Document\n",
      "from bokeh.session import Session\n",
      "\n",
      "document = Document()\n",
      "session = Session()\n",
      "session.use_doc('taylor_server')\n",
      "session.load_document(document)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 2
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import numpy as np\n",
      "import sympy as sy\n",
      "\n",
      "from bokeh.objects import Plot, DataRange1d, LinearAxis, ColumnDataSource, Glyph, Grid, Legend\n",
      "from bokeh.widgetobjects import Slider, TextInput, HBox, VBox, Dialog\n",
      "from bokeh.glyphs import Patch, Line, Text\n",
      "\n",
      "xs = sy.Symbol('x')\n",
      "expr = sy.exp(-xs)*sy.sin(xs)\n",
      "order = 1\n",
      "\n",
      "def taylor(fx, xs, order, x_range=(0, 1), n=200):\n",
      "    x0, x1 = x_range\n",
      "    x = np.linspace(float(x0), float(x1), n)\n",
      "\n",
      "    fy = sy.lambdify(xs, fx, modules=['numpy'])(x)\n",
      "    tx = fx.series(xs, n=order).removeO()\n",
      "\n",
      "    if tx.is_Number:\n",
      "        ty = np.zeros_like(x)\n",
      "        ty.fill(float(tx))\n",
      "    else:\n",
      "        ty = sy.lambdify(xs, tx, modules=['numpy'])(x)\n",
      "\n",
      "    return x, fy, ty\n",
      "\n",
      "def update_data():\n",
      "    x, fy, ty = taylor(expr, xs, order, (-2*sy.pi, 2*sy.pi), 200)\n",
      "\n",
      "    plot.title = \"%s vs. taylor(%s, n=%d)\" % (expr, expr, order)\n",
      "    legend.legends = {\n",
      "        \"%s\"         % expr: [line_f_glyph],\n",
      "        \"taylor(%s)\" % expr: [line_t_glyph],\n",
      "    }\n",
      "    source.data = dict(x=x, fy=fy, ty=ty)\n",
      "    slider.value = order\n",
      "\n",
      "    session.store_document(document)\n",
      "\n",
      "source = ColumnDataSource(data=dict(\n",
      "    x  = [],\n",
      "    fy = [],\n",
      "    ty = [],\n",
      "))\n",
      "\n",
      "xdr = DataRange1d(sources=[source.columns(\"x\")])\n",
      "ydr = DataRange1d(sources=[source.columns(\"fy\")])\n",
      "\n",
      "plot = Plot(data_sources=[source], x_range=xdr, y_range=ydr, plot_width=800, plot_height=400)\n",
      "\n",
      "line_f = Line(x=\"x\", y=\"fy\", line_color=\"blue\", line_width=2)\n",
      "line_f_glyph = Glyph(data_source=source, xdata_range=xdr, ydata_range=ydr, glyph=line_f)\n",
      "plot.renderers.append(line_f_glyph)\n",
      "\n",
      "line_t = Line(x=\"x\", y=\"ty\", line_color=\"red\", line_width=2)\n",
      "line_t_glyph = Glyph(data_source=source, xdata_range=xdr, ydata_range=ydr, glyph=line_t)\n",
      "plot.renderers.append(line_t_glyph)\n",
      "\n",
      "xaxis = LinearAxis(plot=plot, dimension=0)\n",
      "yaxis = LinearAxis(plot=plot, dimension=1)\n",
      "\n",
      "xgrid = Grid(plot=plot, dimension=0, axis=xaxis)\n",
      "ygrid = Grid(plot=plot, dimension=1, axis=yaxis)\n",
      "\n",
      "legend = Legend(plot=plot, orientation=\"bottom_left\")\n",
      "plot.renderers.append(legend)\n",
      "\n",
      "def on_slider_value_change(obj, attr, old, new):\n",
      "    global order\n",
      "    order = int(new)\n",
      "    update_data()\n",
      "\n",
      "def on_text_value_change(obj, attr, old, new):\n",
      "    try:\n",
      "        global expr\n",
      "        expr = sy.sympify(new, dict(x=xs))\n",
      "    except (sy.SympifyError, TypeError, ValueError) as exception:\n",
      "        dialog.content = str(exception)\n",
      "        dialog.visible = True\n",
      "        session.store_document(document)\n",
      "    else:\n",
      "        update_data()\n",
      "\n",
      "dialog = Dialog(title=\"Invalid expression\", buttons=[\"Close\"])\n",
      "\n",
      "slider = Slider(start=1, end=20, value=order, step=1, title=\"Order:\")\n",
      "slider.on_change('value', on_slider_value_change)\n",
      "\n",
      "text = TextInput(value=str(expr), title=\"Expression:\")\n",
      "text.on_change('value', on_text_value_change)\n",
      "\n",
      "inputs = HBox(children=[slider, text])\n",
      "layout = VBox(children=[inputs, plot, dialog])\n",
      "\n",
      "document.add(layout)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 3
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "update_data()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 4
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "session.show(layout)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 5
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import time\n",
      "\n",
      "try:\n",
      "    while True:\n",
      "        session.load_document(document)\n",
      "        time.sleep(0.5)\n",
      "except KeyboardInterrupt:\n",
      "    pass"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 8
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [],
     "language": "python",
     "metadata": {},
     "outputs": []
    }
   ],
   "metadata": {}
  }
 ]
}