diff --git a/code/11 Project 2.ipynb b/code/11 Project 2.ipynb new file mode 100644 index 00000000..2ff87bad --- /dev/null +++ b/code/11 Project 2.ipynb @@ -0,0 +1,776 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "from modsim import *" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# S = % SUSCEPTIBLE, I = % INFECTED, R = % RECOVERED" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def make_system(S=89, I=1, N=0, D=0, contact_rate = .11, safe_rate = .02, death_rate=.006, t_end = 200):\n", + " \n", + " pop = State(S = S, I = I, N = N, D=D) #creates initial population\n", + " pop /= sum(pop) #converts population to percentages\n", + "\n", + " t0 = 0\n", + "\n", + " return System(init=pop, t0=t0, t_end=t_end,\n", + " contact_rate = contact_rate, death_rate = death_rate, safe_rate = safe_rate)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def update(state, system):\n", + " \n", + " unpack(system)\n", + " \n", + " s, i, n , d = state \n", + " \n", + " infected = contact_rate * i * s\n", + " non_infectious = safe_rate*i\n", + " dead = death_rate * i\n", + " \n", + " s -= infected\n", + " i += infected - non_infectious - dead\n", + " n += non_infectious\n", + " d += dead\n", + " \n", + " return State(S=s, I=i, N=n, D=d)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# def run_simulation(system, update_func):\n", + "# unpack(system)\n", + "# state = pop\n", + "# for t in linrange(t0, t_end):\n", + "# state = update_func(state, system)\n", + "# return state" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run_simulation(system, update_func):\n", + " \n", + " \n", + " frame = DataFrame(columns = system.init.index)\n", + " frame.loc[system.t0] = system.init\n", + " \n", + " for i in linrange(system.t0, system.t_end):\n", + " frame.loc[i+1] = update_func(frame.loc[i], system)\n", + " \n", + " system.results = frame\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def plot_results(S, I, N, D):\n", + " \"\"\"Plot the results of a SIR model.\n", + " \n", + " S: TimeSeries\n", + " I: TimeSeries\n", + " R: TimeSeries\n", + " \"\"\"\n", + " plot(S, '--', color='blue', label='Susceptible')\n", + " plot(I, '-', color='red', label='Infected')\n", + " plot(N, ':', color='green', label='Non-Infectious')\n", + " plot(D, '-', color='black', label='Dead')\n", + " decorate(xlabel='Time (Years)',\n", + " ylabel='Fraction of population')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
S0.996553
I0.001724
N0.001724
D0.000000
\n", + "
" + ], + "text/plain": [ + "S 0.996553\n", + "I 0.001724\n", + "N 0.001724\n", + "D 0.000000\n", + "dtype: float64" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_system = make_system(S=318000, I=550, N=550, D=0, contact_rate = .11, safe_rate = .02, death_rate=.006, t_end =75)\n", + "test_system.init" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nPhEwBAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "run_simulation(test_system, update)\n", + "frame= test_system.results\n", + "plot_results(frame.S, frame.I, frame.N, frame.D)\n", + "decorate(title='Fraction of Population Infected with HIV Over Time')\n", + "#plt.rcParams[\"figure.figsize\"] = [13,8]" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def logistic(x, A=0, B=1, C=1, M=0, K=1, Q=1, nu=1):\n", + " \"\"\"Computes the generalize logistic function.\n", + " \n", + " A: controls the lower bound\n", + " B: controls the steepness of the transition \n", + " C: not all that useful, AFAIK\n", + " M: controls the location of the transition\n", + " K: controls the upper bound\n", + " Q: shift the transition left or right\n", + " nu: affects the symmetry of the transition\n", + " \n", + " returns: float or array\n", + " \"\"\"\n", + " exponent = -B * (x - M)\n", + " denom = C + Q * exp(exponent)\n", + " return A + (K-A) / denom ** (1/nu)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def compute_factor(spending):\n", + " \"\"\"Reduction factor as a function of spending.\n", + " \n", + " spending: dollars from 0 to 1200\n", + " \n", + " returns: fractional reduction in beta\n", + " \"\"\"\n", + " return logistic(spending, M=40000, K=.35, B=0.0001)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0., 5000., 10000., 15000., 20000., 25000.,\n", + " 30000., 35000., 40000., 45000., 50000., 55000.,\n", + " 60000., 65000., 70000., 75000., 80000., 85000.,\n", + " 90000., 95000., 100000.])" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "spending = linspace(0, 100000, 21)\n", + "spending" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure to file chap05-fig04.pdf\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "percent_reduction = compute_factor(spending) * 100\n", + "\n", + "plot(spending, percent_reduction)\n", + "\n", + "decorate(xlabel='condom campaign spending (USD)',\n", + " ylabel='Percent reduction in infection rate',\n", + " title='Effect of providing condoms on infection rate',\n", + " legend=False)\n", + "\n", + "savefig('chap05-fig04.pdf')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def calc_total_infected(system):\n", + " \"\"\"Fraction of population infected during the simulation.\n", + " \n", + " system: System object with results.\n", + " \n", + " returns: fraction of population\n", + " \"\"\"\n", + " frame = system.results\n", + " return frame.S[system.t0] - frame.S[system.t_end]\n", + "\n", + "def add_condoms(system, spending):\n", + " \"\"\"Modifies system to model the effect of hand washing.\n", + " \n", + " system: System object\n", + " spending: campaign spending in USD\n", + " \"\"\"\n", + " factor = compute_factor(spending)\n", + " system.contact_rate *= (1-factor)\n", + " \n", + "def sweep_condoms(spending_array):\n", + " \"\"\"Run simulations with a range of spending.\n", + " \n", + " spending_array: array of dollars from 0 to 1200\n", + " \n", + " returns: Sweep object\n", + " \"\"\"\n", + " sweep = SweepSeries()\n", + " for spending in spending_array:\n", + " #system = test_system = make_system(S=318000, I=550, N=550, D=0, contact_rate = .11, safe_rate = 0, death_rate=.006, t_end =75)\n", + " add_condoms(system, spending)\n", + " run_simulation(system, update)\n", + " sweep[spending] = calc_total_infected(system)\n", + " return sweep " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'system' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0minfected_sweep\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0msweep_condoms\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mspending\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minfected_sweep\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m decorate(xlabel='Condom campaign spending (USD)',\n", + "\u001b[1;32m\u001b[0m in \u001b[0;36msweep_condoms\u001b[1;34m(spending_array)\u001b[0m\n\u001b[0;32m 28\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mspending\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mspending_array\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 29\u001b[0m \u001b[1;31m#system = test_system = make_system(S=318000, I=550, N=550, D=0, contact_rate = .11, safe_rate = 0, death_rate=.006, t_end =75)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 30\u001b[1;33m \u001b[0madd_condoms\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msystem\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mspending\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 31\u001b[0m \u001b[0mrun_simulation\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msystem\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mupdate\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 32\u001b[0m \u001b[0msweep\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mspending\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcalc_total_infected\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msystem\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mNameError\u001b[0m: name 'system' is not defined" + ] + } + ], + "source": [ + "infected_sweep = sweep_condoms(spending)\n", + "\n", + "plot(infected_sweep)\n", + "\n", + "decorate(xlabel='Condom campaign spending (USD)',\n", + " ylabel='Total fraction infected',\n", + " title='Effect of condoms on total infections',\n", + " legend=False)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def linear(x, slope=1):\n", + " value = slope*x\n", + " return value\n", + "\n", + "def compute_factor_ARV(spending):\n", + " return linear(spending,slope=.000015)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# def compute_factor_ARV(spending):\n", + "# \"\"\"Reduction factor as a function of spending.\n", + " \n", + "# spending: dollars from 0 to 1200\n", + " \n", + "# returns: fractional reduction in beta\n", + "# \"\"\"\n", + "# return logistic(spending, M=40000, K=.2, B=0.0001)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nSUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "percent_reduction = compute_factor_ARV(spending) * 100\n", + "\n", + "plot(spending, percent_reduction)\n", + "\n", + "decorate(xlabel='ARV campaign spending (USD)',\n", + " ylabel='multiplier increase safe rate',\n", + " title='Effect of providing ARV on safe rate',\n", + " legend=False)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def add_ARV(system, spending):\n", + " \"\"\"Modifies system to model the effect of hand washing.\n", + " \n", + " system: System object\n", + " spending: campaign spending in USD\n", + " \"\"\"\n", + " factor = compute_factor_ARV(spending)\n", + " system.safe_rate *= factor\n", + " \n", + "def sweep_ARV(spending_array):\n", + " \"\"\"Run simulations with a range of spending.\n", + " \n", + " spending_array: array of dollars from 0 to 1200\n", + " \n", + " returns: Sweep object\n", + " \"\"\"\n", + " sweep = SweepSeries()\n", + " for spending in spending_array:\n", + " system = test_system = make_system(S=318000, I=550, N=550, D=0, contact_rate = .11, safe_rate = .02, death_rate=.006, t_end =75)\n", + " add_ARV(system, spending)\n", + " run_simulation(system, update)\n", + " sweep[spending] = calc_total_infected(system)\n", + " return sweep " + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure to file chap05-fig05.pdf\n" + ] + }, + { + "data": { + "image/png": "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\nPgsXLtT5fa1OSUkJ48aNo0uXLrz77rucPn2aDRs2oNFoWLhwIU8//TTW1tbMmzePsLAwQkND8fLy\nIj8/nzFjxpCRkcGYMWNwcnLiyJEj/Otf/+LGjRvaJKrRaBgzZgzXrl1j5MiRqNVq9u7dy3vvvUdR\nUREDBw7knXfeqXL+mu5BzZgxgx07dhAWFsb48eO5evUqa9as4ejRo6xduxYLCwvtse+99x5OTk68\n9tprZGVl8dVXXzFlyhR27dqFvr4+V65c4ZVXXsHf35+ZM2dSXl7OmjVreOWVV/j+++8JCgp6qPf1\niaGIRvXOO+8oarX6vn8uXLigPf6TTz5R1Gq1kpCQUGNbWVmZEhoaqowaNUopLS3VHldQUKAMGDBA\nGTZsmLZtxIgRSkhIiJKVlaVtu3btmuLr66vMmzevxmtW54UXXlACAwOVlJQUbVtRUZHy3HPPKQEB\nAUpmZqaiKIqyfv16Ra1WK0ePHn3g+3Pw4EFFrVYr//d//6dt+9vf/qao1WolIiKiyrEfffSRolar\nlT179iiZmZnaPwkJCUp4eLjSpUsXpXv37kpubm6V57377ruKn5+fkpOTo21LSkpSfHx8lMWLF983\nPo1Go4SEhCh9+/ZV8vPzte3Z2dlKSEiI0rt3b6WkpERRFEXp2bOn4uPjo8TGxmqPS0lJUdRqtfL2\n22/f9zqVr+3u9/a5555TOnTooKSmpmrbioqKlKFDhyqBgYHa1/Pjjz8qarVaOX78uPa4iRMnKqGh\noYpGo6lyneHDhyudO3fW/vsvf/mL0qZNm1rFVvnv+fPnVzlu4sSJip+fn1JcXKwoiqLExcUparVa\nWbp0aZVz+fv7V3mPFEVR5s2bp6jVaiUmJkZRFEVZsWKFolarlS1btmiPKSsrU0aOHKn07NlTKSsr\nq/b8hw4dUtRqtbJx40ZFURRl9+7dilqtVv7zn/9Uud7mzZsVtVqtLFy4sMrzRo4cqZSVlWmP++yz\nzxS1Wq0cOXJEURRF+fzzzxW1Wl3ld+zmzZvKwIEDlZUrV973fWxKZKjtEfHhhx+yfPnyav94eHjU\n6lwXLlwgISGB/v37k5ubS1ZWFllZWRQVFdG3b18uXrxIWloamZmZREdHM2TIkCoz6lq2bMn69et5\n+eWXdb7mzZs3OXPmDMOGDcPZ2VnbbmxszEsvvURRURGHDx+u1euAikkFgHbY5O6/1zTcNmXKFLp1\n66b9ExoayuzZswkMDGTt2rVYWVlVOX7o0KGUlJRUGaLaunUriqI8cJjt7NmzZGRkMG7cuCr3Kmxs\nbBgzZgwpKSlcuHBB2966desqvUZnZ2dsbW25efPmg96KKtLS0jh//jzPPfccTk5O2nZjY2P++Mc/\ncvv27fu+38uWLWPdunVVeoxZWVlYWlrW2bT5p59+usq/fX19KSkp0Q63VSciIgJfX1/s7Oy0v7dZ\nWVnaIcLKIau9e/fi4OBQ5Rp6enosWLCAlStXolKpdIpx9+7dAPzpT3+q0j548GA8PT2r/E5Axe+e\nnt6dj802bdoAaH9+lb/7c+fO1f7c7ezs2L59O2PHjtUppqZAhtoeER06dNBpVpsuKteqzJ8/n/nz\n51d7THJyMvr6+gB4enre8/iD1m78VlJSElCRtH6rVatW2mvWRnFxMREREVhZWeHk5KRdj+Hm5oaZ\nmRkHDhwgMzMTOzu7Ks+bNWsWarWasrIyoqKi+PrrrwkJCWH+/Pn3JB2ALl264OjoyLZt2xg+fDhQ\nkXjatWtX7eu5W2VMD3rdAQEBANVOmTcyMqKsrOxBb8fvum5N9PX1uXHjBosWLeLq1avcuHGD9PR0\n7WN14bdTt42MjICKtTU1SUhIoKSkhG7dulX7eEpKClDx+j08PO5JMLX9P5SYmIitrW21PxcvLy+O\nHTtWpa2m11T583vmmWfYuXMnP//8Mz///DOOjo707t2b5557rs6XOTzOJPE8gSr/Y0+fPp3AwMBq\nj/Hy8uL69esAOn87vB/lPts6VcZT25lhu3fv1t7ovntK7N02bdrEpEmTqrT5+/tr72H17NkTf39/\nXnvtNV5++WW+++477YdFJT09PQYPHsx3333HrVu3yMrK4vz58/z1r399YIy1fd13f1t+GA/7fn/5\n5ZcsXLgQLy8vOnXqRFhYGO3bt+ebb75h27ZtdRLj73mt5eXlBAcH88orr1T7eGXvrry8vEF+b3/7\nHj7omoaGhnz66adcunSJiIgIDhw4wPr161m7di1vv/02L7300kPH/CSQxPMEcnV1BcDMzIzu3btX\neSw6Oprc3FxMTEy0C/buXs1f6cMPP8Ta2vqeIYgHXfPatWv3PFaZ4O4egtNF5TDbe++9pz1/pbS0\nNP7xj3+wYcOGexLPbw0YMICxY8eyatUqPvroI9599917jhk6dChff/01e/bsITU1FQMDA5555pkH\nxnj36757EgHced11vTAS7nyzv9/7XdN1CwsL+fTTTwkJCeF///tflR5ObYf86lrz5s0pKCi45/c2\nOzubyMhI7cJgFxcX7eu82549e9i+fTtvv/22TtdzdXXlyJEjZGdn39PriYuLq/XvbFJSEqmpqXTs\n2BFfX1/eeOMNkpOTmTBhAl999ZUknl/JPZ4nkL+/Pw4ODnz33XcUFBRo2/Pz85kxYwazZs1CX18f\nJycnfH192bJlS5UptAkJCaxYsUL7IVT5zfV+3w4dHBzw9/dn06ZNVUqnaDQali9fjpGRESEhITq/\nhry8PPbt20eLFi2YMGEC/fv3r/Jn7Nix+Pj4EBsby7lz5x54vjfffBNXV1e+/fbbaqeUt2nTBm9v\nb/bt28fu3bvp3r37PUN41QkICMDe3p6VK1dWea9v3brF6tWrcXZ21t4HeBiVyaGyN1N53o0bN5KW\nlqY9TqPR8O2332JiYqIdrvrtz6+wsJDi4mJatGhRJemcO3eOkydP1nrYry7169eP8+fPa2cgVlq6\ndClvvPEGV69eBSqmlaenp2vv0VRavnw5+/fvx8bGRvu67ze017dvX6CiB3i3bdu2cePGDe3juvrs\ns8+YNGmSdtgSKpKpo6NjnfV2nwTS43lE7Ny5s8aSOUCtVlsbGhoye/Zs/vznPzN8+HBGjBiBsbEx\na9euJTk5mQULFmBgUPGjnzVrFpMnT+b555/nhRdeQE9Pj5UrV2JlZaWdXFA5rr1s2TJ69epFaGho\ntdedPXs2EyZMYMSIEYwePRpzc3M2bdrE+fPnmT17drX3V2qyfft2SkpKeP7552s8ZtSoUcydO5fw\n8HD8/f3vez4zMzPef/99/vSnPzF79mw2bNigfQ8qDR06lC+//JLbt2/XeG/st4yMjPjrX//KX/7y\nF55//nlGjBhBeXk5a9euJSsriyVLltTJkFDlz+B///sfPXv2pF+/fsyePZtJkyZp328zMzPt+z1n\nzhztNODK565atYq0tDQGDx6Mn58fP/74I6amprRo0YLY2FjWrVun/XDMz8+vMo24oUydOpWdO3cy\nbdo0Ro8eTatWrTh+/DibN2+mb9++2inno0ePJjw8nOnTpzN27Fg8PT3Zu3cvx44dY968eejp6WFr\na4tKpWLXrl04OTnx1FNP3XO90NBQ+vTpw9dff01ycjJdunTh2rVr/PDDD7Ro0aJWE2wA/vCHP7B5\n82b+8Ic/8OKLL2JpacmRI0eIiopi5syZdfIePQkk8TwiPvjgg/s+XtsyH0899RTW1tZ8/vnnfPbZ\nZ+jp6dG6dWs+//zzKt/iunbtyrfffssnn3zC0qVLMTY2pnPnzrz11ls4ODgAFTdMIyIi2LBhA5GR\nkTUmnqCgIFavXs0nn3zC119/TXl5Ob6+vixdurTGezQ12bRpE/r6+jz77LM1HjN06FA+/PBD7Zqe\nB+nduzeDBg1i69atLFu2jKlTp1Z5fPDgwSxatAhTU9NaxTto0CCsra357LPP+PTTTzEwMKB9+/b8\n5z//qbMbyoMHD2bHjh2sXbuWqKgo+vXrR6dOnfj+++/55JNPWLZsGYqi0KZNGz7//PMqC4lDQkII\nCwtj9+7dHDlyhIEDB/Lpp5/ywQcfsG7dOkpKSnB1dWXq1Km4u7vz5z//maNHj9b6Z1YXmjVrxg8/\n/MAnn3zC1q1byc3NpXnz5tp7dJVJ3MzMjO+++45FixaxefNm8vPzadWqFZ988glhYWEAWFhYMH36\ndJYvX87//d//VTsRQ6VSsWTJEr788kt++ukndu3ahb29PaNGjeL111+vdfJt06YNX3/9NZ999hlf\nffUV+fn5tGzZkvfff79eygI9rlTK/cZPhBBCiDomg45CCCEalCQeIYQQDUoSjxBCiAb1RE4uKCoq\n4ty5czg4ONTZKmwhhHjSlZWVkZGRgb+/PyYmJvV2nScy8Zw7d07qIgkhxO+0atWqezZTrEtPZOKp\nnAa8atWqWq88FkKIpio1NZWxY8dqP0PryxOZeCqH15ydneus8KYQQjQV9X2L4olMPDU5e/UmZ2Iz\ncHW0oIufM2Ymsp2xEEI0tCaVeE5cTCO/sISc/GKuJOQQ7OdMu1b26Ok9fEkTIYQQumlS06nbet0p\n+lhcUsaB00ms2RlLckbt9pgXQgjx+zWpxBPc1pkhPb2wsTDWtmXmFrJh7xUijt0gv7CkEaMTQoim\noUkNtQF4OlvhNtCC05cziLqQRklZRcn02Phsrifn0rmtM+297dHXb1I5WQghGkyT/HTV19ejo68T\nY5/ypbW7jba9pLScw9HJ/LAjloS0W40YoRBCPLmaZOKpZGFmRFjXFgzr1YpmVndW6WbfKuKn/Vf5\n5UgceQWaxgtQCCGeQE068VRyd7Jk5AAferRvjpHhnfnrVxNz+H77JaIuplFaVvMuhkIIIXQniedX\n+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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "infected_sweep_ARV = sweep_ARV(spending)\n", + "\n", + "plot(infected_sweep_ARV)\n", + "\n", + "decorate(xlabel='Condom campaign spending (USD)',\n", + " ylabel='Total fraction infected',\n", + " title='Effect of ARV on total infections',\n", + " legend=False)\n", + "\n", + "savefig('chap05-fig05.pdf')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9090" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "population = 318000\n", + "budget = 100000\n", + "price_per_dose = 11\n", + "max_doses = int(budget / price_per_dose)\n", + "dose_array = linrange(max_doses)\n", + "max_doses" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# def sweep_doses(dose_array):\n", + "# \"\"\"Runs simulations with different doses and campaign spending.\n", + " \n", + "# dose_array: range of values for number of vaccinations\n", + " \n", + "# return: Sweep object with total number of infections \n", + "# \"\"\"\n", + "# sweep = SweepSeries()\n", + "# for doses in dose_array:\n", + "# fraction = doses / population\n", + "# spending = budget - doses * price_per_dose\n", + " \n", + "# system = make_system(S=318000, I=550, N=550, D=0, contact_rate = .11, safe_rate = .02, death_rate=.006, t_end =75)\n", + "# add_condoms(system, fraction)\n", + "# add_ARV(system, spending)\n", + " \n", + "# run_simulation(system, update)\n", + "# sweep[doses] = calc_total_infected(system)\n", + "\n", + "# return sweep" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#infected_sweep = sweep_doses(dose_array)\n", + "# plot(infected_sweep)\n", + "\n", + "# decorate(xlabel='Doses of vaccine',\n", + "# ylabel='Total fraction infected',\n", + "# title='Total infections vs. doses',\n", + "# legend=False)\n", + "\n", + "# savefig('chap05-fig06.pdf')" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "spending_array= linspace(0, 100000, 21)\n", + "\n", + "def sweep_spending(system,spending):\n", + " sweep = SweepSeries()\n", + " for spending in spending_array:\n", + " system = make_system(S=318000, I=550, N=550, D=0, contact_rate = .11, safe_rate = .02, death_rate=.006, t_end =75)\n", + " #print('1')\n", + " #print(system)\n", + " add_ARV(system, 100000-spending)\n", + " #print('2')\n", + " #print(system)\n", + " add_condoms(system, spending)\n", + " #print('3')\n", + " #print(system)\n", + " run_simulation(system, update)\n", + " sweep[spending] = calc_total_infected(system)\n", + " return sweep" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure to file chap05-fig06.pdf\n" + ] + }, + { + "data": { + "image/png": "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\nYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "spending_array= linspace(0, 1, 50)\n", + "\n", + "def sweep_spending(system,spending):\n", + " sweep = SweepSeries()\n", + " for spending in spending_array:\n", + " system = make_system(S=318000, I=550, N=550, D=0, contact_rate = .11, safe_rate = .02, death_rate=.006, t_end =75)\n", + " #print('1')\n", + " #print(system)\n", + " add_ARV(system, (1-spending)*100000)\n", + " #print('2')\n", + " #print(system)\n", + " add_condoms(system, spending*100000)\n", + " #print('3')\n", + " #print(system)\n", + " run_simulation(system, update)\n", + " sweep[spending] = calc_total_infected(system)\n", + " return sweep" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure to file chap05-fig06.pdf\n" + ] + }, + { + "data": { + "image/png": "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\nUStnohDQJ9BTal+4loei0tp/TCEiIiJqas0apAICAmBtbY24uDipLy0tDenp6ejVq1et/desWSNd\nxlctISEBzs7OcHR0REREBHQ6HeLj46XtZ86cgcFgQERERNOdCBHJpou3PTycrQEAeoOIuEu8H5KI\niIiaX7MGKaVSiQkTJmDJkiU4cuQILl26hDlz5qB3794IDQ1FRUUFcnNzpcv1Jk+ejMOHD+PTTz9F\namoqtm/fjrVr12L69OkQBAHu7u549NFH8fe//x1nzpzB6dOnsXDhQowYMaLOES4iav0EQUC/oLuj\nUldvFSKvsFzGioiIiKg9avYFeWfNmoVhw4YhNjYWkyZNgpeXFz7++GMAQHx8PAYMGCCNMA0YMADL\nli3DN998g2HDhmHt2rVYsGABxo8fLx3vH//4B8LDw/HCCy/g5ZdfRp8+ffDmm28292kRUTPycrVB\nJ087AIAoijh+IUPmioiIiKi9EURRFOUuormlpaUhJiYGBw8ehI+Pj9zlENEfkH+nHFv3J6H6I2zE\nA13g624rc1VERETUltwvNzT7iBQRUWNwtrdE946OUvvEhUy0w78LERERkUwYpIio1erdwwOmJlUf\nYzkFZUi+XShzRURERNReMEgRUatlY6VEcFcXqR13KQsGA0eliIiIqOkxSBFRqxYe4AZzpQkAoLBE\ni2tpHJUiIiKipscgRUStmoXSFCHdXKX26SvZvFeKiIiImhyDFBG1esFdXGBmWvVxpi7SICX9jswV\nERERUVvHIEVErZ6FuSmCuty9V4qjUkRERNTUGKSIqE0IVblKM/jlFpbjVlaxzBURERFRW8YgRURt\ngpWFGXp2dpbav3BUioiIiJoQgxQRtRlhKlcoFAIAICu/FOm5JTJXRERERG0VgxQRtRk2Vkp07+gk\ntU9fyZGxGiIiImrLGKSIqE0J93eDQqgalUrLKUZWfqnMFREREVFbxCBFRG2KvY05VB0cpPbpK9ky\nVkNERERtFYMUEbU5EQHuEH4dlbqZWYTcgnKZKyIiIqK2hkGKiNocRzsLdPG2l9qnEzkqRURERI2L\nQYqI2qTI7u7Sv6+nFUJdpJGxGiIiImprGKSIqE1ycbBEJ087qX2G90oRERFRI2KQIqI2K6LGqFTS\n7ULcKdHKWA0RERG1JQxSRNRmeThbw9fdFgAgiiLOJHJdKSIiImocDFJE1KbVvFcqMVWNkrIKGash\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "test_system = make_system(S=318000, I=550, N=550, D=0, contact_rate = .11, safe_rate = .02, death_rate=.006, t_end =75)\n", + "infected_sweep = sweep_spending(test_system,spending_array)\n", + "plot(infected_sweep)\n", + "\n", + "decorate(xlabel='Fraction Spent on Condom Distribution',\n", + " ylabel='Total fraction infected',\n", + " title='Total infections vs. spending on condoms',\n", + " legend=False)\n", + "plt.rcParams[\"figure.figsize\"] = [13,8]\n", + "\n", + "savefig('chap05-fig06.pdf')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/code/111Project.ipynb b/code/111Project.ipynb new file mode 100644 index 00000000..1d34167a --- /dev/null +++ b/code/111Project.ipynb @@ -0,0 +1,1181 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#Population models for Syria\n", + "\n", + "%matplotlib inline\n", + "\n", + "from modsim import *" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from pandas import read_csv\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import csv\n", + "#myfile = open('C:/Users/epan/Desktop/popdata.csv') # Windows\n", + "#mycsv = myfile.read()\n", + "\n", + "filename = 'C:/Users/dberny/Desktop/popdata1.csv'\n", + "tables = read_csv(filename, header = 1, index_col=0, usecols=[0, 226], skiprows=[2,3])\n", + "#tables = read_csv(filename, header=1, index_col=1, nrows=1, skiprows=226)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Population
Year
19604573512
19614721896
19624875422
19635034646
19645200336
19655373137
19665553246
19675740710
19685935860
19696139048
19706350541
19716570857
19726800141
19737037851
19747283177
19757535714
19767794662
19778060649
19788336418
19798625690
19808930774
19819252851
19829590227
19839938847
198410293049
198510648632
198611004272
198711360852
198811719071
198912080444
199012446171
199112815219
199213187085
199313564167
199413949697
199514345492
199614755286
199715177456
199815602210
199916016092
200016410848
200116766899
200217087901
200317415266
200417806638
200518294611
200618914977
200719632806
200820325443
200920824893
201021018834
201120863993
201220420701
201319809141
201419203090
201518734987
201618430453
\n", + "
" + ], + "text/plain": [ + " Population\n", + "Year \n", + "1960 4573512\n", + "1961 4721896\n", + "1962 4875422\n", + "1963 5034646\n", + "1964 5200336\n", + "1965 5373137\n", + "1966 5553246\n", + "1967 5740710\n", + "1968 5935860\n", + "1969 6139048\n", + "1970 6350541\n", + "1971 6570857\n", + "1972 6800141\n", + "1973 7037851\n", + "1974 7283177\n", + "1975 7535714\n", + "1976 7794662\n", + "1977 8060649\n", + "1978 8336418\n", + "1979 8625690\n", + "1980 8930774\n", + "1981 9252851\n", + "1982 9590227\n", + "1983 9938847\n", + "1984 10293049\n", + "1985 10648632\n", + "1986 11004272\n", + "1987 11360852\n", + "1988 11719071\n", + "1989 12080444\n", + "1990 12446171\n", + "1991 12815219\n", + "1992 13187085\n", + "1993 13564167\n", + "1994 13949697\n", + "1995 14345492\n", + "1996 14755286\n", + "1997 15177456\n", + "1998 15602210\n", + "1999 16016092\n", + "2000 16410848\n", + "2001 16766899\n", + "2002 17087901\n", + "2003 17415266\n", + "2004 17806638\n", + "2005 18294611\n", + "2006 18914977\n", + "2007 19632806\n", + "2008 20325443\n", + "2009 20824893\n", + "2010 21018834\n", + "2011 20863993\n", + "2012 20420701\n", + "2013 19809141\n", + "2014 19203090\n", + "2015 18734987\n", + "2016 18430453" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tables" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYEAAAEKCAYAAAD0Luk/AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XtY0/e9B/A3AQKCFgW5KepRVnReuVMr9bDjHgWfjdhn\ntnNV6aqMdrZV2x7OKkg8ruijdd5tvddra3WP2g46fTo5HZ3tpnI5fYYXQD0IOLlonJ0UiUm+5w9K\nNCQhCQnwS/J+PQ+P5vv7Jn4/1f4++V5/HkIIASIickuyvm4AERH1HSYBIiI3xiRAROTGmASIiNwY\nkwARkRtjEiAicmNefd0AeymVSmi1Wqxatcqq+lu3bsW2bdtMXnv99dfx2muvObJ5RESS5uGs+wSE\nENiyZQvef/99zJ492+ok0NLSgu+++86gbNu2bfjTn/6EkydPIjQ0tCeaS0QkSU7ZE6irq0NOTg6q\nq6sxZMgQm97r7+8Pf39//evy8nIcO3YMO3fuZAIgIrfjlHMCZWVlCA8PR0FBASIiIoyuHzt2DDNm\nzMDEiRPx05/+FCdPnjT5OUIIrFq1CtOnT8fUqVN7utlERJLjlD0BhUIBhUJh8tpHH32ErVu3YsWK\nFRg7dizKy8vxzjvvAACeffZZg7pFRUW4dOkS1q9f3+NtJiKSIqdMAl3ZsWMHXnvtNaSmpgIAhg8f\njn/84x/YsWOHURI4cOAAUlNTMWLEiL5oKhFRn3OpJKBSqdDY2Ii1a9fid7/7nb5co9FAq9VCrVZD\nLpcDABoaGnD+/HkcOHCgr5pLRNTnXCoJeHt7AwDy8vKQmJhodN3L61G4RUVFCA4ONlmPiMhdOOXE\nsDkDBgxAaGgo6uvrMWLECP3P119/jb1790ImexRuSUkJEhMTDcqIiNyNy90Bf/3rX2P//v04evQo\namtrUVBQgDVr1iA4ONig3qVLlxAVFdVHrSQikgaXGg4CgF/84hdQq9XYu3cv3nnnHYSGhmLRokXI\nysoyqNfc3IyAgIA+aiURkTQ47Y5hIiKyn9P0BB48eICKigoEBwfD09Ozr5tDROQUtFotmpubMX78\nePj6+hpdd5okUFFRgblz5/Z1M4iInNKHH36I+Ph4o3KnSQIdE7sffvghwsLC+rg1RETOoaGhAXPn\nzjVaHNPBaZJAxxBQWFiYyfOCiIh61YULwKlTwK1bQHg4kJYGJCT0davMMjeM7jRJgIhIMi5cAPbs\nefT65s1HryWcCExhEiAisqTzt/6bN03XO326/Vcn6iEwCRARdcXUt/6//AUYMwboPM7+v/8L1Ncb\n1pV4D8HldgwTETnUqVPGZX5+QF2dcfndu6Y/o6OHIEFMAkREXbl1y7hs2DCgpcW4fNAg05/xj384\ntk0OxCRARNSV8HDjspAQYOpUICICkMnaf83MBCZNMv0ZNj4GtzdxToCIqCtpaYZzAh0WLjQ9zm+q\nbmqqZJeUMgkQEXXo6kZ9+nT7sM6QIe03dVM3cHN1AckuKWUSICICLK/9t/Zmbarub39ruu7p032e\nBDgnQEQEmF4FBDhmZY+pyWVAEhPGViWB27dv4ze/+Q2Sk5MRHx+PhQsXoqqqymz9v//975gzZw4m\nTZqE6dOn45NPPjG43trairy8PCQlJSE+Ph7Lly9Hi6mZdiKi3tKTN2pTk8uAJCaMLSYBnU6H1157\nDTU1NXj//ffx8ccfo3///vjlL3+JuybWxKpUKmRmZmLcuHE4ceIE5s+fj9zcXJw9e1ZfR6lUorS0\nFDt37sSOHTtw/vx5KJVKx0ZGRGSLnrxRp6WZLu+YL+hDFpPAlStXUF5ejtWrV2PixIn4wQ9+gHXr\n1uG7775DcXGxUf3f//736N+/P3JzcxEZGYn58+cjPT0dH3zwAYD2E+0KCwuxYsUKREdHIz4+Hvn5\n+fjss8/Q2Njo+AiJiKzRkzfqhIT2JaSdl5Q6w+qg8PBw7Ny5EyNHjtSXeXh4AADu3btnVL+kpAQJ\nCQkGD3BPTEzEypUrIYRAWVkZZDIZYmNj9ddjY2Ph6emJ0tJSzJw5066AiIi6xZZVQN39fAnc9Duz\nmAQGDRqElJQUg7JDhw7hwYMHSE5ONqrf0NCAsWPHGpSFhISgtbUVd+/eRWNjIwIDA+Ht7f2oEV5e\nCAwMxC1zY3JERL2hL27Ufbx/wOYlokVFRdiwYQNeeuklREZGGl1/8OAB5HK5QVnHa7VajdbWVvj4\n+Bi9Ty6Xo62tzdbmEBE5LwkcSW1TEjhx4gTy8vIwc+ZMZGdnm6zj6+sLtVptUNbxul+/fiavd9Tx\n8/OzpTlERN0jld27XS1LlVoS2L59OzZt2oR58+Zh+fLl+nmBzsLCwtDc3GxQ1tTUBD8/PwwYMABh\nYWFQqVTQarX6J91oNBqoVCqEhITYEQoRkRUk8O1bTwL7B6zaJ7B7925s2rQJixcvRl5entkEAABx\ncXEoKSmBEEJfdu7cOcTGxkImkyEuLg4ajQbl5eX666WlpdDpdIiLi7MjFCIiK/TkpjBbSWD/gFVL\nRDdu3Iif/exneP7559Hc3Kz/+e6776BWq9Hc3Kwf4pk9ezZUKhVWrFiBa9eu4dChQygsLERmZiYA\nIDQ0FGlpacjNzUVpaSlKSkqQl5cHhUKB0NDQno2WiEgC3771JLB/wOJw0B//+EdotVocP34cx48f\nN7i2ZMkSxMXFISMjAwcPHkRSUhIGDx6MPXv2ID8/H7NmzcKQIUOwdu1aTJ48Wf++/Px85OfnIysr\nC15eXpgxYwZycnIcHx0RUWfmHg/ZF7t3e3pZqhU8xOPjNhJWX1+PadOmoaioCBEREX3dHCJyVp3n\nBDpIZPOWo1m6d/IUUSJyLxL49m1RL65eYhIgIvcj0d27AHp99RKPkiYikpJeXr3EngARuS6pbAqz\nRS+vXmISICLXJKVNYbbo5dVLHA4iItckpU1htujlvQPsCRCRa5LSpjBbdLV6qQeGt5gEiMg1SWlT\nmK1MrV7qoeEtDgcRkWuSwJEMDtVDw1vsCRCRa3KGTWG26Gp4y45hIiYBInJdUt4UZitzw1tC2DVM\nxCRARK7BGfcE2CItzfSZR+aOf7PywTScEyAi59cxaXrzJqDTPfo2fOFCX7fMcRIS2g+5i4gAZLL2\nXzMz239vipWroNgTICLnJ4HHNPYKU8Nbp07ZtQqKPQEicn7OuifAEexcBcWeABE5P2feE2AvO1dB\nMQkQkfMzN2nqrHsCbGXHKigmASJyLl2tAnKVPQG9iEmAiJyHpaMTeNO3GSeGich5OOvJoBJmc09A\nqVRCq9Vi1apVJq/Pnz8f58+fN3nt8OHDSEhIQHFxMbKysoyuFxcXIywszNYmEZG7cOdVQD3E6iQg\nhMCWLVtw9OhRzJ4922y9rVu34uHDh/rXOp0Or7zyCvr374+YmBgAQGVlJcaOHYtdu3YZvDcoKMjW\n9hORO3HnVUA9xKokUFdXh5ycHFRXV2OIhf/YAwcONHi9a9cu1NXV4dSpU/Dyav/jqqurERUVheDg\n4G42m4hcnqkJYHdfBdQDrJoTKCsrQ3h4OAoKChAREWH1hzc3N2P79u144403DG741dXViIyMtL21\nROQezB0DAZg+OoETwt1mVU9AoVBAoVDY/OG7d+9GUFAQ5syZoy/TarW4fv06KioqkJ6eDpVKhQkT\nJiA7OxujRo2y+c8gIhfU1QRwXh5v+g7UY6uD7t+/j+PHjyMzMxOenp768traWrS1tUGtViM/Px+b\nNm2CWq3G3LlzcefOnZ5qDhE5E04A95oe2ydQVFQErVaL9PR0g/KRI0fi3LlzeOKJJyD7/vS7bdu2\nISUlBZ9++ikWLFjQU00iImfBCeBe06NJICUlBX5+fkbXOk8e9+vXD8OGDcMtc9mfiFwXJ4D7VI8N\nB5WWluKpp54yKj9z5gxiYmKgUqn0Zffv30dNTQ2efPLJnmoOEUkRJ4D7nN09AbVajXv37iEgIABy\nuRwA0NTUhNu3byMqKsqofkJCAvr374/s7GxkZ2dDq9Viw4YNGDRoULcmn4nIiXECuM/Z3RMoLy9H\ncnIyysvL9WXNzc0AgICAAKP6AQEB2L9/P7y9vZGRkYH58+fDz88PBw4cgI+Pj73NISJnwgngPmdz\nT+DQoUMGr5OSklBZWWlQNm7cOKOyx0VGRmLHjh22/tFE5Ow6j//rdKbrcQK41/AUUSLqHaZOAG1q\nAjw8gM6nB3ACuNcwCRBR7zA1/h8S0p4Ehg7lcwD6CJMAEfUOc+P/Hh7tk8DUJ5gEiMjxTK395wYw\nSeJDZYjIscyt/R8xwnR9jv/3KSYBInIsc2v/a2u5AUyCOBxERI7V1dp/PgdYctgTICLHCg83Xc6x\nf0liT4CIuo+Hvzk99gSIqHt4+JtLYE+AiLqHh7+5BPYEiKh7ePibS2ASIKLu4QSwS+BwEBFZxglg\nl8WeABF1jRPALo09ASLqGieAXRp7AkTUNU4AuzQmASLqGieAXRqTABF1LS3NdDkngF2CzXMCSqUS\nWq0Wq1atMltnyZIlOH36tEHZ5MmTsX//fgBAa2srVq9ejc8//xxarRapqalYtmwZ/P39bW0OETma\nqZVAmZntcwB8+pfLsToJCCGwZcsWHD16FLNnz+6yblVVFd566y08++yz+jK5XK7/vVKpxMWLF7Fz\n505oNBrk5ORAqVRi/fr13QiBiBzG1HOA9+xpTwJ8+pdLsmo4qK6uDhkZGThy5AiGWBgHVKvVqK2t\nxcSJExEcHKz/CQgIAAA0NDSgsLAQK1asQHR0NOLj45Gfn4/PPvsMjY2N9kdERN3X1UogcklWJYGy\nsjKEh4ejoKAAERERXda9fv06NBoNIiMjzX6WTCZDbGysviw2Nhaenp4oLS21oelE5HBcCeR2rBoO\nUigUUCgUVn1gVVUVvL29sXXrVnz55Zfw8fFBamoqFi1aBB8fHzQ2NiIwMBDe3t6PGuHlhcDAQNwy\n9w+QiHoHnwPsdhy+Wezq1asAgFGjRmHu3LmoqqrCmjVr0NDQgLVr16K1tRU+Pj5G75PL5Whra3N0\nc4jIHB4FQeiBJLB06VIsWLAAAwcOBACMHj0anp6eeOONN/D222/D19cXarXa6H1qtRp+fn6Obg4R\nmdLVBDBXArkVhycBmUymTwAdoqKiALRPCoeFhUGlUkGr1cLT0xMAoNFooFKpEBIS4ujmEJEpPAqC\nvufwzWJLlizBq6++alBWUVEBuVyO4cOHIy4uDhqNBuXl5frrpaWl0Ol0iIuLc3RziMgUTgDT9+xO\nAmq1Gs3NzfohnhkzZqCoqAj79u1DbW0tTp8+jbVr12LBggXw9/dHaGgo0tLSkJubi9LSUpSUlCAv\nLw8KhQKhoaF2B0REVuBREPQ9u4eDysvLkZGRgYMHDyIpKQkzZ86EWq3G3r17sXHjRgQFBSEjIwMv\nv/yy/j35+fnIz89HVlYWvLy8MGPGDOTk5NjbFCIyhRPA1AUPIYTo60ZYo76+HtOmTUNRUZHFvQpE\n9L3OE8AdMjPbf+UEsMuzdO/k8wSIXBkngMkCniJK5Mo4AUwWMAkQuTJOAJMFHA4ichWcAKZuYE+A\nyBXwYfDUTewJELkCTgBTN7EnQOQKOAFM3cQkQOQKOAFM3cThICJn1HkSeMQI088B4AQwWcAkQORs\nTB0DffMm8PTTQG0tdwCTTZgEiJyNuUng2lo+DJ5sxjkBImfDSWByICYBImfDSWByIA4HEUkZdwFT\nD2NPgEiquAuYegF7AkRSxV3A1AvYEyCSKk4AUy9gEiCSKk4AUy/gcBCRFHACmPoIewJEfY0TwNSH\nbO4JKJVKaLVarFq1ymydP/7xj9i5cydu3LiB4OBgPPfcc1i4cCE8PT0BAMXFxcjKyjJ6X3FxMcLC\nwmxtEpFz4wQw9SGrk4AQAlu2bMHRo0cxe/Zss/WKi4vxn//5n8jJycHUqVNx6dIl5OXl4eHDh3j1\n1VcBAJWVlRg7dix27dpl8N6goKBuhkHkxDgBTH3IqiRQV1eHnJwcVFdXY4iFSamPP/4Y06dPx7x5\n8wAAw4cPx7Vr13DixAl9EqiurkZUVBSCg4PtbD6RCwgPN30CKCeAqRdYlQTKysoQHh6ODRs24M03\n3+yy7q9//Wv4+fkZlMlkMnz77bf619XV1Zg5c2Y3mkvk5DgBTBJjVRJQKBRQKBRWfeDEiRMNXt+/\nfx9HjhzBM888AwDQarW4fv06KioqkJ6eDpVKhQkTJiA7OxujRo2ysflETsTUEdB79rRP9mZmts8B\n8Bho6mU9ukS0tbUVixYtQltbG9566y0AQG1tLdra2qBWq5Gfnw+1Wo3t27dj7ty5KCws5LwAuS5O\nAJME9VgSUKlUWLRoEa5evYoPPvgAQ4cOBQCMHDkS586dwxNPPAGZrH2F6rZt25CSkoJPP/0UCxYs\n6KkmEfUtTgCTBPVIEqivr8fChQvR0tKCw4cPY8yYMQbXBw4caPC6X79+GDZsGG6Z+5+EyBl1Hv/X\n6UzX4wQw9SGHbxa7c+cOMjIyoNPpcOTIEaMEcObMGcTExEClUunL7t+/j5qaGjz55JOObg5R3zC1\nAaypCWhuNq7LCWDqQ3b3BNRqNe7du4eAgADI5XKsXLkSd+/exYEDB+Dr64vm7//Re3h4YPDgwUhI\nSED//v2RnZ2N7OxsaLVabNiwAYMGDbJ68plI8kyN/4eEAB4ewNChnAAmybA7CZSXlyMjIwMHDx7E\npEmT8Kc//Qk6nQ7PPfecQT1PT09cunQJAQEB2L9/P9atW4eMjAxoNBpMmTIFBw4cgI+Pj73NIZIG\nc0ObHh58DjBJis1J4NChQwavk5KSUFlZqX99+fJli58RGRmJHTt22PpHEzkPbgAjJ8FTRInsxQ1g\n5MR4iiiRPXgCKDk59gSI7MENYOTk2BMgsgc3gJGTY0+AyFqmxv45AUxOjj0BImuYG/sfMcJ0fU4A\nk5NgEiCyhrmx/9paTgCTU+NwEJE1uhr7T0jgTZ+cFnsCRNYIDzddzrF/cnLsCRB1xs1f5EbYEyB6\nHDd/kZthT4Docdz8RW6GPQGix3HzF7kZ9gTIvfHpX+TmmATIfXWM/3foePqXhwcQHGxYlxPA5KKY\nBMh98elfREwC5Mb49C8iTgyTG+MGMCL2BMhNcAMYkUnsCZDr4wYwIrNs7gkolUpotVqsWrXKbJ2/\n//3vWLVqFS5fvozQ0FAsWrQIs2bN0l9vbW3F6tWr8fnnn0Or1SI1NRXLli2Dv79/96Ig6go3gBGZ\nZXVPQAiBzZs34+jRo13WU6lUyMzMxLhx43DixAnMnz8fubm5OHv2rL6OUqlEaWkpdu7ciR07duD8\n+fNQKpXdj4KoK9wARmSWVT2Buro65OTkoLq6GkMsTJr9/ve/R//+/ZGbmwuZTIbIyEhcunQJH3zw\nAZKTk9HQ0IDCwkLs378f0dHRAID8/HxkZGTgv/7rvxAaGmp/VOS++PQvIptY1RMoKytDeHg4CgoK\nEBER0WXdkpISJCQkQCZ79NGJiYkoKyuDEAJlZWWQyWSIjY3VX4+NjYWnpydKS0u7GQYR+PQvom6w\nqiegUCigUCis+sCGhgaMHTvWoCwkJAStra24e/cuGhsbERgYCG9v70eN8PJCYGAgbpnrthNZw9LT\nv06f5gYwok4cvkT0wYMHkMvlBmUdr9VqNVpbW+Hj42P0Prlcjra2Nkc3h9wJn/5FZDOHLxH19fWF\nWq02KOt43a9fP5PXO+r4+fk5ujnkTrj5i8hmDu8JhIWFobm52aCsqakJfn5+GDBgAMLCwqBSqaDV\nauHp6QkA0Gg0UKlUCAkJcXRzyFVx8xeRQzi8JxAXF4eSkhIIIfRl586dQ2xsLGQyGeLi4qDRaFBe\nXq6/XlpaCp1Oh7i4OEc3h1wRN38ROYzdPQG1Wo179+4hICAAcrkcs2fPxp49e7BixQq8+OKL+Prr\nr1FYWIjdu3cDAEJDQ5GWlobc3FysXr0aQgjk5eVBoVBweShZh5u/iBzG7p5AeXk5kpOT9d/sBw8e\njD179uDSpUuYNWsWDh8+jLVr12Ly5Mn69+Tn5yM2NhZZWVl49dVX8dRTT+G///u/7W0KuQtu/iJy\nGA/x+LiNhNXX12PatGkoKiqyuFeBXEzn8X9TG7+A9uEfHgFNZMDSvZOniJK08elfRD2KSYCkjU//\nIupRTAIkbXz6F1GPYhIg6eDhb0S9jg+VIWng4W9EfYJJgKTB0uFv3ABG1CM4HETSwMPfiPoEkwD1\nPo79E0kGh4Ood3Hsn0hSmASod3Hsn0hSOBxEvYtj/0SSwiRAPYdj/0SSx+Eg6hkc+ydyCkwC1DM4\n9k/kFDgcRI7Reejnm2+AwYON63Hsn0hSmATIfqaOe75xAxDC+Lhnjv0TSQqHg8h+poZ+hg0D6uqM\nyzn2TyQp7AmQ/Uwt+wwJeTTmzzP/iSSLSYBsY8uyz+honvlPJHEcDiLrcdknkcuxqieg1WqxadMm\nnDx5Ei0tLXjmmWegVCox2MTqj/nz5+P8+fMmP+fw4cNISEhAcXExsrKyjK4XFxcjLCzMxhCo11ha\n9nn6NId+iJyMVUlg69atOHnyJNauXYuBAwdi5cqVeP3113HkyBGTdR8+fKh/rdPp8Morr6B///6I\niYkBAFRWVmLs2LHYtWuXwXuDgoLsiYUcydSwD498IHI5FpOAWq3GwYMHsXz5ckyZMgUAsGHDBkyb\nNg1lZWWIjY01qD9w4ECD17t27UJdXR1OnToFL6/2P666uhpRUVEI7rx8kKTB1JLPx193xmWfRE7L\n4pzAlStX0NLSgsTERH1ZREQEhg4dipKSki7f29zcjO3bt+ONN94wuOFXV1cjMjLSjmZTjzI37OPh\nYbqcY/9ETstiT6ChoQEAEBoaalAeEhKiv2bO7t27ERQUhDlz5ujLtFotrl+/joqKCqSnp0OlUmHC\nhAnIzs7GqFGjuhMD2cOWYR8PD2DhQo79E7kQi0mgtbUVMpkM3t7eBuVyuRxtbW1m33f//n0cP34c\n2dnZ8PT01JfX1taira0NarUa+fn5UKvV2L59O+bOnYvCwkLOC/Sm7gz7cOyfyKVYTAK+vr7Q6XTQ\naDT6MX2gfa6gX79+Zt9XVFQErVaL9PR0g/KRI0fi3LlzeOKJJyCTtY9Gbdu2DSkpKfj000+xYMGC\n7sZCtupq2EcI43IO+xC5HItJIDw8HED7+H7H7wGgqanJaIjocUVFRUhJSYGfn5/Rtc6Tx/369cOw\nYcNwy9wwBDmGtYe8cdiHyG1YnBgeM2YM/P39Ddb+19fX4+bNm0jo4qZQWlqKp556yqj8zJkziImJ\ngUql0pfdv38fNTU1ePLJJ21tP1nL1EavGzeA5mbjuh3DPnl5wPbt7b8yARC5JItJQC6X44UXXsC7\n776LL7/8EhcvXsSbb76JxMREREdHQ61Wo7m5GWq1Wv+epqYm3L59G1FRUUafl5CQgP79+yM7OxtX\nrlzBxYsXsWTJEgwaNAgKhcKx0dEjPOSNiEywarPY0qVLodFokJ2dDY1Go98xDADl5eXIyMjAwYMH\nkZSUBKB96AgAAgICjD4rICAA+/fvx7p165CRkQGNRoMpU6bgwIED8PHxcVRc7s3aFT885I3I7XkI\nYWoGUHrq6+sxbdo0FBUVISIioq+bI12dV/xYEhHBQ96IXJileycPkHM13OhFRDbgUdLOjBu9iMhO\nTALOihu9iMgBOBzkrDjsQ0QOwJ6AM+CwDxH1ECYBqeOwDxH1IA4HSR2HfYioB7EnIDU834eIehGT\ngJSYGvq5caP9RM/OT2HjsA8ROQCTQF8xNdnb1fk+nZMAh32IyAGYBPqCucne27eNh354vg8R9SAm\ngb5gbrL37l3T4//R0Tzfh4h6BJNAT7Nljf+gQabLOfRDRD2ESaAn2brGPzq6/YbPFT9E1EuYBBzF\n2oleoOtn+HLFDxH1Im4WcwRTj27cs6d9jb8pHh5AZmb7ZG/HpG9mJm/+RNTr2BPojs7f+m/eNF3P\n3EQv1/gTkUSwJ2ArU9/6//IX0w9s50QvEUkck4CtTI3z+/mZfmB7dDSHfYhI0jgc1BVrl3cOGwZU\nVhqXc6KXiCTOqp6AVqvF+vXrkZycjJiYGCxevBi3b982W3/JkiUYPXq0wc8vf/lL/fXW1lbk5eUh\nKSkJ8fHxWL58OVpaWuwOxqHMTfbqdMZ1Q0KAqVP5jZ+InI5VPYGtW7fi5MmTWLt2LQYOHIiVK1fi\n9ddfx5EjR0zWr6qqwltvvYVnn31WXyaXy/W/VyqVuHjxInbu3AmNRoOcnBwolUqsX7/eznC6yRHL\nOxcu5E2fiJyOxZ6AWq3GwYMH8eabb2LKlCkYN24cNmzYgLKyMpSVlZmsX1tbi4kTJyI4OFj/ExAQ\nAABoaGhAYWEhVqxYgejoaMTHxyM/Px+fffYZGhsbHR+hJVzeSURuzGJP4MqVK2hpaUFiYqK+LCIi\nAkOHDkVJSQliY2MN6l+/fh0ajQaRkZEmP6+srAwymczgfbGxsfD09ERpaSlmzpzZ3Vgss+UbP5d3\nEpEbsJgEGhoaAAChoaEG5SEhIfprj6uqqoK3tze2bt2KL7/8Ej4+PkhNTcWiRYvg4+ODxsZGBAYG\nwtvb+1EjvLwQGBiIW+bO1HEEW07uBLi8k4jcgsUk0NraCplMZnDTBtrH+Nva2ozqX716FQAwatQo\nzJ07F1VVVVizZg0aGhqwdu1atLa2wsfHx+h95j6v2+zd0MVzfIjIDVhMAr6+vtDpdNBoNPDyelRd\nrVajX79+RvWXLl2KBQsWYODAgQCA0aNHw9PTE2+88Qbefvtt+Pr6Qq1WG71PrVbDz8/PnlgeMfWt\n/y9/AcaMMX44S1ff+DnsQ0QuzmISCA8PBwA0Nzfrfw8ATU1NRkNEACCTyfQJoENUVBSA9qGlsLAw\nqFQqaLVaeHp6AgA0Gg1UKhVCQkJsj8Dacf6ODV2dkwC/8RORG7OYBMaMGQN/f3+cP38eCoUCAFBf\nX4+bN28iwcSNcsmSJdBoNHjvvff0ZRUVFZDL5Rg+fDgCAwOh0WhQXl6O+Ph4AEBpaSl0Oh3i4uJs\na70t4/yhM42uAAAL/0lEQVTc0EVEZMRiEpDL5XjhhRfw7rvvYtCgQQgKCsLKlSuRmJiI6OhoqNVq\n3Lt3DwEBAZDL5ZgxYwbefPNN7Nu3D9OmTcOlS5ewdu1aLFiwAP7+/vD390daWhpyc3OxevVqCCGQ\nl5cHhUJhsmfRJVtW9oSEAKGhwNCh/MZPRPQ9qzaLLV26FBqNBtnZ2dBoNHjmmWegVCoBAOXl5cjI\nyMDBgweRlJSEmTNnQq1WY+/evdi4cSOCgoKQkZGBl19+Wf95+fn5yM/PR1ZWFry8vDBjxgzk5OTY\n3npbn9DFDV1ERAY8hDC1/VV66uvrMW3aNBQVFSEiIqK98Le/Nb3qJyKC4/xERDBz73yMcx8gl5Zm\n+nGNHOcnIrKK0yQBrVYLAIYb1MLDAYUCKC4GGhvbx/z//d/by+vr+6ilRETS0XHP7LiHduY0SaD5\n+4e2zJ07t+uKn3zSC60hInIuzc3NGDFihFG508wJPHjwABUVFQgODtbvLyAioq5ptVo0Nzdj/Pjx\n8PX1NbruNEmAiIgcj4+XJCJyY0wCRERujEmAiMiNMQkQEbkxJgEiIjcm2SSgVCqRm5trUPbJJ5/g\nJz/5CaKjo/Hcc8/hq6++MriuVquxZs0aTJkyBTExMcjKykJdXZ1Bnf379+NHP/oRJk2ahJdeegk1\nNTU9HYpZtsa4detWjB492uTPtm3b9PWkFCPQvb/Luro6vPLKK4iPj0dycjKWL1+Ob7/91qCOlOLs\nTow1NTX41a9+hfj4eEydOhVbtmyBRqMxqNPXMd6+fRu/+c1vkJycjPj4eCxcuBBVVVX662fPnoVC\nocDEiRPx05/+FMXFxQbvv3PnDpYsWYL4+HhMnjwZ69atk1yMgP1xdlCr1UhPT8enn35qdE0KcZok\nJEan04lNmzaJqKgokZOToy8vKCgQo0ePFjt27BDXr18Xhw8fFhMmTBB/+9vf9HXefvttMXXqVPH1\n11+LyspKMX/+fPGTn/xE6HQ6IYQQx44dEzExMeLUqVPiypUr4uWXXxbTpk0TbW1tThHj/fv3RVNT\nk8GPUqkUkydPFg0NDZKK0Z44Hz58KFJTU8WiRYvE1atXRWlpqUhNTRWvv/66/jOkEmd3Y/znP/8p\nnn76aTF//nxx8eJFceHCBZGamiqWLVsmmRi1Wq34+c9/Lp5//nnxzTffiOrqarF48WIxefJkoVKp\nRHV1tRg/frx4//33xdWrV8XGjRvFuHHjRFVVlf4zfvGLX4gXXnhBXL58Wfz5z38WTz31lNiwYYNk\nYnRUnEII8a9//UtkZmaKqKgo8cknnxhck0Kc5kgqCdTW1op58+aJpKQkkZKSYvA/VXp6unjrrbcM\n6ufm5op58+bp3xsVFSW+/vpr/fVr166JlJQUUVNTI4QQYvr06WLLli366/fv3xfR0dHiD3/4Q0+G\nZcCeGDsrKysTY8aMEcXFxfoyKcQohH1xVlZWiqioKHHlyhX99cOHD4uYmBj9aynEaU+M+/btEzEx\nMeLu3bv66yUlJSIqKkrU1dUJIfo+xosXL4qoqChx9epVfVlbW5uYNGmSOHnypMjLyzP6tzlv3jyx\nfPlyIUT7v8+oqChRW1urv37ixAkRExOjv/n1dYxC2B+nEEJ89dVXYtq0aeLZZ581mQSkEKc5khoO\nKisrQ3h4OAoKCoxOu7tx44b+ITQdfvjDH6K8vBwajQZnz55FYGAgJk+erL8+atQofPHFFxgxYgTu\n3LmDmpoaJCYm6q/7+/tj/PjxKCkp6dnAHmNPjI8TQmDVqlWYPn06pk6dCgCSiRGwL86AgADIZDIc\nO3YMbW1tUKlUOH36NMaPHw9AOnHaE+ONGzfw5JNPGjyFb+zYsQCAkpISScQYHh6OnTt3YuTIkfoy\nDw8PAMC9e/dQUlJi0D4ASEpK0revpKQEQ4cOxbBhw/TXExMT0dLSgsuXL0siRsD+OAHgf/7nfzBr\n1ix8/PHHRp8vlTjNkdTZQQqFQv/0ss5CQkJwq9PzA27evImHDx/i22+/RU1NDYYNG4aCggLs3r0b\nKpUKsbGxyMnJQVhYmP4Qpc4PrgkJCTE8lK6H2RNjYGCgvryoqAiXLl3C+vXr9WVSiRGwL87Q0FAs\nX74cv/vd7/DRRx9Bp9MhMjIShw8fBiCdOO2JMSQkBF988QV0Oh1kMpn+OtB+05BCjIMGDUJKSopB\n2aFDh/DgwQMkJydj8+bNXbavsbHR6JGxHa9v3bqlf2Z5X/892hsnACxfvtzs50vh77IrkuoJdCU9\nPR0ffvgh/vrXv0Kr1eJvf/sbjh8/DgB4+PAh7t+/j+vXr2Pfvn1YtmwZNm/ejDt37uDFF19EW1sb\nWltbAQA+Pj4GnyuXy9HW1tbr8ZhiKcbHHThwAKmpqQYHQjlDjIDlOHU6Hf7v//4PkydPxpEjR7B3\n7154enpi6dKl0Gq1ThGnpRjT0tJw584drFu3Dq2trbh9+zby8/Ph5eWFhw8fSjLGoqIibNiwAS+9\n9BIiIyPx4MEDyOVys+1rbW01ar+3tzc8PDwk/f+krXFaItU4O0iqJ9CVrKwsqFQq/OpXv4JWq8UP\nfvADLFy4EOvXr8eAAQPg5eWFf/3rX9i8ebO++7llyxYkJyejuLgYQ4YMAdA+e/84tVqNfv369Xo8\npliKsUNDQwPOnz+PAwcOGLy/43AoKccIWI7zD3/4AwoKCvDFF1/Az88PADBixAj8+Mc/RnFxsf7b\npJTjtBRjaGgoNm/eDKVSif3798PPzw+LFy9GZWUlBgwYILm/yxMnTiAvLw8zZ85EdnY2gPabWucv\nJ4+3z9fX16j9Dx8+hBACfn5+kosR6F6clkgxzsc5TU9ALpdDqVSirKwMX375JQoKCuDr64vBgwfD\nz88PoaGh8PPzMxh/DAoKwsCBA1FfX4/w8HAAj46k7tDU1GT7s417iKUYOxQVFSE4ONhonNIZYgQs\nx/nNN99g1KhRBjEPGzYMgwYNQm1trVPEac3f5X/8x3/g7NmzKC4uxl//+lf87Gc/g0qlwrBhwyQV\n4/bt27Fs2TLMmTMH7777rn74Kjw8HE1NTWbbFxYWZrL9QPvQiJRiBLofpyVSi7Mzp0kCGzduxK5d\nuyCXyxEcHAwAOHPmDKZMmQIAiI+Px3fffYdr167p39Pc3Iy7d+9i+PDhCAoKwr/927/h/Pnz+ust\nLS2oqKhAgkSeQGYpxg4dE1Ud/0g7OEOMgOU4w8LCUFNTY/DNqampCf/85z8xYsQIp4jTUowlJSV4\n8cUXodVqERISArlcjjNnzsDPzw+xsbGSiXH37t3YtGkTFi9ejLy8PP2EKQDExcXhwoULBvXPnTun\nnxCPi4tDXV2dwdzIuXPn4O/vjzFjxkgmRsC+OC2RUpwm9fXyJHPmzZtnsOTu2LFjIjY2Vvz5z38W\ntbW14p133hHR0dHi2rVrQoj29dovvPCCSE9PF2VlZeLy5cti/vz5IjU1Vb8c7aOPPhLR0dGisLBQ\nVFZWipdffllMnz69z9bq2hpjh+nTp4vt27eb/EypxSiE7XE2NDSI+Ph4sXjxYlFVVSW++eYbMWfO\nHDFr1izx8OFDIYT04rQ1xjt37oj4+HixZs0aUVtbKz7//HMRGxtr8Pfa1zFevnxZ/PCHPxTLli0z\n2p/S0tIirly5IsaNGyc2b94srl69KjZt2iQmTJigX2qp0+nE888/L37+85+LiooK/T6Bx5dK9nWM\njoizM1NLRKUQpzlOkwSEEOK9994TU6dOFdHR0WLevHnim2++Mbh+7949kZOTIxISEkR0dLRYtGiR\nuHXrlkGdHTt2iClTpojo6GixYMECgzXMva07MQohRExMjPjoo4/Mfq6UYhSie3FWVlaKhQsXioSE\nBDFlyhSRnZ0t7ty5Y1BHSnF2J8YLFy6I2bNni4kTJ4of//jHYt++fUaf25cxrl+/XkRFRZn8ee+9\n94QQQnzxxRdi5syZYvz48SI9PV189dVXBp/R1NQkFi1aJCZNmiSefvppsX79eqHVaiUToxCOifNx\nppKAEH0fpzl8qAwRkRtzmjkBIiJyPCYBIiI3xiRAROTGmASIiNwYkwARkRtjEiAicmNMAkREboxJ\ngIjIjf0/3Ll67goxmfAAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot(tables, 'ro', label = 'Population of Syria')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
SYR
Country Code
196048.441
196148.087
196247.729
196347.374
196447.034
196546.729
196646.482
196746.303
196846.192
196946.144
197046.147
197146.185
197246.231
197346.255
197446.236
197546.156
197646.002
197745.776
197845.476
197945.096
198044.627
198144.064
198243.414
198342.684
198441.885
198541.011
198640.057
198739.034
198837.969
198936.898
199035.878
199134.971
199234.211
199333.609
199433.160
199532.831
199632.566
199732.301
199831.984
199931.595
200031.133
200130.620
200230.095
200329.585
200429.095
200528.620
200628.148
200727.660
200827.139
200926.579
201025.963
201125.276
201224.526
201323.735
201422.930
201522.158
\n", + "
" + ], + "text/plain": [ + " SYR\n", + "Country Code \n", + "1960 48.441\n", + "1961 48.087\n", + "1962 47.729\n", + "1963 47.374\n", + "1964 47.034\n", + "1965 46.729\n", + "1966 46.482\n", + "1967 46.303\n", + "1968 46.192\n", + "1969 46.144\n", + "1970 46.147\n", + "1971 46.185\n", + "1972 46.231\n", + "1973 46.255\n", + "1974 46.236\n", + "1975 46.156\n", + "1976 46.002\n", + "1977 45.776\n", + "1978 45.476\n", + "1979 45.096\n", + "1980 44.627\n", + "1981 44.064\n", + "1982 43.414\n", + "1983 42.684\n", + "1984 41.885\n", + "1985 41.011\n", + "1986 40.057\n", + "1987 39.034\n", + "1988 37.969\n", + "1989 36.898\n", + "1990 35.878\n", + "1991 34.971\n", + "1992 34.211\n", + "1993 33.609\n", + "1994 33.160\n", + "1995 32.831\n", + "1996 32.566\n", + "1997 32.301\n", + "1998 31.984\n", + "1999 31.595\n", + "2000 31.133\n", + "2001 30.620\n", + "2002 30.095\n", + "2003 29.585\n", + "2004 29.095\n", + "2005 28.620\n", + "2006 28.148\n", + "2007 27.660\n", + "2008 27.139\n", + "2009 26.579\n", + "2010 25.963\n", + "2011 25.276\n", + "2012 24.526\n", + "2013 23.735\n", + "2014 22.930\n", + "2015 22.158" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "birth_filename = 'C:/Users/dberny/Desktop/birthrates1.csv'\n", + "birth_table = read_csv(birth_filename, header = 1, index_col=0, usecols=[0, 226], skiprows=[2,3])\n", + "birthrate = birth_table.SYR/1000\n", + "birth_table\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#birth_table" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
SYR
Country Code
196016.102
196115.583
196215.063
196314.543
196414.025
196513.509
196612.994
196712.481
196811.970
196911.464
197010.967
197110.484
197210.017
19739.568
19749.138
19758.730
19768.340
19777.966
19787.606
19797.260
19806.927
19816.608
19826.304
19836.015
19845.743
19855.489
19865.253
19875.038
19884.842
19894.665
19904.509
19914.372
19924.255
19934.153
19944.066
19953.991
19963.925
19973.867
19983.815
19993.767
20003.716
20013.651
20023.576
20033.497
20043.427
20053.396
20063.438
20073.572
20083.798
20094.103
20104.457
20114.818
20125.142
20135.391
20145.545
20155.589
\n", + "
" + ], + "text/plain": [ + " SYR\n", + "Country Code \n", + "1960 16.102\n", + "1961 15.583\n", + "1962 15.063\n", + "1963 14.543\n", + "1964 14.025\n", + "1965 13.509\n", + "1966 12.994\n", + "1967 12.481\n", + "1968 11.970\n", + "1969 11.464\n", + "1970 10.967\n", + "1971 10.484\n", + "1972 10.017\n", + "1973 9.568\n", + "1974 9.138\n", + "1975 8.730\n", + "1976 8.340\n", + "1977 7.966\n", + "1978 7.606\n", + "1979 7.260\n", + "1980 6.927\n", + "1981 6.608\n", + "1982 6.304\n", + "1983 6.015\n", + "1984 5.743\n", + "1985 5.489\n", + "1986 5.253\n", + "1987 5.038\n", + "1988 4.842\n", + "1989 4.665\n", + "1990 4.509\n", + "1991 4.372\n", + "1992 4.255\n", + "1993 4.153\n", + "1994 4.066\n", + "1995 3.991\n", + "1996 3.925\n", + "1997 3.867\n", + "1998 3.815\n", + "1999 3.767\n", + "2000 3.716\n", + "2001 3.651\n", + "2002 3.576\n", + "2003 3.497\n", + "2004 3.427\n", + "2005 3.396\n", + "2006 3.438\n", + "2007 3.572\n", + "2008 3.798\n", + "2009 4.103\n", + "2010 4.457\n", + "2011 4.818\n", + "2012 5.142\n", + "2013 5.391\n", + "2014 5.545\n", + "2015 5.589" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "death_filename = 'C:/Users/dberny/Desktop/deathrates1.csv'\n", + "death_table = read_csv(death_filename, header = 1, index_col=0, usecols=[0, 226], skiprows=[2,3])\n", + "deathrate = death_table.SYR/1000\n", + "death_table\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#death_table\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "system = System(t0=1960, t_end=2015, p0=4573512, birthrate = birthrate, deathrate = deathrate)\n", + "def run_simulation(system):\n", + " model = TimeSeries()\n", + " model[1960]=4573512\n", + " for t in range(system.t0, system.t_end):\n", + " rate_birth = system.birthrate[t]\n", + " births = model[t]*rate_birth\n", + " deaths = model[t]*system.deathrate[t]\n", + " model[t+1] = model[t] + births - deaths\n", + " system.model = model\n", + " return model\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n0NbWxueff46bN28iNjYWc+fOxY0bN2BqagptbW0EBATgq6++Qnx8POLj4xEQEAAjIyOhF5qIiIga\nHqlUioSEBPz+++949uyZ0N60aVO89957aNq0qRyjq/9YGt1AiMVi9O/fH0eOHBGW83lZr1694O3t\njZ07d+Kbb75B06ZN4e7ujunTpwMoThD27t2Lr7/+GiNGjECbNm0wdepUmbGfq1atwsaNG7F48WJk\nZmbCxMREmF23Ktq1a4cDBw7Az89PWIanefPmGDRoED799FPhuBkzZiAnJwfLly9HWloaDAwMMHv2\nbIwYMeK13o+fnx+WL18OV1dXaGpqYtq0aYiKiqq0PLiwsBCOjo7CtpqaGtq2bYs1a9bggw8+qPK9\np06dim3btgk99tXl7e2NFStWYMSIEWjcuDG6dOmCuXPnYseOHcjOzq7SNTZs2IA1a9bg008/hVgs\nxtSpU6s0a3bJ+xaJRNDV1RWWhypZYggAPv74Y+Tl5WHPnj1YuXIlmjVrBg8PD0ybNg0A8Nlnn+Gf\nf/7B5MmToaCgADMzM6xduxaenp64efMmOnfujAkTJmDVqlUIDg7G1atXq/2OKjNjxgxcuHABX331\nFc6ePfvK96mhoQE3Nzds2LAB165dw9atW/H9999j7dq1GD9+vLC0wb59+6CrqwuguJd5/fr1GDNm\nDIqKitClSxd8++23VfqwgYiIiOqf/Px83LhxA8nJyUKbWCyGubk52rRpwwmx6oBIWp0aznokMTER\nffr0QWBgIAwNDeUdDsmRRCJBZGQkevXqJZSepKamwtHREQcOHKhwrC8RERER0esoLCzE77//LgzF\n09TUhJ2dHRo3biznyOqPV+V77I6gBk9BQQFz5szBli1b8OjRI8TExGDZsmVo3br1a5VaExERERFV\nRkFBAXZ2dhCLxTA2NkavXr2YBNexOk+E09LSsGDBAjg6OqJz586YPHmyzHqnLzt//jyGDRsGGxsb\n9O3bF99++60wkzEABAUFCTM5l/568uRJXTwO1QNaWlrYsWMHQkJCMHToULi5uUFRURHffffda8+c\nTERERERUIicnp8xEpo0bN4azszMsLCw4IZYc1OkY4aKiIsyaNQtSqRTbtm1Do0aN4OvriwkTJuDc\nuXNlJo4JCgrCF198gcWLF8PJyQnR0dHw8vJCfn6+MF70zp07MDc3x7fffitzbsnYPKKq6N69e5XH\n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\nAgC65FYQTktL09dff63Zs2d3OFZcXHzuuzoCAIBBqa2tTTt27FBVVZVmz56tyMhI5zGDwaBRo0ad\n/STMAgYAeIlbQfjuu+/WAw88oObmZl1xxRUaMWKEjh07pg0bNuiNN97QI488ooKCAuf7c3JyvNYw\nAADov+x2uyoqKlRSUqITJ05IkgoLCzVnzpzuPf/LLGAAgBe5FYSXLFkiSfrd736n9957z1lvH3r/\n2GOPOV8bDAaVlJR4uE0AANDfNTY2qrCwUHV1dS718PBwWa1W+fm5PayCWcAAAK9y6zvSO++84+0+\nAADAAGW1WrV7926VlZU5f0kuSaGhocrKylJsbGz3T8osYACAF7kVhGfMmOHtPgAAwABUU1Oj7du3\nq7m52VkzGAwaP368JkyYIF9f33M7MbOAAQBe1I01SgAAACft3r1bO3fudKlFRUUpOztb4eHhPTu5\n0ej6jHA7ZgEDADygT4PwihUrZLVa9eSTT3b5ns8++0yvvvqq9u/fr9jYWF133XX6z//8T+dvmDdu\n3Kjbbrutw+c2btyouLg4r/UOAMBQFxcXp9LSUtntdvn7+ys9PV0pKSnd2xSrK8wCBgB4UZ8EYbvd\nrhdeeEEffPCBrr322i7ft3HjRj344INatmyZLrjgAhUXF2v58uU6ceKE7rzzTklSaWmpMjIytGrV\nKpfPRkdHe/XPAADAUBceHq7x48fr+PHjyszMVGBgoGcvwCxgAICX9HoQPnDggJYtW6bdu3cr4SzP\n+bz//vu69NJLdcMNN0iSUlJStGfPHn300UfOILx7926lpqae20YcAADgrKxWq8rKyhQQEKAxY8a4\nHJs4caJn7gADANCLPBKE9+/fr1GjRrn13oKCAsXHx+v555/Xj370ozO+94c//KFCQkJcaj4+Pmpo\naHC+3r17ty6//PLuNw0AAM7qyJEjKiwsVHNzs/z8/BQXF6fg4GDn8bOG4Px8xygkk8mxAZbRyF1e\nAECfcysINzY26le/+pXy8/NlNpuddZvNppaWFtXW1ro9O3jBggVasGCBW+/Nzs52ed3U1KT33ntP\nc+bMkeT4DXV5ebmKiop05ZVXqq6uTllZWXrooYc0duxYt64BAAA6amtrU3FxsQ4ePOisWSwW7du3\nT+np6e6dJD/fdcOrysqTrwnDAIA+5OPOm5566il9+OGHSkpKkiQFBwcrPT1dra2tqqur089+9jOv\n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\n//33hxoZSdLZZ5+trVu3hu2/efPmUKO2s88+W0VFRWHz1Tdv3qy4uDhNmjSJOoOk46ux3lBjQwtB\nuBfp6el69tlntWnTJhUVFWnlypX6/PPPdcstt0iSZsyYoenTp+vOO+/Ujh07tGfPHt11110aO3Zs\nqKvvddddp3Xr1ulPf/qT8vPzdddddyk1NVUXXnjhQN4aBoneaqzTF198oaysrB7PQY3h2/RWY5de\neql8Pp9ycnK0b98+/fOf/9SyZct02mmn6dxzz5VEjeHb9VZj48aN0xdffKFHHnlERUVF+stf/qL/\n/M//1M0336z4+HhJ1BikPXv2aPXq1frRj36kK664QlVVVaGPlpYWXX311dq2bZsef/xxffXVV1q7\ndq127typa6+9VpI0bdo0TZ06VXfccYd2796tTZs26eGHH9b1118fmvdJnQ1vx1tjR4MaGzqYI9yL\nyy+/XFVVVcrNzdWhQ4c0efJkrV+/XuPGjZMUbLn+9NNP66GHHtLNN9+s9vZ2zZ49W6tWrQp90/3J\nT36iQ4cO6b//+7/V3Nys7OxsPf/8890m42N46q3GOlVVVSkhIaHHc1Bj+Da91ZjL5dIrr7yiVatW\n6aqrrpLdbtfs2bN19913h7qsUmP4Nr3VWHJycuhn5auvvqrU1FTddtttuu6660LnoMbw5z//WX6/\nX6+//nqo2VqnZcuW6dZbb9WTTz6phx9+WOvWrdO4ceP0zDPPaPz48ZKCv5M9+eST+uUvf6mrrrpK\ncXFxuvzyy/Wzn/0sdB7qbHg73ho7GtTY0GExxpiBvggAAAAAAPoLr0YDAAAAAIYVgjAAAAAAYFgh\nCAMAAAAAhhWCMAAAAABgWCEIAwAAAACGFYIwAAAAAGBYIQgDADDI5ebmauLEidq0aVOP43l5eZo4\ncaKeeuqpfr4yAACGJtYRBgBgkGtqatLFF18si8Wid955R3FxcaGxxsZGXXTRRUpLS9Pvf/97RURE\nDOCVAgAwNPBEGACAQS4+Pl6/+tWvVFpaqtWrV4eNrVq1Sg0NDXrwwQcJwQAAHCWCMAAAQ8C8efN0\n2WWX6ZVXXtHOnTslSVu3btVrr72mO++8U+PHjw/tu2HDBi1atEiTJ0/WggULtG7dOn3zBbBXX31V\nl112mc466yydeeaZ+uEPf6i//OUvofHXXntN06ZN0yuvvKJZs2bpnHPOUXFxcf/cLAAAfYxXowEA\nGCIaGhr0/e9/X2lpaXr11Vf1wx/+UElJSXrppZdksVgkSb/5zW/05JNP6rrrrtOcOXO0c+dOPfXU\nU7ruuuuUk5MjSXrhhRf0yCOPaNmyZTrrrLNUX1+v5557Tvn5+crLy1Nqaqpee+015ebmavz48crJ\nyVFdXZ0uvfTSgbx9AABOGNtAXwAAADg6CQkJ+uUvf6mf/exnuuGGG1RaWqpnnnkmFIIbGhr07LPP\n6pprrtEvfvELSdLcuXMVExOjRx99VEuWLJHL5VJJSYluuukmLV26NHRut9utyy+/XDt37tSFF14o\nSQoEAvqP//gPfec73+n/mwUAoA/xajQAAEPIBRdcoO9///vaunWr7r77bqWnp4fGtm/fLo/Ho/PO\nO08+ny/0cf7558vn8+mTTz6RJK1YsULLly9XQ0ODPvvsM7399tvasGGDJKm9vT3s3zvttNP67+YA\nAOgnPBEGAGCImTt3rv70pz9p3rx5Ydvr6+slSdddd12Px1VWVkqSCgoKlJubq82bN8tut2vcuHE6\n9dRTJanbXOLY2NgTfPUAAAw8gjAAACeJESNGSJLWrl2rUaNGdRt3uVzy+/1aunSp4uPj9cYbb2ji\nxImy2Wzas2ePNm7c2N+XDADAgODVaAAAThJTp05VZGSkqqurNWXKlNCHx+PRmjVrVF1drerqah08\neFBXXHGFzjjjDNlswb+Jf/jhh5KC84IBADjZ8UQYAICTREpKipYsWaJHHnlEDQ0Nys7OVklJiVav\nXq3ExERNmDBBkZGRcrvdWr9+vRwOh+Lj4/Xhhx/qd7/7nSSptbV1gO8CAIC+xxNhAABOIjk5OVq+\nfLk2btyom266SWvWrNH8+fO1fv162e12WSwWPfXUU3I4HPr5z3+u5cuX6/PPP9ezzz6rzMxMbdu2\nbaBvAQCAPsc6wgAAAACAYYUnwgAAAACAYYUgDAAAAAAYVgjCAAAAAIBhhSAMAAAAABhWCMIAAAAA\ngGGFIAwAAAAAGFYIwgAAAACAYYUgDAAAAAAYVgjCAAAAAIBh5f8DW7RIuzbBtcUAAAAASUVORK5C\nYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "simulation = run_simulation(system)\n", + "newfig()\n", + "plot(tables, 'ro', label = 'Population of Syria') \n", + "plot(simulation, '--', color='gray', label='Model Using Birth and Death Rates')\n", + "decorate(xlabel='Year', ylabel='Syria population (1e7)', title='Population Growth in Syria', )\n", + "plt.rcParams[\"figure.figsize\"] = [16,9]\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/code/Project1.ipynb b/code/Project1.ipynb new file mode 100644 index 00000000..387df96b --- /dev/null +++ b/code/Project1.ipynb @@ -0,0 +1,76 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'xlrd'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mpandas\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mpd\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mmatplotlib\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpyplot\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[1;32mimport\u001b[0m \u001b[0mxlrd\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 5\u001b[0m \u001b[0mget_ipython\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmagic\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'matplotlib inline'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mmath\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'xlrd'" + ] + } + ], + "source": [ + "# import numpy as np\n", + "# import pandas as pd\n", + "# import matplotlib.pyplot as plt\n", + "# import xlrd\n", + "# %matplotlib inline\n", + "# import math\n", + "# from modsim import *" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# import csv\n", + "# with open('popdata.csv', newline='') as csvfile:\n", + "# spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')\n", + "# for row in spamreader:\n", + "# print(', '.join(row))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/code/chap01_fig01.pdf b/code/chap01_fig01.pdf new file mode 100644 index 00000000..b32f1498 Binary files /dev/null and b/code/chap01_fig01.pdf differ diff --git a/code/chap01mine.ipynb b/code/chap01mine.ipynb new file mode 100644 index 00000000..b5511d95 --- /dev/null +++ b/code/chap01mine.ipynb @@ -0,0 +1,2584 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Modeling and Simulation in Python\n", + "\n", + "Chapter 1: Modeling\n", + "\n", + "Copyright 2017 Allen Downey\n", + "\n", + "License: [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Jupyter\n", + "\n", + "Welcome to Modeling and Simulation, welcome to Python, and welcome to Jupyter.\n", + "\n", + "This is a Jupyter notebook, which is a development environment where you can write and run Python code. Each notebook is divided into cells. Each cell contains either text (like this cell) or Python code (like the cell below this one).\n", + "\n", + "### Selecting and running cells\n", + "\n", + "To select a cell, click in the left margin next to the cell. You should see a blue frame surrounding the selected cell.\n", + "\n", + "To edit a code cell, click inside the cell. You should see a green frame around the selected cell, and you should see a cursor inside the cell.\n", + "\n", + "To edit a text cell, double-click inside the cell. Again, you should see a green frame around the selected cell, and you should see a cursor inside the cell.\n", + "\n", + "To run a cell, hold down SHIFT and press ENTER. If you run a text cell, it will typeset the text and display the result.\n", + "\n", + "If you run a code cell, it runs the Python code in the cell and displays the result, if any wowoowwoowwowowwoow.\n", + "\n", + "To try it out, edit this cell, change some of the text, and then press SHIFT-ENTER to run it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Adding and removing cells\n", + "\n", + "You can add and remove cells from a notebook using the buttons in the toolbar and the items in the menu, both of which you should see at the top of this notebook.\n", + "\n", + "You might want to try the following exercises:\n", + "\n", + "1. From the Insert menu select \"Insert cell below\" to add a cell below this one. By default, you get a code cell, and you can see in the pulldown menu that says \"Code\".\n", + "\n", + "2. In the new cell, add a print statement like `print('Hello')`, and run it.\n", + "\n", + "3. Add another cell, select the new cell, and then click on the pulldown menu that says \"Code\" and select \"Markdown\". This makes the new cell a text cell.\n", + "\n", + "4. In the new cell, type some text, and then run it.\n", + "\n", + "5. Use the arrow buttons in the toolbar to move cells up and down.\n", + "\n", + "6. Use the cut, copy, and paste buttons to delete, add, and move cells.\n", + "\n", + "7. As you make changes, Jupyter saves your notebook automatically, but if you want to make sure, you can press the save button, which looks like a floppy disk from the 1990s.\n", + "\n", + "8. Finally, when you are done with a notebook, selection \"Close and Halt\" from the File menu." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello\n" + ] + } + ], + "source": [ + "print('Hello')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "this is a text cell" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using the notebooks\n", + "\n", + "The notebooks for each chapter contain the code from the chapter along with addition examples, explanatory text, and exercises. I recommend you read the chapter first to understand the concepts and vocabulary, then run the notebook to review what you learned and see it in action, and then attempt the exercises.\n", + "\n", + "The notebooks contain some explanatory text, but it is probably not enough to make sense if you have not read the book. If you are working through a notebook and you get stuck, you might want to re-read (or read!) the corresponding section of the book.\n", + "\n", + "If you try to work through the notebooks without reading the book, you're gonna have a bad time. If you have previous programming experience, you might get through the first few notebooks, but sooner or later, you will get to the end of your leash, and you won't like it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Importing modsim\n", + "\n", + "The following cell imports `modsim`, which is a collection of functions we will use throughout the book. Whenever you start the notebook, you will have to run the following cell. It does two things:\n", + "\n", + "1. It uses a Jupyter \"magic command\" to specify whether figures should appear in the notebook, or pop up in a new window.\n", + "\n", + "2. It imports everything defined in `modsim`.\n", + "\n", + "Select the following cell and press SHIFT-ENTER to run it." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "If this cell runs successfully, it produces no output other than this message.\n" + ] + } + ], + "source": [ + "# If you want the figures to appear in the notebook, \n", + "# and you want to interact with them, use\n", + "# %matplotlib notebook\n", + "\n", + "# If you want the figures to appear in the notebook, \n", + "# and you don't want to interact with them, use\n", + "# %matplotlib inline\n", + "\n", + "# If you want the figures to appear in separate windows, use\n", + "# %matplotlib qt5\n", + "\n", + "# To switch from one to another, you have to select Kernel->Restart\n", + "\n", + "%matplotlib notebook\n", + "\n", + "from modsim import *\n", + "\n", + "print('If this cell runs successfully, it produces no output other than this message.')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The penny myth\n", + "\n", + "The following cells contain code from the beginning of Chapter 1.\n", + "\n", + "`modsim` defines `UNITS`, which contains variables representing pretty much every unit you've ever heard of. The following to lines create new variables named `meter` and `second`." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "meter = UNITS.meter\n", + "second = UNITS.second" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To find out what units are defined, type `UNITS.` in the next cell and then press TAB. You should see a pop-up menu with a list of units." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (, line 1)", + "output_type": "error", + "traceback": [ + "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m UNITS.\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" + ] + } + ], + "source": [ + "UNITS." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a variable named `a` and display its value:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "9.8 meter/second2" + ], + "text/latex": [ + "$9.8 \\frac{meter}{second^{2}}$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a = 9.8 * meter / second**2\n", + "a" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Create `t` and display its value:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "4 second" + ], + "text/latex": [ + "$4 second$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "t = 4 * second\n", + "t" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "If you create a variable and don't display the value, you don't get any output:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "156.8 meter" + ], + "text/latex": [ + "$156.8 meter$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h = a * t**2\n", + "h" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Add a second line to the previous cell to display the value of `h`.\n", + "\n", + "Now let's solve the falling penny problem. The following lines set `h` to the height of the Empire State Building and compute the time it would take a penny to fall, assuming constant acceleration." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "8.817885349720552 second" + ], + "text/latex": [ + "$8.817885349720552 second$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h = 381 * meter\n", + "t = sqrt(2 * h / a)\n", + "t" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Given `t`, we can compute the velocity of the penny when it lands." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "86.41527642726142 meter/second" + ], + "text/latex": [ + "$86.41527642726142 \\frac{meter}{second}$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v = a * t\n", + "v" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "We can convert from one set of units to another like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "mile = UNITS.mile\n", + "hour= UNITS.hour" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "193.30546802805438 mile/hour" + ], + "text/latex": [ + "$193.30546802805438 \\frac{mile}{hour}$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v.to(mile/hour)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** In reality, air resistance prevents the penny from reaching this velocity. At about 20 meters per second, the force of air resistance equals the force of gravity and the penny stops accelerating.\n", + "\n", + "As a simplification, let's assume that the acceleration of the penny is `a` until the penny reaches 20 meters per second, and then 0 afterwards. What is the total time for the penny to fall 381 meters?" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "20.070408163265306 second" + ], + "text/latex": [ + "$20.070408163265306 second$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Solution goes here\n", + "meter = UNITS.meter\n", + "second = UNITS.second\n", + "\n", + "a = 9.8 * meter / second**2\n", + "h = 381 * meter\n", + "v = 20 * meter / second\n", + "\n", + "t = v/a\n", + "\n", + "fall1 = a*(t**2)/2\n", + "h = h - fall1\n", + "\n", + "answer = (h / v) + t\n", + "answer" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Modeling a bikeshare system" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We'll start with a `System` object that represents the number of bikes at each station." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "bikeshare = System(olin=10, wellesley=2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you display the value of a `System` object, it lists the system variables and their values (not necessarily in the order you defined them):" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value
olin10
wellesley2
\n", + "
" + ], + "text/plain": [ + "olin 10\n", + "wellesley 2\n", + "dtype: int64" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can access the system variables using dot notation." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare.olin" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare.wellesley" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** What happens if you spell the name of a system variable wrong? Edit the previous cell, change the spelling of `wellesley`, and run the cell again.\n", + "\n", + "The error message uses the word \"attribute\", which is another name for what we are calling a system variable. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Add a third attribute called `babson` with initial value 0, and print the state of `bikeshare` again." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plotting\n", + "\n", + "`newfig` creates a new figure, which should appear either in the notebook or in a new window, depending on which magic command you ran in the first code cell.\n", + "\n", + "`plot` adds a data point to the figure; in this example, you should see a red square and a blue circle representing the number of bikes at each station." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "IOPub data rate exceeded.\n", + "The notebook server will temporarily stop sending output\n", + "to the client in order to avoid crashing it.\n", + "To change this limit, set the config variable\n", + "`--NotebookApp.iopub_data_rate_limit`.\n" + ] + } + ], + "source": [ + "bikeshare = System(olin=10, wellesley=2)\n", + "newfig()\n", + "plot_system(bikeshare)\n", + "decorate_bikeshare()\n", + "run_steps(bikeshare, 60, 0.4, 0.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But this is relatively easy to fix, using the `return` statement to exit the function early if the update would cause negative bikes.\n", + "\n", + "If the second `if` statement seems confusing, remember that `n` can be negative." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def move_bike(system, n):\n", + " # make sure the number of bikes won't go negative\n", + " olin_temp = system.olin - n\n", + " if olin_temp < 0:\n", + " #print('No more bikes at Olin!')\n", + " return\n", + " \n", + " wellesley_temp = system.wellesley + n\n", + " if wellesley_temp < 0:\n", + " #print('No more bikes at Wellesley!')\n", + " return\n", + " \n", + " # update the system\n", + " system.olin = olin_temp\n", + " system.wellesley = wellesley_temp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now if you run the simulation again, it should behave." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "newfig()\n", + "plot_system(bikeshare)\n", + "decorate_bikeshare()\n", + "run_steps(bikeshare, 40, 0.4, 0.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After the simulation, we can print the number of unhappy customers at each location." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare.olin_empty" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare.wellesley_empty" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Let's add a \"clock\" to keep track of how many time steps have elapsed:\n", + "\n", + "1. Add a new system variable named `clock` to `bikeshare`, initialized to 0, and \n", + "\n", + "2. Modify `step` so it increments (adds one to) `clock` each time it is invoked.\n", + "\n", + "Test your code by adding a print statement that prints the value of `clock` at the beginning of each time step." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Here's a copy of step to get you started\n", + "\n", + "def step(system, p1=0.5, p2=0.5):\n", + " \"\"\"Simulate one minute of time.\n", + " \n", + " system: bikeshare System object\n", + " p1: probability of an Olin->Wellesley customer arrival\n", + " p2: probability of a Wellesley->Olin customer arrival\n", + " \"\"\"\n", + " #print(system.clock)\n", + " system.clock+=1\n", + " \n", + " if flip(p1):\n", + " bike_to_wellesley(system)\n", + " \n", + " if flip(p2):\n", + " bike_to_olin(system)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here\n", + "bikeshare = System(olin = 10, wellesley = 2, olin_empty=0, wellesley_empty=0, clock = 0)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here\n", + "run_steps(bikeshare, 20, .5, .5)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After the simulation, check the final value of `clock`." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "20\n" + ] + } + ], + "source": [ + " print(bikeshare.clock)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Now suppose we'd like to know how long it takes to run out of bikes at either location. Modify `move_bike` so the first time a student arrives at Olin and doesn't find a bike, it records the value of `clock` in a system variable.\n", + "\n", + "Hint: create a system variable named `t_first_empty` and initialize it to `-1` to indicate that it has not been set yet.\n", + "\n", + "Test your code by running a simulation for 60 minutes and checking the metrics." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here\n", + "bikeshare = System(olin = 10, wellesley = 2, olin_empty=0, wellesley_empty=0, clock = 0, t_first_empty = -1)\n", + "\n", + "def move_bike(system, n):\n", + " olin_temp = system.olin - n\n", + " if olin_temp < 0:\n", + " system.olin_empty += 1\n", + " if system.t_first_empty < 0:\n", + " system.t_first_empty = system.clock\n", + " return\n", + " \n", + " wellesley_temp = system.wellesley + n\n", + " if wellesley_temp < 0:\n", + " system.wellesley_empty += 1\n", + " return\n", + " \n", + " system.olin = olin_temp\n", + " system.wellesley = wellesley_temp" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here\n", + "run_steps(bikeshare, 15, 1, 0)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After the simulation, check the final value of `t_first_empty`." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "11\n" + ] + } + ], + "source": [ + " print(bikeshare.t_first_empty)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Before we go on, let's put `step` and `move_bike` back the way we found them, so they don't break the examples below." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def step(system, p1=0.5, p2=0.5):\n", + " if flip(p1):\n", + " bike_to_wellesley(system)\n", + " \n", + " if flip(p2):\n", + " bike_to_olin(system)\n", + "\n", + "def move_bike(system, n):\n", + " olin_temp = system.olin - n\n", + " if olin_temp < 0:\n", + " system.olin_empty += 1\n", + " return\n", + " \n", + " wellesley_temp = system.wellesley + n\n", + " if wellesley_temp < 0:\n", + " system.wellesley_empty += 1\n", + " return\n", + " \n", + " system.olin = olin_temp\n", + " system.wellesley = wellesley_temp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Returning values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here's a simple function that returns a value:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def add_five(x):\n", + " return x + 5" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And here's how we call it." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y = add_five(3)\n", + "y" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you run a function on the last line of a cell, Jupyter displays the result:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "add_five(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "But that can be a bad habit, because usually if you call a function and don't assign the result in a variable, the result gets discarded.\n", + "\n", + "In the following example, Jupyter shows the second result, but the first result just disappears." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "add_five(3)\n", + "add_five(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "When you call a function that returns a variable, it is generally a good idea to assign the result to a variable." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8 10\n" + ] + } + ], + "source": [ + "y1 = add_five(3)\n", + "y2 = add_five(5)\n", + "\n", + "print(y1, y2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Write a function called `make_system` that creates a `System` object with the system variables `olin=10` and `wellesley=2`, and then returns the new `System` object.\n", + "\n", + "Write a line of code that calls `make_system` and assigns the result to a variable." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here\n", + "def make_system():\n", + " system = System(olin = 10, wellesley = 2)\n", + " return system" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here\n", + "newSystem = make_system" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Running simulations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Before we go on, I want to update `run_steps` so it doesn't always plot the results. The new version takes an additional parameter, `plot_flag`, to indicate whether we want to plot.\n", + "\n", + "\"flag\" is a conventional name for a boolean variable that indicates whether or not a condition is true.\n", + "\n", + "This version of `run_steps` works even if `num_steps` is not an integer. It uses the `int` function to round down. See https://docs.python.org/3/library/functions.html#int" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run_steps(system, num_steps=1, p1=0.5, p2=0.5, plot_flag=True):\n", + " \"\"\"Simulate the given number of time steps.\n", + " \n", + " `num_steps` should be an integer; if not, it gets rounded down.\n", + " \n", + " system: bikeshare System object\n", + " num_steps: number of time steps\n", + " p1: probability of an Olin->Wellesley customer arrival\n", + " p2: probability of a Wellesley->Olin customer arrival\n", + " plot_flag: boolean, whether to plot\n", + " \"\"\"\n", + " for i in range(int(num_steps)):\n", + " step(system, p1, p2)\n", + " if plot_flag:\n", + " plot_system(system)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now when we run a simulation, we can choose not to plot the results:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "bikeshare = System(olin=10, wellesley=2, \n", + " olin_empty=0, wellesley_empty=0)\n", + "run_steps(bikeshare, 60, 0.4, 0.2, plot_flag=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But after the simulation, we can still read the metrics." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bikeshare.olin_empty" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's wrap all that in a function." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run_simulation():\n", + " system = System(olin=10, wellesley=2, \n", + " olin_empty=0, wellesley_empty=0)\n", + " run_steps(system, 60, 0.4, 0.2, plot_flag=False)\n", + " return system" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And test it." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "system = run_simulation()" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 3\n" + ] + } + ], + "source": [ + "print(system.olin_empty, system.wellesley_empty)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we generalize `run_simulation` to take `p1` and `p2`, we can use it to run simulations with a range of values for the parameters." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run_simulation(p1=0.4, p2=0.2):\n", + " bikeshare = System(olin=10, wellesley=2, \n", + " olin_empty=0, wellesley_empty=0)\n", + " run_steps(bikeshare, 60, p1, p2, plot_flag=False)\n", + " return bikeshare" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When `p1` is small, we probably don't run out of bikes at Olin." + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "system = run_simulation(p1=0.2)\n", + "system.olin_empty" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When `p1` is large, we probably do." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "11" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "system = run_simulation(p1=0.6)\n", + "system.olin_empty" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "**Exercise:** Write a version of `run_simulation` that takes all five model parameters as function parameters." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here\n", + "def run_simulation(numSteps = 60, p1 = 0.4, p2 = 0.2, plot = False):\n", + " bikeshare = System(olin=10, wellesley=2, \n", + " olin_empty=0, wellesley_empty=0)\n", + " run_steps(bikeshare, numSteps, p1, p2, plot)\n", + " return bikeshare" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## More for loops" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`linspace` creates a NumPy array of equally spaced numbers." + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0. , 0.25, 0.5 , 0.75, 1. ])" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "p1_array = linspace(start=0, stop=1, num=5)\n", + "p1_array" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can use an array in a `for` loop, like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0\n", + "0.25\n", + "0.5\n", + "0.75\n", + "1.0\n" + ] + } + ], + "source": [ + "for p1 in p1_array:\n", + " print(p1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This will come in handy in the next section." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** The function `linspace` is part of NumPy. [You can read the documentation here](https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html).\n", + "\n", + "Use `linspace` to make an array of 10 equally spaced numbers from 1 to 10 (including both)." + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** The `modsim` library provides a related function called `linrange`. You can view the documentation by running the following cell:" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on function linrange in module modsim:\n", + "\n", + "linrange(start=0, stop=None, step=1, **kwargs)\n", + " Returns an array of evenly-spaced values in the interval [start, stop].\n", + " \n", + " This function works best if the space between start and stop\n", + " is divisible by step; otherwise the results might be surprising.\n", + " \n", + " By default, the last value in the array is `stop` (at least approximately).\n", + " If you provide the keyword argument `endpoint=False`, the last value\n", + " in the array is `stop-step`. \n", + " \n", + " start: first value\n", + " stop: last value\n", + " step: space between values\n", + " \n", + " Also accepts the same keyword arguments as np.linspace. See\n", + " https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html\n", + " \n", + " returns: array or Quantity\n", + "\n" + ] + } + ], + "source": [ + "help(linrange)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Use `linrange` to make an array of numbers from 1 to 11 with a step size of 2." + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1., 3., 5., 7., 9., 11.])" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Solution goes here\n", + "new_array = linspace(start = 1, stop = 11, num = 6)\n", + "new_array" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## Sweeping parameters" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following example runs simulations with a range of values for `p1`; after each simulation, it prints the number of unhappy customers at the Olin station:" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "p1_array = linspace(0, 1, 11)\n", + "p1_array" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0 0\n", + "0.1 0\n", + "0.2 0\n", + "0.3 2\n", + "0.4 2\n", + "0.5 25\n", + "0.6 7\n", + "0.7 28\n", + "0.8 29\n", + "0.9 34\n", + "1.0 37\n" + ] + } + ], + "source": [ + "for p1 in p1_array:\n", + " system = run_simulation(p1=p1)\n", + " print(p1, system.olin_empty)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can do the same thing, but plotting the results instead of printing them.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Solution goes here\n", + "def parameter_sweep(p1_array):\n", + " newfig()\n", + " for p1 in p1_array:\n", + " system = run_simulation(p1=p1)\n", + " plot(p1, system.olin_empty, 'rs', label='olin')\n", + "parameter_sweep(p1_array)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "illegal target for annotation (, line 2)", + "output_type": "error", + "traceback": [ + "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m Markdown and LaTeX: α**2\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m illegal target for annotation\n" + ] + } + ], + "source": [ + "# Solution goes here\n", + "Markdown and LaTeX: α**2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "**Exercise:** Write a function called `parameter_sweep2` that runs simulations with `p1=0.2` and a range of values for `p2`.\n", + "\n", + "Note: If you run `parameter_sweep2` a few times without calling `newfig`, you can plot multiple runs on the same axes, which will give you a sense of how much random variation there is from one run to the next. " + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Solution goes here\n", + "array_steps = range(1,35)\n", + "def parameter_sweep3(array_steps):\n", + " newfig()\n", + " for num in array_steps:\n", + " system = run_simulation(p1 = 0.8, p2 = 0.3, numSteps = num)\n", + " plot(num, system.olin_empty, 'rs', label='olin')\n", + "parameter_sweep3(array_steps)" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": { + "collapsed": true, + "scrolled": false + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "**Exercise:** The code below runs a simulation with the same parameters 10 times and computes the average number of unhappy customers.\n", + "\n", + "1. Wrap this code in a function called `run_simulations` that takes `num_runs` as a parameter.\n", + "\n", + "2. Test `run_simulations`, and increase `num_runs` until the results are reasonably consistent from one run to the next.\n", + "\n", + "3. Generalize `run_simulations` so it also takes the initial value of `olin` as a parameter.\n", + "\n", + "4. Run the generalized version with `olin=12`. How much do the two extra bikes decrease the average number of unhappy customers.\n", + "\n", + "5. Make a plot that shows the average number of unhappy customers as a function of the initial number of bikes at Olin." + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5.2000000000000002" + ] + }, + "execution_count": 117, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "num_runs = 10\n", + "total = 0\n", + "for i in range(num_runs):\n", + " system = run_simulation(p1=0.4, p2=0.2, numSteps=70)\n", + " total += system.olin_empty + system.wellesley_empty\n", + "total / num_runs" + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here\n", + "def run_simulations(num_runs):\n", + " total = 0\n", + " for i in range(num_runs):\n", + " system = run_simulation(p1=0.4, p2=0.2, numSteps=70)\n", + " total += system.olin_empty + system.wellesley_empty\n", + " return (total / num_runs)" + ] + }, + { + "cell_type": "code", + "execution_count": 199, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5.8499999999999996" + ] + }, + "execution_count": 199, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Solution goes here\n", + "run_simulations(40)" + ] + }, + { + "cell_type": "code", + "execution_count": 201, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Solution goes here\n", + "def run_simulation(numSteps = 60, p1 = 0.4, p2 = 0.2, plot = False, olin = 10):\n", + " bikeshare = System(olin=olin, wellesley=2, \n", + " olin_empty=0, wellesley_empty=0)\n", + " run_steps(bikeshare, numSteps, p1, p2, plot)\n", + " return bikeshare\n", + "\n", + "def run_simulations(num_runs, olin):\n", + " total = 0\n", + " for i in range(num_runs):\n", + " system = run_simulation(p1=0.4, p2=0.2, numSteps=70, olin = olin)\n", + " total += system.olin_empty + system.wellesley_empty\n", + " return (total / num_runs)" + ] + }, + { + "cell_type": "code", + "execution_count": 215, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "4.4000000000000004" + ] + }, + "execution_count": 215, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Solution goes here\n", + "run_simulations(40, 12)" + ] + }, + { + "cell_type": "code", + "execution_count": 219, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure to file chap09-fig01.pdf\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure to file chap09-fig02.pdf\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure to file chap10-fig01.pdf\n" + ] + } + ], + "source": [ + "newfig()\n", + "plot(xs, label='x')\n", + "plot(ys, label='y')\n", + "\n", + "decorate(xlabel='Time (s)',\n", + " ylabel='Position (m)')\n", + "\n", + "savefig('chap10-fig01.pdf')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can plot the velocities the same way." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "vxs = system.results.vx\n", + "vys = system.results.vy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The x velocity slows down due to drag. The y velocity drops quickly while drag and gravity are in the same direction, then more slowly after the ball starts to fall." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure to file chap10-fig02.pdf\n" + ] + } + ], + "source": [ + "newfig()\n", + "plot(xs, ys, label='trajectory')\n", + "\n", + "decorate(xlabel='x position (m)',\n", + " ylabel='y position (m)')\n", + "\n", + "savefig('chap10-fig02.pdf')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also animate the flight of the ball. If there's an error in the simulation, we can sometimes spot it by looking at animations." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "animate2d(system.results.x, system.results.y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** Run the simulation for a few different launch angles and visualize the results. Are they consistent with your expectations?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Finding the range" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next we'll find the time and distance when the ball hits the ground." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "condition.set(duration=7*s)\n", + "system = make_system(condition)\n", + "run_odeint(system, slope_func)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We have to interpolate y to find the landing time, then interpolate x to find the range." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def interpolate_range(results):\n", + " \"\"\"Computes the range of the ball when it lands.\n", + " \n", + " results: TimeFrame with x and y\n", + " \n", + " returns: distance in meters\n", + " \"\"\"\n", + " xs = results.x\n", + " ys = results.y\n", + " t_end = ys.index[-1]\n", + " \n", + " if ys[t_end] > 0:\n", + " msg = \"\"\"The final value of y is still positive;\n", + " looks like the simulation didn't run\n", + " long enough.\"\"\"\n", + " raise ValueError(msg)\n", + " \n", + " t_peak = ys.argmax()\n", + " descent = ys.loc[t_peak:]\n", + " T = interp_inverse(descent, kind='cubic')\n", + " \n", + " t_land = T(0)\n", + " X = interpolate(xs, kind='cubic')\n", + " return X(t_land)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here's the result." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(102.72237841710975)" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interpolate_range(system.results)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exercise:** The baseball stadium in Denver, Colorado is 1,580 meters above sea level, where the density of air is about 1.0 kg / meter$^3$. How much farther would a ball hit with the same velocity and launch angle travel?" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Hint: rather than modify `condition`, make a copy\n", + "\n", + "condition2 = Condition(condition)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(109.07212101030548)" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Solution goes here\n", + "condition2.rho = 1 * kg/m**3\n", + "system2 = make_system(condition2)\n", + "run_odeint(system2, slope_func)\n", + "interpolate_range(system2.results)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Optimal launch angle\n", + "\n", + "To find the launch angle that maximizes range, we need a function that takes launch angle and returns range." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def range_func(angle, condition): \n", + " \"\"\"Computes range for a given launch angle.\n", + " \n", + " angle: launch angle in degrees\n", + " condition: Condition object\n", + " \n", + " returns: distance in meters\n", + " \"\"\"\n", + " condition.set(angle=angle)\n", + " system = make_system(condition)\n", + " run_odeint(system, slope_func)\n", + " x_range = interpolate_range(system.results)\n", + " return x_range" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's test `range_func`." + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wall time: 277 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "array(109.07212101030548)" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time range_func(45, condition)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And sweep through a range of angles." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "30.0 102.22512880611951\n", + "33.0 105.61073422582602\n", + "36.0 107.97200490961362\n", + "39.0 109.32525682573122\n", + "42.0 109.68662225002511\n", + "45.0 109.07212101030548\n", + "48.0 107.49791212235652\n", + "51.0 104.98068732786591\n", + "54.0 101.53816371252147\n", + "57.0 97.1896982361027\n", + "60.0 91.95703077946803\n" + ] + } + ], + "source": [ + "angles = linspace(30, 60, 11)\n", + "sweep = SweepSeries()\n", + "\n", + "for angle in angles:\n", + " x_range = range_func(angle, condition)\n", + " print(angle, x_range)\n", + " sweep[angle] = x_range" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plotting the `Sweep` object, it looks like the peak is between 40 and 45 degrees." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " this.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('