{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Numerical simulatin of β-catenin destruction cycle\n", "\n", "(c) 2019 Justin Bois. With the exception of pasted graphics, where the source is noted, this work is licensed under a [Creative Commons Attribution License CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/). All code contained herein is licensed under an [MIT license](https://opensource.org/licenses/MIT).\n", "\n", "This document was prepared at [Caltech](http://www.caltech.edu) with financial support from the [Donna and Benjamin M. Rosen Bioengineering Center](http://rosen.caltech.edu).\n", "\n", "\n", "\n", "*This document was generated from a Jupyter notebook, which may be downloaded [here](l03_betacat_destruction_cycle.ipynb).*" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " \n", " Loading BokehJS ...\n", "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "\n", "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " var JS_MIME_TYPE = 'application/javascript';\n", " var HTML_MIME_TYPE = 'text/html';\n", " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", " var CLASS_NAME = 'output_bokeh rendered_html';\n", "\n", " /**\n", " * Render data to the DOM node\n", " */\n", " function render(props, node) {\n", " var script = document.createElement(\"script\");\n", " node.appendChild(script);\n", " }\n", "\n", " /**\n", " * Handle when an output is cleared or removed\n", " */\n", " function handleClearOutput(event, handle) {\n", " var cell = handle.cell;\n", "\n", " var id = cell.output_area._bokeh_element_id;\n", " var server_id = cell.output_area._bokeh_server_id;\n", " // Clean up Bokeh references\n", " if (id != null && id in Bokeh.index) {\n", " Bokeh.index[id].model.document.clear();\n", " delete Bokeh.index[id];\n", " }\n", "\n", " if (server_id !== undefined) {\n", " // Clean up Bokeh references\n", " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", " cell.notebook.kernel.execute(cmd, {\n", " iopub: {\n", " output: function(msg) {\n", " var id = msg.content.text.trim();\n", " if (id in Bokeh.index) {\n", " Bokeh.index[id].model.document.clear();\n", " delete Bokeh.index[id];\n", " }\n", " }\n", " }\n", " });\n", " // Destroy server and session\n", " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", " cell.notebook.kernel.execute(cmd);\n", " }\n", " }\n", "\n", " /**\n", " * Handle when a new output is added\n", " */\n", " function handleAddOutput(event, handle) {\n", " var output_area = handle.output_area;\n", " var output = handle.output;\n", "\n", " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", " return\n", " }\n", "\n", " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", "\n", " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", " // store reference to embed id on output_area\n", " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " }\n", " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " var bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " var script_attrs = bk_div.children[0].attributes;\n", " for (var i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", " }\n", "\n", " function register_renderer(events, OutputArea) {\n", "\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " var toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[toinsert.length - 1]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " /* Handle when an output is cleared or removed */\n", " events.on('clear_output.CodeCell', handleClearOutput);\n", " events.on('delete.Cell', handleClearOutput);\n", "\n", " /* Handle when a new output is added */\n", " events.on('output_added.OutputArea', handleAddOutput);\n", "\n", " /**\n", " * Register the mime type and append_mime function with output_area\n", " */\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " /* Is output safe? */\n", " safe: true,\n", " /* Index of renderer in `output_area.display_order` */\n", " index: 0\n", " });\n", " }\n", "\n", " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", " if (root.Jupyter !== undefined) {\n", " var events = require('base/js/events');\n", " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", "\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " }\n", "\n", " \n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " var NB_LOAD_WARNING = {'data': {'text/html':\n", " \"
\\n\"+\n", " \"

\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"

\\n\"+\n", " \"\\n\"+\n", " \"\\n\"+\n", " \"from bokeh.resources import INLINE\\n\"+\n", " \"output_notebook(resources=INLINE)\\n\"+\n", " \"\\n\"+\n", " \"
\"}};\n", "\n", " function display_loaded() {\n", " var el = document.getElementById(\"1001\");\n", " if (el != null) {\n", " el.textContent = \"BokehJS is loading...\";\n", " }\n", " if (root.Bokeh !== undefined) {\n", " if (el != null) {\n", " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", " }\n", " } else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(display_loaded, 100)\n", " }\n", " }\n", "\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n", " }\n", " finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.info(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(js_urls, callback) {\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls == null || js_urls.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", " root._bokeh_is_loading = js_urls.length;\n", " for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " var s = document.createElement('script');\n", " s.src = url;\n", " s.async = false;\n", " s.onreadystatechange = s.onload = function() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.log(\"Bokeh: all BokehJS libraries loaded\");\n", " run_callbacks()\n", " }\n", " };\n", " s.onerror = function() {\n", " console.warn(\"failed to load library \" + url);\n", " };\n", " console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.getElementsByTagName(\"head\")[0].appendChild(s);\n", " }\n", " };var element = document.getElementById(\"1001\");\n", " if (element == null) {\n", " console.log(\"Bokeh: ERROR: autoload.js configured with elementid '1001' but no matching script tag was found. \")\n", " return false;\n", " }\n", "\n", " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.3.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.3.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.3.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.0.3.min.js\"];\n", "\n", " var inline_js = [\n", " function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", " \n", " function(Bokeh) {\n", " \n", " },\n", " function(Bokeh) {\n", " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-1.0.3.min.css\");\n", " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.3.min.css\");\n", " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.3.min.css\");\n", " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.3.min.css\");\n", " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.3.min.css\");\n", " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.3.min.css\");\n", " }\n", " ];\n", "\n", " function run_inline_js() {\n", " \n", " if ((root.Bokeh !== undefined) || (force === true)) {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }if (force === true) {\n", " display_loaded();\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " } else if (force !== true) {\n", " var cell = $(document.getElementById(\"1001\")).parents('.cell').data().cell;\n", " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", " }\n", "\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(js_urls, function() {\n", " console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1001\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n }\n finally {\n delete root._bokeh_onload_callbacks\n }\n console.info(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(js_urls, callback) {\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = js_urls.length;\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var s = document.createElement('script');\n s.src = url;\n s.async = false;\n s.onreadystatechange = s.onload = function() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.log(\"Bokeh: all BokehJS libraries loaded\");\n run_callbacks()\n }\n };\n s.onerror = function() {\n console.warn(\"failed to load library \" + url);\n };\n console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.getElementsByTagName(\"head\")[0].appendChild(s);\n }\n };var element = document.getElementById(\"1001\");\n if (element == null) {\n console.log(\"Bokeh: ERROR: autoload.js configured with elementid '1001' but no matching script tag was found. \")\n return false;\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.3.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.3.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.3.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.0.3.min.js\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n \n },\n function(Bokeh) {\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-1.0.3.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-1.0.3.min.css\");\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.3.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.3.min.css\");\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.3.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.3.min.css\");\n }\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1001\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(js_urls, function() {\n console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "import pandas as pd\n", "import scipy.integrate\n", "\n", "import bokeh.io\n", "import bokeh.models\n", "import bokeh.plotting\n", "import bokeh.application\n", "import bokeh.application.handlers\n", "\n", "bokeh.io.output_notebook()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this document, I present a numerical solution for the dynamical equations describing the β-catenin destruction cycle, as described in the [Lee, et al. paper](https://doi.org/10.1371/journal.pbio.0000010). As a reminder, the destruction cycle is part of the broader Wnt signaling pathway, as shown in this figure from the Lee, et al. paper.\n", "\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "\n", "To aid in interpreting the dynamical equations, the chemical species and their corresponding numerical label that are involved in the cycle are:\n", "\n", "|number | species |\n", "|--:--|--:--|\n", "|3 | APC*/Axin*/GSK-3|\n", "|8 | β-catenin/APC*/Axin*/GSK-3 |\n", "|9 | β-catenin*/APC*/Axin*/GSK-3 |\n", "|10 | β-catenin* |\n", "|11 | β-catenin |\n", "\n", "The mass action equations describing the dynamics are\n", "\n", "\\begin{align}\n", "&\\frac{\\mathrm{d}c_3}{\\mathrm{d}t} = -k_8 c_3 c_{11} + k_{\\text{-}8}c_8 + k_{10}c_9, \\label{eq:41} \\\\\n", "&\\frac{\\mathrm{d}c_8}{\\mathrm{d}t} = k_8 c_3 c_{11} - k_{\\text{-}8}c_8 - k_9c_8, \\label{eq:42}\\\\\n", "&\\frac{\\mathrm{d}c_9}{\\mathrm{d}t} = k_9c_8 - k_{10} c_9,\\label{eq:43} \\\\\n", "&\\frac{\\mathrm{d}c_{10}}{\\mathrm{d}t} = k_{10} c_9 - k_{11}c_{10}, \\label{eq:44}\\\\\n", "&\\frac{\\mathrm{d}c_{11}}{\\mathrm{d}t} = k_{12} - k_8 c_3 c_{11} + k_{\\text{-}8}c_8.\n", "\\end{align}\n", "\n", "Most of the parameters are measured and reported, at least approximately, in the Lee, et al. paper. The parameters $k_8$, $k_{\\text{-}8}$ and $k_{12}$ are unknown. However, $K_\\mathrm{d} = k_{\\text{-}8}/k_8$ is known, so we only have two parameters to set. We will develop an interactive plotting app to allow us to investigate the dynamics of the respective species as the two parameters $k_8$ and $k_{-8}$ are varied. In doing so, we will see how the `scipy.integrate.solve_ivp()` function works to numerically solve systems of ordinary differential equations." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Numerical integration using SciPy\n", "\n", "There are three main APIs for solving real-valued initial value problems in the SciPy library. They are [`scipy.integrate.solve_ivp()`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html#scipy.integrate.solve_ivp), [`ode()`](https://scipy.github.io/devdocs/generated/scipy.integrate.ode.html#scipy.integrate.ode), and [`odeint()`](https://scipy.github.io/devdocs/generated/scipy.integrate.odeint.html#scipy.integrate.odeint). According to the SciPy developers, `scipy.integrate.solve_ivp()` is the preferred method, with the others labeled as having an \"old\" API. The `solve_ivp()` function has the flexibility of allowing choice of multiple numerical algorithms for solving ODEs. However, for the kinds of problems we encounter in this class, I find that the generic LSODA algorithm developed by Linda Petzold and Alan Hindmarsh that handles both stiff and non-stiff problems with variable time stepping is the best option. This is the only solver offered in the `odeint()` function. If we compare the two solvers, `solve_ivp()` and `odeint()`, the former has a large overhead, which can lead to performance issues for small problems (for large problems, this is not a big deal). Since most of our problems are small, we will use `odeint()`. It has much better performance, and though its API is different, it is still intuitive.\n", "\n", "The basic call signature for `scipy.integrate.odeint()` is\n", "\n", " scipy.integrate.odeint(func, y0, t, args=())\n", " \n", "There are many other keyword arguments to set algorithmic parameters, but we will generally not need them (and you can read about them in [the docs](https://scipy.github.io/devdocs/generated/scipy.integrate.odeint.html#scipy.integrate.odeint).\n", "\n", "Importantly, `fun` is a vector-valued function with call signature `f(y, t, *args)` that specifies the right hand side of the system of ODEs to be solved. `t` is a scalar time point and `y` is a one-dimensional array (though multidimensional arrays are possible; see the SciPy docs). `y0` is an array with the initial conditions.\n", "\n", "Let's put together some code to solve the ODEs describing the β-catenin destruction cycle!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Numerical solution of the β-catenin destruction cycle dynamics\n", "\n", "First, the preliminaries. We'll sed up parameters and names of the respective species." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Key for names\n", "names = ['Axin complex', 'Axin-βcat', 'Axin-βcat*', 'βcat*', 'βcat']\n", "\n", "# Define known parameters\n", "c_A = 50 # nM (given by fixed GSK-3 concentration)\n", "k9 = 206 # 1/min\n", "k10 = 206 # 1/min\n", "k11 = 0.417 # 1/min\n", "Kd8 = 120 # nM\n", "\n", "# Unknown parameters\n", "km8 = 1 # 1/min\n", "k12 = 100 # nM/min\n", "\n", "# k8 determined form Kd8 and km8\n", "k8 = km8 / Kd8 # 1/nM-min\n", "\n", "# Set up params for ODE\n", "params = (k8, km8, k9, k10, k11, k12)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For our initial conditions, we will assume that we have no $\\beta$-catenin and that we have a fixed amount of APC/Axin/GKC-3." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Initial conditions\n", "c0 = np.array([c_A, 0, 0, 0, 0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we define the right hand side of the ODEs. We do need to pass in parameters. We list the parameters after the required arguments, `t` and `y` (for the present case, `y` is `c`). The function needs to return an array of time derivatives, in the present case five of them." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def dcdt(c, t, k8, km8, k9, k10, k11, k12):\n", " \"\"\"\n", " Time derivative of concentrations.\n", " c = (c3, c8, c9, c10, c11)\n", " \"\"\"\n", " # Unpack concentrations\n", " c3, c8, c9, c10, c11 = c\n", " \n", " # Build derivatives\n", " deriv = np.empty(5)\n", " deriv[0] = -k8*c3*c11 + km8*c8 + k10*c9\n", " deriv[1] = k8*c3*c11 - (km8 + k9)*c8\n", " deriv[2] = k9*c8 - k10*c9\n", " deriv[3] = k10*c9 - k11*c10\n", " deriv[4] = -k8*c3*c11 + km8*c8 + k12\n", " \n", " return deriv" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we just have to specify what time points we want." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# Set up time points\n", "t = np.linspace(0, 20, 300)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We are finally ready to run the solver." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "c = scipy.integrate.odeint(dcdt, c0, t, args=params)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result is a Numpy array where each column corresponds to one of the variables we are solving for in the ODE, in this case the concentrations. We can use these to plot the solution." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "(function(root) {\n", " function embed_document(root) {\n", " \n", " var docs_json = {\"d39622fe-04e3-43ab-b372-dda860e83bef\":{\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"1011\",\"type\":\"LinearAxis\"}],\"left\":[{\"id\":\"1016\",\"type\":\"LinearAxis\"}],\"plot_height\":400,\"plot_width\":650,\"renderers\":[{\"id\":\"1011\",\"type\":\"LinearAxis\"},{\"id\":\"1015\",\"type\":\"Grid\"},{\"id\":\"1016\",\"type\":\"LinearAxis\"},{\"id\":\"1020\",\"type\":\"Grid\"},{\"id\":\"1029\",\"type\":\"BoxAnnotation\"},{\"id\":\"1048\",\"type\":\"Legend\"},{\"id\":\"1039\",\"type\":\"GlyphRenderer\"},{\"id\":\"1053\",\"type\":\"GlyphRenderer\"},{\"id\":\"1068\",\"type\":\"GlyphRenderer\"},{\"id\":\"1085\",\"type\":\"GlyphRenderer\"},{\"id\":\"1104\",\"type\":\"GlyphRenderer\"}],\"title\":{\"id\":\"1042\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"1027\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"1003\",\"type\":\"DataRange1d\"},\"x_scale\":{\"id\":\"1007\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"1005\",\"type\":\"DataRange1d\"},\"y_scale\":{\"id\":\"1009\",\"type\":\"LinearScale\"}},\"id\":\"1002\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"plot\":null,\"text\":\"\"},\"id\":\"1042\",\"type\":\"Title\"},{\"attributes\":{},\"id\":\"1137\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1079\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1044\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"label\":{\"value\":\"Axin-\\u03b2cat*\"},\"renderers\":[{\"id\":\"1068\",\"type\":\"GlyphRenderer\"}]},\"id\":\"1081\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1046\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[300]},\"y\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[300]}},\"selected\":{\"id\":\"1061\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1062\",\"type\":\"UnionRenderers\"}},\"id\":\"1036\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[300]},\"y\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[300]}},\"selected\":{\"id\":\"1118\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1119\",\"type\":\"UnionRenderers\"}},\"id\":\"1082\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"items\":[{\"id\":\"1049\",\"type\":\"LegendItem\"},{\"id\":\"1064\",\"type\":\"LegendItem\"},{\"id\":\"1081\",\"type\":\"LegendItem\"},{\"id\":\"1100\",\"type\":\"LegendItem\"},{\"id\":\"1121\",\"type\":\"LegendItem\"}],\"location\":\"center_right\",\"plot\":{\"id\":\"1002\",\"subtype\":\"Figure\",\"type\":\"Plot\"}},\"id\":\"1048\",\"type\":\"Legend\"},{\"attributes\":{},\"id\":\"1021\",\"type\":\"PanTool\"},{\"attributes\":{\"line_color\":\"#d62728\",\"line_width\":3,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1083\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1022\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":3,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1084\",\"type\":\"Line\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[300]},\"y\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[300]}},\"selected\":{\"id\":\"1078\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1079\",\"type\":\"UnionRenderers\"}},\"id\":\"1050\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"overlay\":{\"id\":\"1029\",\"type\":\"BoxAnnotation\"}},\"id\":\"1023\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"data_source\":{\"id\":\"1082\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1083\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1084\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"1086\",\"type\":\"CDSView\"}},\"id\":\"1085\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1007\",\"type\":\"LinearScale\"},{\"attributes\":{\"line_color\":\"#ff7f0e\",\"line_width\":3,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1051\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1024\",\"type\":\"SaveTool\"},{\"attributes\":{\"source\":{\"id\":\"1082\",\"type\":\"ColumnDataSource\"}},\"id\":\"1086\",\"type\":\"CDSView\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":3,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1052\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1025\",\"type\":\"ResetTool\"},{\"attributes\":{\"callback\":null},\"id\":\"1003\",\"type\":\"DataRange1d\"},{\"attributes\":{\"data_source\":{\"id\":\"1050\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1051\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1052\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"1054\",\"type\":\"CDSView\"}},\"id\":\"1053\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1026\",\"type\":\"HelpTool\"},{\"attributes\":{},\"id\":\"1098\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null},\"id\":\"1005\",\"type\":\"DataRange1d\"},{\"attributes\":{\"source\":{\"id\":\"1050\",\"type\":\"ColumnDataSource\"}},\"id\":\"1054\",\"type\":\"CDSView\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"1021\",\"type\":\"PanTool\"},{\"id\":\"1022\",\"type\":\"WheelZoomTool\"},{\"id\":\"1023\",\"type\":\"BoxZoomTool\"},{\"id\":\"1024\",\"type\":\"SaveTool\"},{\"id\":\"1025\",\"type\":\"ResetTool\"},{\"id\":\"1026\",\"type\":\"HelpTool\"}]},\"id\":\"1027\",\"type\":\"Toolbar\"},{\"attributes\":{\"label\":{\"value\":\"\\u03b2cat*\"},\"renderers\":[{\"id\":\"1085\",\"type\":\"GlyphRenderer\"}]},\"id\":\"1100\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1061\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1078\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1136\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1009\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1062\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"plot\":null,\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"1029\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[300]},\"y\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[300]}},\"selected\":{\"id\":\"1136\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1137\",\"type\":\"UnionRenderers\"}},\"id\":\"1101\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1097\",\"type\":\"Selection\"},{\"attributes\":{\"axis_label\":\"time (min)\",\"formatter\":{\"id\":\"1044\",\"type\":\"BasicTickFormatter\"},\"plot\":{\"id\":\"1002\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1012\",\"type\":\"BasicTicker\"}},\"id\":\"1011\",\"type\":\"LinearAxis\"},{\"attributes\":{\"label\":{\"value\":\"Axin-\\u03b2cat\"},\"renderers\":[{\"id\":\"1053\",\"type\":\"GlyphRenderer\"}]},\"id\":\"1064\",\"type\":\"LegendItem\"},{\"attributes\":{\"line_color\":\"#9467bd\",\"line_width\":3,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1102\",\"type\":\"Line\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[300]},\"y\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[300]}},\"selected\":{\"id\":\"1097\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1098\",\"type\":\"UnionRenderers\"}},\"id\":\"1065\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":3,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1103\",\"type\":\"Line\"},{\"attributes\":{\"label\":{\"value\":\"Axin complex\"},\"renderers\":[{\"id\":\"1039\",\"type\":\"GlyphRenderer\"}]},\"id\":\"1049\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1012\",\"type\":\"BasicTicker\"},{\"attributes\":{\"line_color\":\"#2ca02c\",\"line_width\":3,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1066\",\"type\":\"Line\"},{\"attributes\":{\"data_source\":{\"id\":\"1101\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1102\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1103\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"1105\",\"type\":\"CDSView\"}},\"id\":\"1104\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_color\":\"#1f77b4\",\"line_width\":3,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1037\",\"type\":\"Line\"},{\"attributes\":{\"plot\":{\"id\":\"1002\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1012\",\"type\":\"BasicTicker\"}},\"id\":\"1015\",\"type\":\"Grid\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":3,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1067\",\"type\":\"Line\"},{\"attributes\":{\"source\":{\"id\":\"1101\",\"type\":\"ColumnDataSource\"}},\"id\":\"1105\",\"type\":\"CDSView\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":3,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1038\",\"type\":\"Line\"},{\"attributes\":{\"axis_label\":\"conc (nM)\",\"formatter\":{\"id\":\"1046\",\"type\":\"BasicTickFormatter\"},\"plot\":{\"id\":\"1002\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1017\",\"type\":\"BasicTicker\"}},\"id\":\"1016\",\"type\":\"LinearAxis\"},{\"attributes\":{\"data_source\":{\"id\":\"1065\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1066\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1067\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"1069\",\"type\":\"CDSView\"}},\"id\":\"1068\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1118\",\"type\":\"Selection\"},{\"attributes\":{\"data_source\":{\"id\":\"1036\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1037\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1038\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"1040\",\"type\":\"CDSView\"}},\"id\":\"1039\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1017\",\"type\":\"BasicTicker\"},{\"attributes\":{\"source\":{\"id\":\"1065\",\"type\":\"ColumnDataSource\"}},\"id\":\"1069\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1119\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"1036\",\"type\":\"ColumnDataSource\"}},\"id\":\"1040\",\"type\":\"CDSView\"},{\"attributes\":{\"dimension\":1,\"plot\":{\"id\":\"1002\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"1017\",\"type\":\"BasicTicker\"}},\"id\":\"1020\",\"type\":\"Grid\"},{\"attributes\":{\"label\":{\"value\":\"\\u03b2cat\"},\"renderers\":[{\"id\":\"1104\",\"type\":\"GlyphRenderer\"}]},\"id\":\"1121\",\"type\":\"LegendItem\"}],\"root_ids\":[\"1002\"]},\"title\":\"Bokeh Application\",\"version\":\"1.0.3\"}};\n", " var render_items = [{\"docid\":\"d39622fe-04e3-43ab-b372-dda860e83bef\",\"roots\":{\"1002\":\"4f28203f-4c69-4fc8-a4f7-6579316247bc\"}}];\n", " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", "\n", " }\n", " if (root.Bokeh !== undefined) {\n", " embed_document(root);\n", " } else {\n", " var attempts = 0;\n", " var timer = setInterval(function(root) {\n", " if (root.Bokeh !== undefined) {\n", " embed_document(root);\n", " clearInterval(timer);\n", " }\n", " attempts++;\n", " if (attempts > 100) {\n", " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", " clearInterval(timer);\n", " }\n", " }, 10, root)\n", " }\n", "})(window);" ], "application/vnd.bokehjs_exec.v0+json": "" }, "metadata": { "application/vnd.bokehjs_exec.v0+json": { "id": "1002" } }, "output_type": "display_data" } ], "source": [ "# Set up canvas on which to paint plot\n", "p = bokeh.plotting.figure(plot_width=650,\n", " plot_height=400,\n", " x_axis_label='time (min)',\n", " y_axis_label='conc (nM)')\n", "\n", "# Specify colors\n", "colors = bokeh.palettes.d3['Category10'][5]\n", "\n", "# Add glyphs\n", "for c_res, name, color in zip(c.transpose(), names, colors):\n", " p.line(t, c_res, line_width=3, color=color, legend=name)\n", "\n", "# Place legend\n", "p.legend.location = 'center_right'\n", "\n", "bokeh.io.show(p)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Axin-β-catenin complexes, both activated and not activated, remain at low levels and closely track each other (if you zoom, you can see that the orange and green curves do not quite perfectly overlap). The unbound Axin complex does not vary much from its initial concentration of 50 nM." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Interactive plotting\n", "\n", "When investigating how parameter values affect dynamics, it is convenient to be able to quickly adjust parameter values and see how the response changes. Interactive plotting is a very useful tool in this regard. We can make sliders to vary parameter values and see how the dynamics change.\n", "\n", "We will use Bokeh to generate an interactive plot. We write a function to make the plot, with the data being sourced with a Bokeh `ColumnDataSource`. We then create sliders and write a callback function that dictates how the data source changes with the slide values." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "application/vnd.bokehjs_exec.v0+json": "", "text/html": [ "\n", "" ] }, "metadata": { "application/vnd.bokehjs_exec.v0+json": { "server_id": "5c572f8cf530431185943da3497a7d55" } }, "output_type": "display_data" } ], "source": [ "def plot_app(doc):\n", " # Set up canvas on which to paint plot\n", " p = bokeh.plotting.figure(plot_width=650,\n", " plot_height=400,\n", " x_axis_label='time (min)',\n", " y_axis_label='conc (nM)')\n", "\n", " # Specify colors\n", " colors = bokeh.palettes.d3['Category10'][5]\n", " \n", " # Set up a data source\n", " df = pd.DataFrame(data=c, columns=names)\n", " df['t'] = t\n", " source = bokeh.models.ColumnDataSource(data=df)\n", "\n", " # Add glyphs\n", " for name, color in zip(names, colors):\n", " p.line(x='t', \n", " y=name, \n", " source=source, \n", " line_width=3, \n", " color=color, \n", " legend=bokeh.core.properties.value(name))\n", " \n", " # Place legend\n", " p.legend.location = 'top_left'\n", "\n", " # Callback function to update curves with new solve on slider change\n", " def callback(attr, old, new):\n", " # Extract parameter values from sliders\n", " km8 = 10**log10_km8_slider.value\n", " k8 = km8 / Kd8\n", " k12 = k12_slider.value\n", " params = (k8, km8, k9, k10, k11, k12)\n", " \n", " # Compute curves\n", " c = scipy.integrate.odeint(dcdt, c0, t, args=params)\n", "\n", " # Update data source\n", " df = pd.DataFrame(c, columns=names)\n", " df['t'] = t\n", " source.data = dict(df)\n", "\n", " # Set up sliders\n", " log10_km8_slider = bokeh.models.Slider(\n", " title='log₁₀ k₋₈ [log₁₀(1/min)]',\n", " value=np.log10(km8),\n", " start=-2.0, \n", " end=4.0,\n", " step=0.1)\n", " log10_km8_slider.on_change('value', callback)\n", " k12_slider = bokeh.models.Slider(\n", " title='k₁₂ [1/nm-min]',\n", " value=k12,\n", " start=20.0,\n", " end=100.0,\n", " step=1.0)\n", " k12_slider.on_change('value', callback)\n", "\n", " # Build app\n", " widgets = bokeh.layouts.widgetbox([log10_km8_slider, k12_slider])\n", " doc.add_root(bokeh.layouts.column(p, widgets))\n", "\n", "# Deploy (change notebook handle appropriately)\n", "handler = bokeh.application.handlers.FunctionHandler(plot_app)\n", "bokeh.io.show(bokeh.application.Application(handler), \n", " notebook_handle='localhost:8888')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The interactive plotting shows that $k_{12}$ simply sets the scale of the concentration of β-catenin, with the axic complex concentrations being essentially unchanged. The parameter $k_{-8}$ adjusts the relative amounts of active and inactive β-catenin." ] } ], "metadata": { "anaconda-cloud": {}, "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.7.1" } }, "nbformat": 4, "nbformat_minor": 2 }