diff --git a/2024/_sources/exercise_solutions/exercise_3/exercise_3.1_solution.ipynb.txt b/2024/_sources/exercise_solutions/exercise_3/exercise_3.1_solution.ipynb.txt new file mode 100644 index 00000000..5ff90b08 --- /dev/null +++ b/2024/_sources/exercise_solutions/exercise_3/exercise_3.1_solution.ipynb.txt @@ -0,0 +1,905 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Exercise 3.1: Mastering .loc for Pandas data frames\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pandas can be a bit frustrating during your first experiences with it. In this and the next few exercises, we will do our first practice with it. Stick with it! The more and more you use it, the more distant the memory of life without it will become.\n", + "\n", + "We will work with a data set from [Kleinteich and Gorb, *Sci. Rep.*, **4**, 5355, 2014](https://doi.org/10.1038/srep05225), and was [featured in the New York Times](http://www.nytimes.com/2014/08/25/science/a-frog-thats-a-living-breathing-pac-man.html). They measured several properties about the tongue strikes of horned frogs. Let's take a look at the data set, which is in the file `~/git/data/frog_tongue_adhesion.csv`." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# These data are from the paper,\n", + "# Kleinteich and Gorb, Sci. Rep., 4, 5225, 2014.\n", + "# It was featured in the New York Times.\n", + "# http://www.nytimes.com/2014/08/25/science/a-frog-thats-a-living-breathing-pac-man.html\n", + "#\n", + "# The authors included the data in their supplemental information.\n", + "#\n", + "# Importantly, the ID refers to the identifites of the frogs they tested.\n", + "# I: adult, 63 mm snout-vent-length (SVL) and 63.1 g body weight,\n", + "# Ceratophrys cranwelli crossed with Ceratophrys cornuta\n", + "# II: adult, 70 mm SVL and 72.7 g body weight,\n", + "# Ceratophrys cranwelli crossed with Ceratophrys cornuta\n", + "# III: juvenile, 28 mm SVL and 12.7 g body weight, Ceratophrys cranwelli\n", + "# IV: juvenile, 31 mm SVL and 12.7 g body weight, Ceratophrys cranwelli\n", + "date,ID,trial number,impact force (mN),impact time (ms),impact force / body weight,adhesive force (mN),time frog pulls on target (ms),adhesive force / body weight,adhesive impulse (N-s),total contact area (mm2),contact area without mucus (mm2),contact area with mucus / contact area without mucus,contact pressure (Pa),adhesive strength (Pa)\n", + "2013_02_26,I,3,1205,46,1.95,-785,884,1.27,-0.290,387,70,0.82,3117,-2030\n", + "2013_02_26,I,4,2527,44,4.08,-983,248,1.59,-0.181,101,94,0.07,24923,-9695\n", + "2013_03_01,I,1,1745,34,2.82,-850,211,1.37,-0.157,83,79,0.05,21020,-10239\n", + "2013_03_01,I,2,1556,41,2.51,-455,1025,0.74,-0.170,330,158,0.52,4718,-1381\n", + "2013_03_01,I,3,493,36,0.80,-974,499,1.57,-0.423,245,216,0.12,2012,-3975\n" + ] + } + ], + "source": [ + "!head -20 data/frog_tongue_adhesion.csv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first lines all begin with `#` signs, signifying that they are comments and not data. They do give important information, though, such as the meaning of the ID data. The ID refers to which specific frog was tested.\n", + "\n", + "Immediately after the comments, we have a row of comma-separated headers. This row sets the number of columns in this data set and labels the meaning of the columns. So, we see that the first column is the date of the experiment, the second column is the ID of the frog, the third is the trial number, and so on.\n", + "\n", + "After this row, each row represents a single experiment where the frog struck the target. So, these data are already in tidy format. \n", + "\n", + "**a)** Load in the data set into a data frame. Be sure to use the appropriate value for the `comment` keyword argument of `pd.read_csv()`.\n", + "\n", + "**b)** Extract the impact time of all impacts that had an adhesive strength of magnitude greater than 2000 Pa. *Note*: The data in the `'adhesive strength (Pa)'` column is all negative. This is because the adhesive force is defined to be negative in the measurement. Without changing the data in the data frame, how can you check that the magnitude (the absolute value) is greater than 2000?\n", + "\n", + "**c)** Extract the impact force and adhesive force for all of Frog II's strikes.\n", + "\n", + "**d)** Extract the adhesive force and the time the frog pulls on the target for juvenile frogs (Frogs III and IV). *Hint*: We saw the `&` operator for Boolean indexing across more than one column. The `|` operator signifies OR, and works analogously. For technical reasons that we can discuss if you like, the Python operators `and` and `or` will **not** work for Boolean indexing of data frames. You could also approach this using the `isin()` method of a Pandas `Series`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solution\n", + "\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To read in the data frame, we use the `comment='#'` kwarg." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "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", + "
dateIDtrial numberimpact force (mN)impact time (ms)impact force / body weightadhesive force (mN)time frog pulls on target (ms)adhesive force / body weightadhesive impulse (N-s)total contact area (mm2)contact area without mucus (mm2)contact area with mucus / contact area without mucuscontact pressure (Pa)adhesive strength (Pa)
02013_02_26I31205461.95-7858841.27-0.290387700.823117-2030
12013_02_26I42527444.08-9832481.59-0.181101940.0724923-9695
22013_03_01I11745342.82-8502111.37-0.15783790.0521020-10239
32013_03_01I21556412.51-45510250.74-0.1703301580.524718-1381
42013_03_01I3493360.80-9744991.57-0.4232452160.122012-3975
\n", + "
" + ], + "text/plain": [ + " date ID trial number impact force (mN) impact time (ms) \\\n", + "0 2013_02_26 I 3 1205 46 \n", + "1 2013_02_26 I 4 2527 44 \n", + "2 2013_03_01 I 1 1745 34 \n", + "3 2013_03_01 I 2 1556 41 \n", + "4 2013_03_01 I 3 493 36 \n", + "\n", + " impact force / body weight adhesive force (mN) \\\n", + "0 1.95 -785 \n", + "1 4.08 -983 \n", + "2 2.82 -850 \n", + "3 2.51 -455 \n", + "4 0.80 -974 \n", + "\n", + " time frog pulls on target (ms) adhesive force / body weight \\\n", + "0 884 1.27 \n", + "1 248 1.59 \n", + "2 211 1.37 \n", + "3 1025 0.74 \n", + "4 499 1.57 \n", + "\n", + " adhesive impulse (N-s) total contact area (mm2) \\\n", + "0 -0.290 387 \n", + "1 -0.181 101 \n", + "2 -0.157 83 \n", + "3 -0.170 330 \n", + "4 -0.423 245 \n", + "\n", + " contact area without mucus (mm2) \\\n", + "0 70 \n", + "1 94 \n", + "2 79 \n", + "3 158 \n", + "4 216 \n", + "\n", + " contact area with mucus / contact area without mucus \\\n", + "0 0.82 \n", + "1 0.07 \n", + "2 0.05 \n", + "3 0.52 \n", + "4 0.12 \n", + "\n", + " contact pressure (Pa) adhesive strength (Pa) \n", + "0 3117 -2030 \n", + "1 24923 -9695 \n", + "2 21020 -10239 \n", + "3 4718 -1381 \n", + "4 2012 -3975 " + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.read_csv('data/frog_tongue_adhesion.csv', comment='#')\n", + "\n", + "# Take a look\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**b)** To extract the entries with strong adhesive strength, we need to use the `np.abs()` function to esure that the absolute value of the adhesive strength is above 2000." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 46\n", + "1 44\n", + "2 34\n", + "4 36\n", + "7 46\n", + "8 50\n", + "11 48\n", + "13 31\n", + "14 38\n", + "17 60\n", + "19 40\n", + "23 59\n", + "24 33\n", + "25 43\n", + "27 31\n", + "29 42\n", + "31 57\n", + "33 21\n", + "35 29\n", + "37 31\n", + "38 15\n", + "39 42\n", + "42 105\n", + "44 29\n", + "45 16\n", + "47 31\n", + "49 32\n", + "50 30\n", + "51 16\n", + "52 27\n", + "53 30\n", + "54 35\n", + "55 39\n", + "57 34\n", + "59 34\n", + "60 26\n", + "61 20\n", + "62 55\n", + "65 33\n", + "66 74\n", + "67 26\n", + "68 27\n", + "69 33\n", + "71 6\n", + "73 31\n", + "74 34\n", + "75 38\n", + "78 33\n", + "Name: impact time (ms), dtype: int64" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.loc[np.abs(df['adhesive strength (Pa)']) > 2000, 'impact time (ms)']" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "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", + "
impact force (mN)adhesive force (mN)
201612-655
21605-292
22327-246
23946-245
24541-553
251539-664
26529-261
27628-691
281453-92
29297-566
30703-223
31269-512
32751-227
33245-573
341182-522
35515-599
36435-364
37383-469
38457-844
39730-648
\n", + "
" + ], + "text/plain": [ + " impact force (mN) adhesive force (mN)\n", + "20 1612 -655\n", + "21 605 -292\n", + "22 327 -246\n", + "23 946 -245\n", + "24 541 -553\n", + "25 1539 -664\n", + "26 529 -261\n", + "27 628 -691\n", + "28 1453 -92\n", + "29 297 -566\n", + "30 703 -223\n", + "31 269 -512\n", + "32 751 -227\n", + "33 245 -573\n", + "34 1182 -522\n", + "35 515 -599\n", + "36 435 -364\n", + "37 383 -469\n", + "38 457 -844\n", + "39 730 -648" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# c) Impact force and adhesive force for Frog II\n", + "df.loc[df['ID']=='II', ['impact force (mN)', 'adhesive force (mN)']]" + ] + }, + { + "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", + "
adhesive force (mN)time frog pulls on target (ms)
40-94683
41-163245
42-172619
43-2251823
44-301918
45-931351
46-1311790
47-2891006
48-104883
49-2291218
50-259910
51-231550
52-2672081
53-178376
54-123289
55-151607
56-1272932
57-372680
58-236685
59-3901308
60-456462
61-193250
62-236743
63-225844
64-217728
65-161472
66-139959
67-264844
68-3421515
69-231279
70-2091427
71-2922874
72-3394251
73-371626
74-3311254
75-302986
76-2161627
77-1632021
78-3671366
79-2181269
\n", + "
" + ], + "text/plain": [ + " adhesive force (mN) time frog pulls on target (ms)\n", + "40 -94 683\n", + "41 -163 245\n", + "42 -172 619\n", + "43 -225 1823\n", + "44 -301 918\n", + "45 -93 1351\n", + "46 -131 1790\n", + "47 -289 1006\n", + "48 -104 883\n", + "49 -229 1218\n", + "50 -259 910\n", + "51 -231 550\n", + "52 -267 2081\n", + "53 -178 376\n", + "54 -123 289\n", + "55 -151 607\n", + "56 -127 2932\n", + "57 -372 680\n", + "58 -236 685\n", + "59 -390 1308\n", + "60 -456 462\n", + "61 -193 250\n", + "62 -236 743\n", + "63 -225 844\n", + "64 -217 728\n", + "65 -161 472\n", + "66 -139 959\n", + "67 -264 844\n", + "68 -342 1515\n", + "69 -231 279\n", + "70 -209 1427\n", + "71 -292 2874\n", + "72 -339 4251\n", + "73 -371 626\n", + "74 -331 1254\n", + "75 -302 986\n", + "76 -216 1627\n", + "77 -163 2021\n", + "78 -367 1366\n", + "79 -218 1269" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# d) Adhesive force and time frog pulls for frogs III and IV\n", + "df.loc[\n", + " df[\"ID\"].isin([\"III\", \"IV\"]),\n", + " [\"adhesive force (mN)\", \"time frog pulls on target (ms)\"],\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Computing environment" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Python implementation: CPython\n", + "Python version : 3.11.3\n", + "IPython version : 8.12.0\n", + "\n", + "numpy : 1.24.3\n", + "pandas : 1.5.3\n", + "jupyterlab: 3.6.3\n", + "\n" + ] + } + ], + "source": [ + "%load_ext watermark\n", + "%watermark -v -p numpy,pandas,jupyterlab" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/2024/_sources/exercise_solutions/exercise_3/exercise_3.2_solution.ipynb.txt b/2024/_sources/exercise_solutions/exercise_3/exercise_3.2_solution.ipynb.txt new file mode 100644 index 00000000..545dac37 --- /dev/null +++ b/2024/_sources/exercise_solutions/exercise_3/exercise_3.2_solution.ipynb.txt @@ -0,0 +1,868 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Exercise 3.2: Split-Apply-Combine of the frog data set\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will continue working with the frog tongue adhesion data set.\n", + "\n", + "\n", + "You'll now practice your split-apply-combine skills. First load in the data set. Then, \n", + "\n", + "**a)** Compute standard deviation of the impact forces for each frog.\n", + "\n", + "**b)** Compute the coefficient of variation of the impact forces *and* adhesive forces for each frog.\n", + "\n", + "**c)** Compute a data frame that has the mean, median, standard deviation, and coefficient of variation of the impact forces and adhesive forces for each frog.\n", + "\n", + "**d)** Now tidy this data frame. It might help to read [the documentation about melting](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.melt.html)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solution\n", + "\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Of course, we start by loading in the data frame." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.read_csv('data/frog_tongue_adhesion.csv', comment='#')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**a)** To compute the standard deviation of impact forces for each frog, we first group by the frog ID and then apply the `std()` method to the `GroupBy` object." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ID\n", + "I 630.207952\n", + "II 424.573256\n", + "III 124.273849\n", + "IV 234.864328\n", + "Name: impact force (mN), dtype: float64" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "grouped = df.groupby('ID')\n", + "\n", + "grouped['impact force (mN)'].std()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We could also do this by method chaining." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ID\n", + "I 630.207952\n", + "II 424.573256\n", + "III 124.273849\n", + "IV 234.864328\n", + "Name: impact force (mN), dtype: float64" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.groupby('ID')['impact force (mN)'].std()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**b)** We first write a function to compute the coefficient of variation. We saw this in our [lesson on tidy data and split-apply-combine](l17_split_apply_combine.ipynb)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def coeff_of_var(data):\n", + " \"\"\"Coefficient of variation.\"\"\"\n", + " return np.std(data) / np.abs(np.mean(data))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we group the data frame with by the ID column." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "grouped = df.groupby('ID')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we select the columns of interest and apply the `coeff_of_var()` aggregating function." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "df_cv = grouped[['impact force (mN)', 'adhesive force (mN)']].agg(coeff_of_var)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we reset the index to get our resulting data frame." + ] + }, + { + "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", + "
IDimpact force (mN)adhesive force (mN)
0I0.4014190.247435
1II0.5850330.429701
2III0.2201910.415435
3IV0.5462120.308042
\n", + "
" + ], + "text/plain": [ + " ID impact force (mN) adhesive force (mN)\n", + "0 I 0.401419 0.247435\n", + "1 II 0.585033 0.429701\n", + "2 III 0.220191 0.415435\n", + "3 IV 0.546212 0.308042" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_cv.reset_index()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Again, we could do this in one line by method chaining." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "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", + "
IDimpact force (mN)adhesive force (mN)
0I0.4014190.247435
1II0.5850330.429701
2III0.2201910.415435
3IV0.5462120.308042
\n", + "
" + ], + "text/plain": [ + " ID impact force (mN) adhesive force (mN)\n", + "0 I 0.401419 0.247435\n", + "1 II 0.585033 0.429701\n", + "2 III 0.220191 0.415435\n", + "3 IV 0.546212 0.308042" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.groupby(\"ID\")[[\"impact force (mN)\", \"adhesive force (mN)\"]].agg(\n", + " coeff_of_var\n", + ").reset_index()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**c)** Now we will apply all of the statistical functions to the impact force and adhesive force. This is as simple as using a list of aggregating functions in the `agg()` method of the `GroupBy` object." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "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", + "
IDimpact force (mN)adhesive force (mN)
meanmedianstdcoeff_of_varmeanmedianstdcoeff_of_var
0I1530.201550.5630.2079520.401419-658.40-664.5167.1436190.247435
1II707.35573.0424.5732560.585033-462.30-517.0203.8116000.429701
2III550.10544.0124.2738490.220191-206.75-201.588.1224480.415435
3IV419.10460.5234.8643280.546212-263.60-233.583.3094420.308042
\n", + "
" + ], + "text/plain": [ + " ID impact force (mN) adhesive force (mN) \\\n", + " mean median std coeff_of_var mean \n", + "0 I 1530.20 1550.5 630.207952 0.401419 -658.40 \n", + "1 II 707.35 573.0 424.573256 0.585033 -462.30 \n", + "2 III 550.10 544.0 124.273849 0.220191 -206.75 \n", + "3 IV 419.10 460.5 234.864328 0.546212 -263.60 \n", + "\n", + " \n", + " median std coeff_of_var \n", + "0 -664.5 167.143619 0.247435 \n", + "1 -517.0 203.811600 0.429701 \n", + "2 -201.5 88.122448 0.415435 \n", + "3 -233.5 83.309442 0.308042 " + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_result = (\n", + " df.groupby(\"ID\")[[\"impact force (mN)\", \"adhesive force (mN)\"]]\n", + " .agg(['mean', 'median', 'std', coeff_of_var])\n", + " .reset_index()\n", + ")\n", + "\n", + "# Take a look\n", + "df_result" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**d)** We can index these things using the `MultiIndex` of the columns, but we much prefer tidy data frames, which we can generate again use `pd.melt()`. The `var_name` kwarg specifies what we name the levels of the `MultiIndex`, and the `id_vars` kwarg tells us which column to keep as it is." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "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", + "
IDquantitystatisticvalue
0Iimpact force (mN)mean1530.200000
1IIimpact force (mN)mean707.350000
2IIIimpact force (mN)mean550.100000
3IVimpact force (mN)mean419.100000
4Iimpact force (mN)median1550.500000
5IIimpact force (mN)median573.000000
6IIIimpact force (mN)median544.000000
7IVimpact force (mN)median460.500000
8Iimpact force (mN)std630.207952
9IIimpact force (mN)std424.573256
10IIIimpact force (mN)std124.273849
11IVimpact force (mN)std234.864328
12Iimpact force (mN)coeff_of_var0.401419
13IIimpact force (mN)coeff_of_var0.585033
14IIIimpact force (mN)coeff_of_var0.220191
15IVimpact force (mN)coeff_of_var0.546212
16Iadhesive force (mN)mean-658.400000
17IIadhesive force (mN)mean-462.300000
18IIIadhesive force (mN)mean-206.750000
19IVadhesive force (mN)mean-263.600000
20Iadhesive force (mN)median-664.500000
21IIadhesive force (mN)median-517.000000
22IIIadhesive force (mN)median-201.500000
23IVadhesive force (mN)median-233.500000
24Iadhesive force (mN)std167.143619
25IIadhesive force (mN)std203.811600
26IIIadhesive force (mN)std88.122448
27IVadhesive force (mN)std83.309442
28Iadhesive force (mN)coeff_of_var0.247435
29IIadhesive force (mN)coeff_of_var0.429701
30IIIadhesive force (mN)coeff_of_var0.415435
31IVadhesive force (mN)coeff_of_var0.308042
\n", + "
" + ], + "text/plain": [ + " ID quantity statistic value\n", + "0 I impact force (mN) mean 1530.200000\n", + "1 II impact force (mN) mean 707.350000\n", + "2 III impact force (mN) mean 550.100000\n", + "3 IV impact force (mN) mean 419.100000\n", + "4 I impact force (mN) median 1550.500000\n", + "5 II impact force (mN) median 573.000000\n", + "6 III impact force (mN) median 544.000000\n", + "7 IV impact force (mN) median 460.500000\n", + "8 I impact force (mN) std 630.207952\n", + "9 II impact force (mN) std 424.573256\n", + "10 III impact force (mN) std 124.273849\n", + "11 IV impact force (mN) std 234.864328\n", + "12 I impact force (mN) coeff_of_var 0.401419\n", + "13 II impact force (mN) coeff_of_var 0.585033\n", + "14 III impact force (mN) coeff_of_var 0.220191\n", + "15 IV impact force (mN) coeff_of_var 0.546212\n", + "16 I adhesive force (mN) mean -658.400000\n", + "17 II adhesive force (mN) mean -462.300000\n", + "18 III adhesive force (mN) mean -206.750000\n", + "19 IV adhesive force (mN) mean -263.600000\n", + "20 I adhesive force (mN) median -664.500000\n", + "21 II adhesive force (mN) median -517.000000\n", + "22 III adhesive force (mN) median -201.500000\n", + "23 IV adhesive force (mN) median -233.500000\n", + "24 I adhesive force (mN) std 167.143619\n", + "25 II adhesive force (mN) std 203.811600\n", + "26 III adhesive force (mN) std 88.122448\n", + "27 IV adhesive force (mN) std 83.309442\n", + "28 I adhesive force (mN) coeff_of_var 0.247435\n", + "29 II adhesive force (mN) coeff_of_var 0.429701\n", + "30 III adhesive force (mN) coeff_of_var 0.415435\n", + "31 IV adhesive force (mN) coeff_of_var 0.308042" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Melt the DataFrame to make it tidy\n", + "pd.melt(df_result, id_vars=[(\"ID\", \"\")]).rename(\n", + " columns={(\"ID\", \"\"): \"ID\", \"variable_0\": \"quantity\", \"variable_1\": \"statistic\"}\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Computing environment" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Python implementation: CPython\n", + "Python version : 3.11.9\n", + "IPython version : 8.20.0\n", + "\n", + "numpy : 1.26.4\n", + "pandas : 2.2.1\n", + "jupyterlab: 4.0.13\n", + "\n" + ] + } + ], + "source": [ + "%load_ext watermark\n", + "%watermark -v -p numpy,pandas,jupyterlab" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/2024/_sources/exercise_solutions/exercise_3/exercise_3.3_solution.ipynb.txt b/2024/_sources/exercise_solutions/exercise_3/exercise_3.3_solution.ipynb.txt new file mode 100644 index 00000000..be55a01c --- /dev/null +++ b/2024/_sources/exercise_solutions/exercise_3/exercise_3.3_solution.ipynb.txt @@ -0,0 +1,4201 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Exercise 3.3: Adding data to a data frame\n", + "\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "\n", + "We continue working with the frog tongue data. Recall that the header comments in the data file contained information about the frogs." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# These data are from the paper,\n", + "# Kleinteich and Gorb, Sci. Rep., 4, 5225, 2014.\n", + "# It was featured in the New York Times.\n", + "# http://www.nytimes.com/2014/08/25/science/a-frog-thats-a-living-breathing-pac-man.html\n", + "#\n", + "# The authors included the data in their supplemental information.\n", + "#\n", + "# Importantly, the ID refers to the identifites of the frogs they tested.\n", + "# I: adult, 63 mm snout-vent-length (SVL) and 63.1 g body weight,\n", + "# Ceratophrys cranwelli crossed with Ceratophrys cornuta\n", + "# II: adult, 70 mm SVL and 72.7 g body weight,\n", + "# Ceratophrys cranwelli crossed with Ceratophrys cornuta\n", + "# III: juvenile, 28 mm SVL and 12.7 g body weight, Ceratophrys cranwelli\n", + "# IV: juvenile, 31 mm SVL and 12.7 g body weight, Ceratophrys cranwelli\n", + "date,ID,trial number,impact force (mN),impact time (ms),impact force / body weight,adhesive force (mN),time frog pulls on target (ms),adhesive force / body weight,adhesive impulse (N-s),total contact area (mm2),contact area without mucus (mm2),contact area with mucus / contact area without mucus,contact pressure (Pa),adhesive strength (Pa)\n", + "2013_02_26,I,3,1205,46,1.95,-785,884,1.27,-0.290,387,70,0.82,3117,-2030\n", + "2013_02_26,I,4,2527,44,4.08,-983,248,1.59,-0.181,101,94,0.07,24923,-9695\n", + "2013_03_01,I,1,1745,34,2.82,-850,211,1.37,-0.157,83,79,0.05,21020,-10239\n", + "2013_03_01,I,2,1556,41,2.51,-455,1025,0.74,-0.170,330,158,0.52,4718,-1381\n", + "2013_03_01,I,3,493,36,0.80,-974,499,1.57,-0.423,245,216,0.12,2012,-3975\n" + ] + } + ], + "source": [ + "!head -20 data/frog_tongue_adhesion.csv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So, each frog has associated with it an age (adult or juvenile), snout-vent-length (SVL), body weight, and species (either cross or *cranwelli*). For a tidy data frame, we should have a column for each of these values. Your task is to load in the data, and then add these columns to the data frame. For convenience, here is a data frame with data about each frog." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "df_frog = pd.DataFrame(\n", + " data={\n", + " \"ID\": [\"I\", \"II\", \"III\", \"IV\"],\n", + " \"age\": [\"adult\", \"adult\", \"juvenile\", \"juvenile\"],\n", + " \"SVL (mm)\": [63, 70, 28, 31],\n", + " \"weight (g)\": [63.1, 72.7, 12.7, 12.7],\n", + " \"species\": [\"cross\", \"cross\", \"cranwelli\", \"cranwelli\"],\n", + " }\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note: There are lots of ways to solve this problem. This is a good exercise in searching through the [Pandas documentation](https://pandas.pydata.org/pandas-docs/stable/) and other online resources, such as [Stack Overflow](https://stackoverflow.com/questions). Remember, much of your programming efforts are spent searching through documentation and the internet.\n", + "\n", + "Finally, as a fun challenge, see if you can highlight the strike with the highest impact force for each frog in the data frame." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solution\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The most direct way is to use [built-in pd.merge() function](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.merge.html). This function finds a common column between two `DataFrames`, and then uses that column to merge them, filling in values that match in the common column. This is exactly what we want." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Load the data\n", + "df = pd.read_csv('data/frog_tongue_adhesion.csv', comment='#')\n", + "\n", + "# Perform merge\n", + "df = df.merge(df_frog)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's look at the `DataFrame` to make sure it has what we expect." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "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", + "
dateIDtrial numberimpact force (mN)impact time (ms)impact force / body weightadhesive force (mN)time frog pulls on target (ms)adhesive force / body weightadhesive impulse (N-s)total contact area (mm2)contact area without mucus (mm2)contact area with mucus / contact area without mucuscontact pressure (Pa)adhesive strength (Pa)ageSVL (mm)weight (g)species
02013_02_26I31205461.95-7858841.27-0.290387700.823117-2030adult6363.1cross
12013_02_26I42527444.08-9832481.59-0.181101940.0724923-9695adult6363.1cross
22013_03_01I11745342.82-8502111.37-0.15783790.0521020-10239adult6363.1cross
32013_03_01I21556412.51-45510250.74-0.1703301580.524718-1381adult6363.1cross
42013_03_01I3493360.80-9744991.57-0.4232452160.122012-3975adult6363.1cross
\n", + "
" + ], + "text/plain": [ + " date ID trial number impact force (mN) impact time (ms) \\\n", + "0 2013_02_26 I 3 1205 46 \n", + "1 2013_02_26 I 4 2527 44 \n", + "2 2013_03_01 I 1 1745 34 \n", + "3 2013_03_01 I 2 1556 41 \n", + "4 2013_03_01 I 3 493 36 \n", + "\n", + " impact force / body weight adhesive force (mN) \\\n", + "0 1.95 -785 \n", + "1 4.08 -983 \n", + "2 2.82 -850 \n", + "3 2.51 -455 \n", + "4 0.80 -974 \n", + "\n", + " time frog pulls on target (ms) adhesive force / body weight \\\n", + "0 884 1.27 \n", + "1 248 1.59 \n", + "2 211 1.37 \n", + "3 1025 0.74 \n", + "4 499 1.57 \n", + "\n", + " adhesive impulse (N-s) total contact area (mm2) \\\n", + "0 -0.290 387 \n", + "1 -0.181 101 \n", + "2 -0.157 83 \n", + "3 -0.170 330 \n", + "4 -0.423 245 \n", + "\n", + " contact area without mucus (mm2) \\\n", + "0 70 \n", + "1 94 \n", + "2 79 \n", + "3 158 \n", + "4 216 \n", + "\n", + " contact area with mucus / contact area without mucus \\\n", + "0 0.82 \n", + "1 0.07 \n", + "2 0.05 \n", + "3 0.52 \n", + "4 0.12 \n", + "\n", + " contact pressure (Pa) adhesive strength (Pa) age SVL (mm) weight (g) \\\n", + "0 3117 -2030 adult 63 63.1 \n", + "1 24923 -9695 adult 63 63.1 \n", + "2 21020 -10239 adult 63 63.1 \n", + "3 4718 -1381 adult 63 63.1 \n", + "4 2012 -3975 adult 63 63.1 \n", + "\n", + " species \n", + "0 cross \n", + "1 cross \n", + "2 cross \n", + "3 cross \n", + "4 cross " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we can highlight the strike with the highest impact force for each frog. One way to do this is to write a function that returns an entire data frame with the same index and columns as `df` where each entry contains a formatting string like `'background-color: lightgray'`, and then use `df.style.apply()` with the `axis=None` kwarg." + ] + }, + { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 dateIDtrial numberimpact force (mN)impact time (ms)impact force / body weightadhesive force (mN)time frog pulls on target (ms)adhesive force / body weightadhesive impulse (N-s)total contact area (mm2)contact area without mucus (mm2)contact area with mucus / contact area without mucuscontact pressure (Pa)adhesive strength (Pa)ageSVL (mm)weight (g)species
02013_02_26I31205461.950000-7858841.270000-0.290000387700.8200003117-2030adult6363.100000cross
12013_02_26I42527444.080000-9832481.590000-0.181000101940.07000024923-9695adult6363.100000cross
22013_03_01I11745342.820000-8502111.370000-0.15700083790.05000021020-10239adult6363.100000cross
32013_03_01I21556412.510000-45510250.740000-0.1700003301580.5200004718-1381adult6363.100000cross
42013_03_01I3493360.800000-9744991.570000-0.4230002452160.1200002012-3975adult6363.100000cross
52013_03_01I42276313.680000-5929690.960000-0.1760003411060.6900006676-1737adult6363.100000cross
62013_03_05I1556430.900000-5128350.830000-0.2850003591100.6900001550-1427adult6363.100000cross
72013_03_05I21928463.110000-8045081.300000-0.2850002461780.2800007832-3266adult6363.100000cross
82013_03_05I32641504.270000-6904911.120000-0.2390002692240.1700009824-2568adult6363.100000cross
92013_03_05I41897413.060000-4628390.750000-0.3280002661760.3400007122-1733adult6363.100000cross
102013_03_12I11891403.060000-76610691.240000-0.380000408330.9200004638-1879adult6363.100000cross
112013_03_12I21545482.500000-7156491.150000-0.2980001411120.21000010947-5064adult6363.100000cross
122013_03_12I31307292.110000-61318450.990000-0.768000455920.8000002874-1348adult6363.100000cross
132013_03_12I41692312.730000-6779171.090000-0.4570001861290.3100009089-3636adult6363.100000cross
142013_03_12I51543382.490000-5287500.850000-0.3530001531480.03000010095-3453adult6363.100000cross
152013_03_15I11282312.070000-4527850.730000-0.2530002901050.6400004419-1557adult6363.100000cross
162013_03_15I2775341.250000-4308370.700000-0.2760002571240.5200003019-1677adult6363.100000cross
172013_03_15I32032603.280000-6524861.050000-0.2570001471340.09000013784-4425adult6363.100000cross
182013_03_15I41240342.000000-6929061.120000-0.3170003642600.2800003406-1901adult6363.100000cross
192013_03_15I5473400.760000-53612180.870000-0.3820002591680.3500001830-2073adult6363.100000cross
202013_03_19II11612183.790000-65530871.540000-0.385000348150.9600004633-1881adult7072.700000cross
212013_03_19II2605551.420000-29212610.690000-0.294000248240.9000002441-1177adult7072.700000cross
222013_03_19II3327510.770000-24615080.580000-0.282000130340.7400002517-1894adult7072.700000cross
232013_03_19II4946592.230000-24518410.580000-0.340000106260.7600008893-2301adult7072.700000cross
242013_03_21II1541331.270000-55331261.300000-0.432000276160.9400001959-2004adult7072.700000cross
252013_03_21II21539433.620000-6647411.560000-0.04600085240.72000018073-7802adult7072.700000cross
262013_03_21II3529281.240000-26124820.610000-0.414000325330.9000001627-803adult7072.700000cross
272013_03_21II4628311.480000-6919981.630000-0.071000242670.7200002600-2860adult7072.700000cross
282013_03_25II11453723.420000-9216520.220000-0.00800013601.00000010645-678adult7072.700000cross
292013_03_25II2297420.700000-5669361.330000-0.08400012640.9700002367-4506adult7072.700000cross
302013_03_25II3703331.650000-22321520.520000-0.20900023780.9700002972-942adult7072.700000cross
312013_03_25II4269570.630000-5121891.200000-0.05500029280.0300009279-17652adult7072.700000cross
322013_03_28II1751391.770000-22711950.530000-0.02600020601.0000003647-1101adult7072.700000cross
332013_03_28II2245210.580000-57314661.350000-0.215000190460.7600001288-3014adult7072.700000cross
342013_04_03II11182282.780000-52211971.230000-0.11800028101.0000004213-1860adult7072.700000cross
352013_04_03II2515291.210000-59914861.410000-0.22600021701.0000002369-2757adult7072.700000cross
362013_04_08II1435261.020000-36410170.860000-0.211000189890.5300002302-1927adult7072.700000cross
372013_04_08II2383310.900000-4699741.100000-0.260000221720.6700001737-2129adult7072.700000cross
382013_04_08II3457151.080000-8447801.990000-0.3280001711060.3800002665-4925adult7072.700000cross
392013_04_12II1730421.720000-6487861.520000-0.121000142430.7000005149-4573adult7072.700000cross
402013_05_27III1614884.940000-946830.760000-0.00100097150.8300006326-967juvenile2812.700000cranwelli
412013_05_27III24141433.330000-1632451.310000-0.032000108100.6000003824-1507juvenile2812.700000cranwelli
422013_05_27III33241052.610000-1726191.380000-0.07900055230.3700005946-3149juvenile2812.700000cranwelli
432013_06_11III1776356.240000-22518231.810000-0.132000124170.7700006272-1818juvenile2812.700000cranwelli
442013_06_11III2611294.910000-3019182.420000-0.155000128430.0200004770-2354juvenile2812.700000cranwelli
452013_06_11III3544164.380000-9313510.750000-0.11000043340.71000012699-2181juvenile2812.700000cranwelli
462013_06_14III1538384.320000-13117901.050000-0.036000130741.0000004130-1005juvenile2812.700000cranwelli
472013_06_14III2579314.660000-28910062.330000-0.07300011340.4800005110-2555juvenile2812.700000cranwelli
482013_06_18III1806296.490000-1048830.840000-0.055000115550.6600006993-902juvenile2812.700000cranwelli
492013_06_18III2459323.700000-22912181.850000-0.1370008960.9500005165-2580juvenile2812.700000cranwelli
502013_06_18III3458303.690000-2599102.080000-0.19400091880.1500005048-2855juvenile2812.700000cranwelli
512013_06_18III4626165.040000-2315501.860000-0.04200082230.0100007633-2819juvenile2812.700000cranwelli
522013_06_21III1621274.990000-26720812.140000-0.183000120580.9000005152-2213juvenile2812.700000cranwelli
532013_06_21III2544304.380000-1783761.430000-0.03400019170.05000028641-9364juvenile2812.700000cranwelli
542013_06_21III3535354.300000-1232890.990000-0.02900021290.05000025471-5843juvenile2812.700000cranwelli
552013_06_21III4385393.090000-1516071.220000-0.082000311260.03000012409-4882juvenile2812.700000cranwelli
562013_06_26III1401363.230000-12729321.020000-0.215000142120.8600002835-896juvenile2812.700000cranwelli
572013_06_26III2614344.940000-3726802.990000-0.1400007210.4200008475-5136juvenile2812.700000cranwelli
582013_06_26III3665405.350000-2366851.900000-0.11800012900.1600005171-1834juvenile2812.700000cranwelli
592013_06_26III4488343.930000-39013083.140000-0.208000112580.3900004376-3492juvenile2812.700000cranwelli
602013_05_27IV2172261.280000-4564623.400000-0.05000013300.8800001297-3440juvenile3112.700000cranwelli
612013_05_27IV3142201.050000-1932501.440000-0.04700057740.8300002498-3400juvenile3112.700000cranwelli
622013_05_27IV437550.280000-2367431.760000-0.11900051440.540000735-4647juvenile3112.700000cranwelli
632013_05_30IV1453383.370000-2258441.680000-0.1100001421080.4800003177-1581juvenile3112.700000cranwelli
642013_05_30IV2355312.640000-2177281.610000-0.023000174390.9800002037-1245juvenile3112.700000cranwelli
652013_05_30IV322330.170000-1614721.200000-0.0520005640.020000397-2866juvenile3112.700000cranwelli
662013_06_03IV1502743.740000-1399591.040000-0.08900065770.9100007713-2141juvenile3112.700000cranwelli
672013_06_11IV1273262.030000-2648441.970000-0.160000124810.2900002205-2136juvenile3112.700000cranwelli
682013_06_11IV2720275.360000-34215152.550000-0.22600013700.8300005259-2497juvenile3112.700000cranwelli
692013_06_11IV3582334.340000-2312791.720000-0.0330006040.0300009705-3847juvenile3112.700000cranwelli
702013_06_11IV4198231.470000-20914271.550000-0.151000110690.8400001793-1889juvenile3112.700000cranwelli
712013_06_14IV119861.470000-29228742.170000-0.232000145500.9900001369-2018juvenile3112.700000cranwelli
722013_06_18IV1597294.440000-33942512.530000-0.281000191121.0000003116-1772juvenile3112.700000cranwelli
732013_06_18IV2516313.840000-3716262.760000-0.09400083180.1200006184-4447juvenile3112.700000cranwelli
742013_06_18IV3815346.070000-33112542.470000-0.077000151200.7100005386-2190juvenile3112.700000cranwelli
752013_06_18IV4402383.000000-3029862.250000-0.122000117300.0700003446-2591juvenile3112.700000cranwelli
762013_06_21IV1605394.500000-21616271.610000-0.139000123201.0000004928-1759juvenile3112.700000cranwelli
772013_06_21IV2711765.300000-16320211.210000-0.217000129420.9700005498-1257juvenile3112.700000cranwelli
782013_06_21IV3614334.570000-36713662.730000-0.1980001281080.4600004776-2857juvenile3112.700000cranwelli
792013_06_21IV4468363.480000-21812691.630000-0.122000129680.6100003617-1688juvenile3112.700000cranwelli
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def highlight_max(df):\n", + " # Make full data frame with all strings being light gray bg color\n", + " highlight_df = pd.DataFrame(\n", + " \"background-color: lightgray\", index=df.index, columns=df.columns\n", + " )\n", + " \n", + " # Which rows contain a maximum force\n", + " has_max_force = (\n", + " df.groupby(\"ID\")[\"impact force (mN)\"]\n", + " .transform(\"max\")\n", + " .eq(df[\"impact force (mN)\"])\n", + " )\n", + " \n", + " # Color rows with maximum force green\n", + " highlight_df.loc[has_max_force, :] = 'background-color: #7fc97f'\n", + " \n", + " return highlight_df\n", + "\n", + "df.style.apply(highlight_max, axis=None)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "While this works and does not require adding anything to the data frame, I think it is more concise to simply add a column that is a Boolean stating whether or not the row contains a maximum impact force and then using this column to determine how each row is shaded." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext blackcellmagic" + ] + }, + { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 dateIDtrial numberimpact force (mN)impact time (ms)impact force / body weightadhesive force (mN)time frog pulls on target (ms)adhesive force / body weightadhesive impulse (N-s)total contact area (mm2)contact area without mucus (mm2)contact area with mucus / contact area without mucuscontact pressure (Pa)adhesive strength (Pa)ageSVL (mm)weight (g)speciesmax_strike
02013_02_26I31205461.950000-7858841.270000-0.290000387700.8200003117-2030adult6363.100000crossFalse
12013_02_26I42527444.080000-9832481.590000-0.181000101940.07000024923-9695adult6363.100000crossFalse
22013_03_01I11745342.820000-8502111.370000-0.15700083790.05000021020-10239adult6363.100000crossFalse
32013_03_01I21556412.510000-45510250.740000-0.1700003301580.5200004718-1381adult6363.100000crossFalse
42013_03_01I3493360.800000-9744991.570000-0.4230002452160.1200002012-3975adult6363.100000crossFalse
52013_03_01I42276313.680000-5929690.960000-0.1760003411060.6900006676-1737adult6363.100000crossFalse
62013_03_05I1556430.900000-5128350.830000-0.2850003591100.6900001550-1427adult6363.100000crossFalse
72013_03_05I21928463.110000-8045081.300000-0.2850002461780.2800007832-3266adult6363.100000crossFalse
82013_03_05I32641504.270000-6904911.120000-0.2390002692240.1700009824-2568adult6363.100000crossTrue
92013_03_05I41897413.060000-4628390.750000-0.3280002661760.3400007122-1733adult6363.100000crossFalse
102013_03_12I11891403.060000-76610691.240000-0.380000408330.9200004638-1879adult6363.100000crossFalse
112013_03_12I21545482.500000-7156491.150000-0.2980001411120.21000010947-5064adult6363.100000crossFalse
122013_03_12I31307292.110000-61318450.990000-0.768000455920.8000002874-1348adult6363.100000crossFalse
132013_03_12I41692312.730000-6779171.090000-0.4570001861290.3100009089-3636adult6363.100000crossFalse
142013_03_12I51543382.490000-5287500.850000-0.3530001531480.03000010095-3453adult6363.100000crossFalse
152013_03_15I11282312.070000-4527850.730000-0.2530002901050.6400004419-1557adult6363.100000crossFalse
162013_03_15I2775341.250000-4308370.700000-0.2760002571240.5200003019-1677adult6363.100000crossFalse
172013_03_15I32032603.280000-6524861.050000-0.2570001471340.09000013784-4425adult6363.100000crossFalse
182013_03_15I41240342.000000-6929061.120000-0.3170003642600.2800003406-1901adult6363.100000crossFalse
192013_03_15I5473400.760000-53612180.870000-0.3820002591680.3500001830-2073adult6363.100000crossFalse
202013_03_19II11612183.790000-65530871.540000-0.385000348150.9600004633-1881adult7072.700000crossTrue
212013_03_19II2605551.420000-29212610.690000-0.294000248240.9000002441-1177adult7072.700000crossFalse
222013_03_19II3327510.770000-24615080.580000-0.282000130340.7400002517-1894adult7072.700000crossFalse
232013_03_19II4946592.230000-24518410.580000-0.340000106260.7600008893-2301adult7072.700000crossFalse
242013_03_21II1541331.270000-55331261.300000-0.432000276160.9400001959-2004adult7072.700000crossFalse
252013_03_21II21539433.620000-6647411.560000-0.04600085240.72000018073-7802adult7072.700000crossFalse
262013_03_21II3529281.240000-26124820.610000-0.414000325330.9000001627-803adult7072.700000crossFalse
272013_03_21II4628311.480000-6919981.630000-0.071000242670.7200002600-2860adult7072.700000crossFalse
282013_03_25II11453723.420000-9216520.220000-0.00800013601.00000010645-678adult7072.700000crossFalse
292013_03_25II2297420.700000-5669361.330000-0.08400012640.9700002367-4506adult7072.700000crossFalse
302013_03_25II3703331.650000-22321520.520000-0.20900023780.9700002972-942adult7072.700000crossFalse
312013_03_25II4269570.630000-5121891.200000-0.05500029280.0300009279-17652adult7072.700000crossFalse
322013_03_28II1751391.770000-22711950.530000-0.02600020601.0000003647-1101adult7072.700000crossFalse
332013_03_28II2245210.580000-57314661.350000-0.215000190460.7600001288-3014adult7072.700000crossFalse
342013_04_03II11182282.780000-52211971.230000-0.11800028101.0000004213-1860adult7072.700000crossFalse
352013_04_03II2515291.210000-59914861.410000-0.22600021701.0000002369-2757adult7072.700000crossFalse
362013_04_08II1435261.020000-36410170.860000-0.211000189890.5300002302-1927adult7072.700000crossFalse
372013_04_08II2383310.900000-4699741.100000-0.260000221720.6700001737-2129adult7072.700000crossFalse
382013_04_08II3457151.080000-8447801.990000-0.3280001711060.3800002665-4925adult7072.700000crossFalse
392013_04_12II1730421.720000-6487861.520000-0.121000142430.7000005149-4573adult7072.700000crossFalse
402013_05_27III1614884.940000-946830.760000-0.00100097150.8300006326-967juvenile2812.700000cranwelliFalse
412013_05_27III24141433.330000-1632451.310000-0.032000108100.6000003824-1507juvenile2812.700000cranwelliFalse
422013_05_27III33241052.610000-1726191.380000-0.07900055230.3700005946-3149juvenile2812.700000cranwelliFalse
432013_06_11III1776356.240000-22518231.810000-0.132000124170.7700006272-1818juvenile2812.700000cranwelliFalse
442013_06_11III2611294.910000-3019182.420000-0.155000128430.0200004770-2354juvenile2812.700000cranwelliFalse
452013_06_11III3544164.380000-9313510.750000-0.11000043340.71000012699-2181juvenile2812.700000cranwelliFalse
462013_06_14III1538384.320000-13117901.050000-0.036000130741.0000004130-1005juvenile2812.700000cranwelliFalse
472013_06_14III2579314.660000-28910062.330000-0.07300011340.4800005110-2555juvenile2812.700000cranwelliFalse
482013_06_18III1806296.490000-1048830.840000-0.055000115550.6600006993-902juvenile2812.700000cranwelliTrue
492013_06_18III2459323.700000-22912181.850000-0.1370008960.9500005165-2580juvenile2812.700000cranwelliFalse
502013_06_18III3458303.690000-2599102.080000-0.19400091880.1500005048-2855juvenile2812.700000cranwelliFalse
512013_06_18III4626165.040000-2315501.860000-0.04200082230.0100007633-2819juvenile2812.700000cranwelliFalse
522013_06_21III1621274.990000-26720812.140000-0.183000120580.9000005152-2213juvenile2812.700000cranwelliFalse
532013_06_21III2544304.380000-1783761.430000-0.03400019170.05000028641-9364juvenile2812.700000cranwelliFalse
542013_06_21III3535354.300000-1232890.990000-0.02900021290.05000025471-5843juvenile2812.700000cranwelliFalse
552013_06_21III4385393.090000-1516071.220000-0.082000311260.03000012409-4882juvenile2812.700000cranwelliFalse
562013_06_26III1401363.230000-12729321.020000-0.215000142120.8600002835-896juvenile2812.700000cranwelliFalse
572013_06_26III2614344.940000-3726802.990000-0.1400007210.4200008475-5136juvenile2812.700000cranwelliFalse
582013_06_26III3665405.350000-2366851.900000-0.11800012900.1600005171-1834juvenile2812.700000cranwelliFalse
592013_06_26III4488343.930000-39013083.140000-0.208000112580.3900004376-3492juvenile2812.700000cranwelliFalse
602013_05_27IV2172261.280000-4564623.400000-0.05000013300.8800001297-3440juvenile3112.700000cranwelliFalse
612013_05_27IV3142201.050000-1932501.440000-0.04700057740.8300002498-3400juvenile3112.700000cranwelliFalse
622013_05_27IV437550.280000-2367431.760000-0.11900051440.540000735-4647juvenile3112.700000cranwelliFalse
632013_05_30IV1453383.370000-2258441.680000-0.1100001421080.4800003177-1581juvenile3112.700000cranwelliFalse
642013_05_30IV2355312.640000-2177281.610000-0.023000174390.9800002037-1245juvenile3112.700000cranwelliFalse
652013_05_30IV322330.170000-1614721.200000-0.0520005640.020000397-2866juvenile3112.700000cranwelliFalse
662013_06_03IV1502743.740000-1399591.040000-0.08900065770.9100007713-2141juvenile3112.700000cranwelliFalse
672013_06_11IV1273262.030000-2648441.970000-0.160000124810.2900002205-2136juvenile3112.700000cranwelliFalse
682013_06_11IV2720275.360000-34215152.550000-0.22600013700.8300005259-2497juvenile3112.700000cranwelliFalse
692013_06_11IV3582334.340000-2312791.720000-0.0330006040.0300009705-3847juvenile3112.700000cranwelliFalse
702013_06_11IV4198231.470000-20914271.550000-0.151000110690.8400001793-1889juvenile3112.700000cranwelliFalse
712013_06_14IV119861.470000-29228742.170000-0.232000145500.9900001369-2018juvenile3112.700000cranwelliFalse
722013_06_18IV1597294.440000-33942512.530000-0.281000191121.0000003116-1772juvenile3112.700000cranwelliFalse
732013_06_18IV2516313.840000-3716262.760000-0.09400083180.1200006184-4447juvenile3112.700000cranwelliFalse
742013_06_18IV3815346.070000-33112542.470000-0.077000151200.7100005386-2190juvenile3112.700000cranwelliTrue
752013_06_18IV4402383.000000-3029862.250000-0.122000117300.0700003446-2591juvenile3112.700000cranwelliFalse
762013_06_21IV1605394.500000-21616271.610000-0.139000123201.0000004928-1759juvenile3112.700000cranwelliFalse
772013_06_21IV2711765.300000-16320211.210000-0.217000129420.9700005498-1257juvenile3112.700000cranwelliFalse
782013_06_21IV3614334.570000-36713662.730000-0.1980001281080.4600004776-2857juvenile3112.700000cranwelliFalse
792013_06_21IV4468363.480000-21812691.630000-0.122000129680.6100003617-1688juvenile3112.700000cranwelliFalse
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = df.assign(\n", + " max_strike=df.groupby(\"ID\")[\"impact force (mN)\"]\n", + " .transform(\"max\")\n", + " .eq(df[\"impact force (mN)\"])\n", + ")\n", + "\n", + "\n", + "def highlight_max(s):\n", + " if s[\"max_strike\"]:\n", + " return [\"background-color: #7fc97f\"] * len(s)\n", + " else:\n", + " return [\"background-color: lightgray\"] * len(s)\n", + "\n", + "\n", + "df.style.apply(highlight_max, axis=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Computing environment" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Python implementation: CPython\n", + "Python version : 3.11.9\n", + "IPython version : 8.20.0\n", + "\n", + "pandas : 2.2.1\n", + "jupyterlab: 4.0.13\n", + "\n" + ] + } + ], + "source": [ + "%load_ext watermark\n", + "%watermark -v -p pandas,jupyterlab" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/2024/_sources/exercise_solutions/exercise_3/exercise_3.4_solution.ipynb.txt b/2024/_sources/exercise_solutions/exercise_3/exercise_3.4_solution.ipynb.txt new file mode 100644 index 00000000..c9fbdce8 --- /dev/null +++ b/2024/_sources/exercise_solutions/exercise_3/exercise_3.4_solution.ipynb.txt @@ -0,0 +1,770 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Exercise 3.4: Axes with logarithmic scale and error bars\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Sometimes you need to plot your data with a logarithmic scale. As an example, let's consider the classic genetic switch engineered by Jim Collins and coworkers ([Gardner, et al., *Nature*, **403**, 339, 2000](https://doi.org/10.1038/35002131)). This genetic switch was incorporated into *E. coli* and is inducible by adjusting the concentration of the lactose analog IPTG. The readout is the fluorescence intensity of GFP.\n", + "\n", + "The data set has the IPTG concentrations and GFP fluorescence intensity. The data are in the file `~/git/data/collins_switch.csv`. Let's look at it." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Data digitized from Fig. 5a of Gardner, et al., *Nature*, **403**, 339, 2000. The last column gives the standard error of the mean normalized GFP intensity.\n", + "[IPTG] (mM),normalized GFP expression (a.u.),sem\n", + "0.001000,0.004090,0.003475\n", + "0.010000,0.010225,0.002268\n", + "0.020000,0.022495,0.004781\n", + "0.030000,0.034765,0.003000\n", + "0.040000,0.067485,0.006604\n", + "0.040000,0.668712,0.087862\n", + "0.060000,0.740286,0.045853\n", + "0.100000,0.840491,0.058986\n", + "0.300000,0.936605,0.026931\n", + "0.600000,0.961145,0.093553\n", + "1.000000,0.940695,0.037624\n", + "3.000000,0.852761,0.059035\n", + "6.000000,0.910020,0.051052\n", + "10.000000,0.893661,0.042773\n" + ] + } + ], + "source": [ + "!cat data/collins_switch.csv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It has two rows of non-data. Then, Column 1 is the IPTG concentration, column 2 is the normalized GFP expression level, and the last column is the standard error of the mean normalized GFP intensity. This gives the error bars, which we will plot momentarily. For now, we will just plot IPTG versus normalized GFP intensity.\n", + "\n", + "In looking at the data set, note that there are two entries for [IPTG] = 0.04 mM. At this concentration, the switch happens, and there are two populations of cells, one with high expression of GFP and one with low. The two data points represent these two populations of cells.\n", + "\n", + "**a)** Now, let's make a plot of IPTG versus GFP.\n", + "\n", + "1. Load in the data set using Pandas. Make sure you use the `comment` kwarg of pd.read_csv() properly.\n", + "2. Make a plot of normalized GFP intensity (y-axis) versus IPTG concentration (x-axis).\n", + "\n", + "**b)** Now that you have done that, there are some problems with the plot. It is really hard to see the data points with low concentrations of IPTG. In fact, looking at the data set, the concentration of IPTG varies over four orders of magnitude. When you have data like this, it is wise to plot them on a logarithmic scale. You can specify the x-axis as logarithmic when you instantiate a figure with `bokeh.plotting.figure()` by using the `x_axis_type='log'` kwarg. (The obvious analogous kwarg applied for the y-axis.) For this data set, it is definitely best to have the x-axis on a logarithmic scale. Remake the plot you just did with the x-axis logarithmically scaled.\n", + "\n", + "**c)** The data set also contains the standard error of the mean, or SEM. The SEM is often displayed on plots as error bars. Now construct the plot with error bars.\n", + "\n", + "1. Add columns `error_low` and `error_high` to the data frame containing the Collins data. These will set the bottoms and tops of the error bars. You should base the values in these columns on the standard error of the mean (`sem`). Assuming a Gaussian model, the 95% confidence interval is ±1.96 times the s.e.m.\n", + "2. Make a plot with the measured expression levels and the error bars. *Hint*: Check out the [Bokeh docs](https://bokeh.pydata.org/en/latest/docs/user_guide/plotting.html) and think about what kind of glyph works best for error bars." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solution\n", + "\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + " \n", + "
\n", + " \n", + " Loading BokehJS ...\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "'use strict';\n", + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const 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", + "const JS_MIME_TYPE = 'application/javascript';\n", + " const HTML_MIME_TYPE = 'text/html';\n", + " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " const CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " const 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", + " function drop(id) {\n", + " const view = Bokeh.index.get_by_id(id)\n", + " if (view != null) {\n", + " view.model.document.clear()\n", + " Bokeh.index.delete(view)\n", + " }\n", + " }\n", + "\n", + " const cell = handle.cell;\n", + "\n", + " const id = cell.output_area._bokeh_element_id;\n", + " const server_id = cell.output_area._bokeh_server_id;\n", + "\n", + " // Clean up Bokeh references\n", + " if (id != null) {\n", + " drop(id)\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " const cmd_clean = \"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_clean, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " const id = msg.content.text.trim()\n", + " drop(id)\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd_destroy);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " const output_area = handle.output_area;\n", + " const output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " const 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", + " const bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " const script_attrs = bk_div.children[0].attributes;\n", + " for (let i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\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", + " const 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", + " const 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", + " const events = require('base/js/events');\n", + " const 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", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " const 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", + " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", + " \"
  • use INLINE resources instead, as so:
  • \\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(error = null) {\n", + " const el = document.getElementById(\"a1b7e833-ce1f-4bce-894c-0f7a06de9e36\");\n", + " if (el != null) {\n", + " const html = (() => {\n", + " if (typeof root.Bokeh === \"undefined\") {\n", + " if (error == null) {\n", + " return \"BokehJS is loading ...\";\n", + " } else {\n", + " return \"BokehJS failed to load.\";\n", + " }\n", + " } else {\n", + " const prefix = `BokehJS ${root.Bokeh.version}`;\n", + " if (error == null) {\n", + " return `${prefix} successfully loaded.`;\n", + " } else {\n", + " return `${prefix} encountered errors while loading and may not function as expected.`;\n", + " }\n", + " }\n", + " })();\n", + " el.innerHTML = html;\n", + "\n", + " if (error != null) {\n", + " const wrapper = document.createElement(\"div\");\n", + " wrapper.style.overflow = \"auto\";\n", + " wrapper.style.height = \"5em\";\n", + " wrapper.style.resize = \"vertical\";\n", + " const content = document.createElement(\"div\");\n", + " content.style.fontFamily = \"monospace\";\n", + " content.style.whiteSpace = \"pre-wrap\";\n", + " content.style.backgroundColor = \"rgb(255, 221, 221)\";\n", + " content.textContent = error.stack ?? error.toString();\n", + " wrapper.append(content);\n", + " el.append(wrapper);\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(() => display_loaded(error), 100);\n", + " }\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"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.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error(url) {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.4.1.min.js\"];\n", + " const css_urls = [];\n", + "\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {\n", + " }\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if (root.Bokeh !== undefined || force === true) {\n", + " try {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }\n", + "\n", + " } catch (error) {display_loaded(error);throw error;\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", + " const cell = $(document.getElementById(\"a1b7e833-ce1f-4bce-894c-0f7a06de9e36\")).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "'use strict';\n(function(root) {\n function now() {\n return new Date();\n }\n\n const 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 if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const 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 \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\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(error = null) {\n const el = document.getElementById(\"a1b7e833-ce1f-4bce-894c-0f7a06de9e36\");\n if (el != null) {\n const html = (() => {\n if (typeof root.Bokeh === \"undefined\") {\n if (error == null) {\n return \"BokehJS is loading ...\";\n } else {\n return \"BokehJS failed to load.\";\n }\n } else {\n const prefix = `BokehJS ${root.Bokeh.version}`;\n if (error == null) {\n return `${prefix} successfully loaded.`;\n } else {\n return `${prefix} encountered errors while loading and may not function as expected.`;\n }\n }\n })();\n el.innerHTML = html;\n\n if (error != null) {\n const wrapper = document.createElement(\"div\");\n wrapper.style.overflow = \"auto\";\n wrapper.style.height = \"5em\";\n wrapper.style.resize = \"vertical\";\n const content = document.createElement(\"div\");\n content.style.fontFamily = \"monospace\";\n content.style.whiteSpace = \"pre-wrap\";\n content.style.backgroundColor = \"rgb(255, 221, 221)\";\n content.textContent = error.stack ?? error.toString();\n wrapper.append(content);\n el.append(wrapper);\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(() => display_loaded(error), 100);\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"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.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.4.1.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n try {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n\n } catch (error) {display_loaded(error);throw error;\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 const cell = $(document.getElementById(\"a1b7e833-ce1f-4bce-894c-0f7a06de9e36\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "import bokeh.io\n", + "import bokeh.plotting\n", + "\n", + "bokeh.io.output_notebook()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**a)** The initial plot is straightforward. We load in the data and directly make the plot." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"13f27b34-bc29-46c3-a944-6ee2414dc924\":{\"version\":\"3.4.1\",\"title\":\"Bokeh Application\",\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1001\",\"attributes\":{\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1002\"},\"y_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1003\"},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1010\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1011\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1008\"},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1042\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1033\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1034\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1035\"},\"data\":{\"type\":\"map\",\"entries\":[[\"index\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAA=\"},\"shape\":[14],\"dtype\":\"int32\",\"order\":\"little\"}],[\"[IPTG] (mM)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"/Knx0k1iUD97FK5H4XqEP3sUrkfhepQ/uB6F61G4nj97FK5H4XqkP3sUrkfheqQ/uB6F61G4rj+amZmZmZm5PzMzMzMzM9M/MzMzMzMz4z8AAAAAAADwPwAAAAAAAAhAAAAAAAAAGEAAAAAAAAAkQA==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}],[\"normalized GFP expression (a.u.)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"VKnZA63AcD+pE9BE2PCEP9RIS+XtCJc/6UMX1LfMoT+fdvhrskaxPwYrTrUWZuU/Fvn1Q2yw5z9/orJhTeXqP3+kiAyr+O0/b9i2KLPB7j/RV5BmLBruP3e8yW/RSes/5pZWQ+Ie7T+yvRb03pjsPw==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}],[\"sem\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"8rBQa5p3bD+SeHk6V5RiP1daRuo9lXM/+n5qvHSTaD/BUl3Aywx7P6inj8AffrY/a9PYXgt6pz+C/de5aTOuP7WK/tDMk5s/AFRx4xbztz9x4xbzc0OjPyeDo+TVOa4/0nDK3Hwjqj/HuU24V+alPw==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1043\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1044\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1039\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y\":{\"type\":\"field\",\"field\":\"normalized GFP expression (a.u.)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1040\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y\":{\"type\":\"field\",\"field\":\"normalized GFP expression (a.u.)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1041\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y\":{\"type\":\"field\",\"field\":\"normalized GFP expression (a.u.)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1009\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1022\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1023\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1024\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1025\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1030\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1031\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1032\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1017\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1018\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1019\"},\"axis_label\":\"normalized GFP expression (a.u.)\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1020\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1012\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1013\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1014\"},\"axis_label\":\"[IPTG] (mM)\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1015\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1016\",\"attributes\":{\"axis\":{\"id\":\"p1012\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1021\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1017\"}}}],\"frame_width\":450,\"frame_height\":300}}]}};\n", + " const render_items = [{\"docid\":\"13f27b34-bc29-46c3-a944-6ee2414dc924\",\"roots\":{\"p1001\":\"e054d13a-d512-4f51-baec-5e365023a32a\"},\"root_ids\":[\"p1001\"]}];\n", + " void root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1001" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "# Load in the data\n", + "df = pd.read_csv('data/collins_switch.csv', comment='#')\n", + "\n", + "# For convenience\n", + "x = '[IPTG] (mM)'\n", + "y = 'normalized GFP expression (a.u.)'\n", + "\n", + "# Make the plot\n", + "p = bokeh.plotting.figure(\n", + " frame_height=300,\n", + " frame_width=450,\n", + " x_axis_label=x,\n", + " y_axis_label=y,\n", + ")\n", + "\n", + "p.scatter(\n", + " source=df,\n", + " x=x,\n", + " y=y,\n", + ")\n", + "\n", + "bokeh.io.show(p)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**b)** We clearly need the $x$-axis to be on a log scale, so let's remake the plot." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"8dfd08c8-52d1-49a6-be16-821dd0c918f0\":{\"version\":\"3.4.1\",\"title\":\"Bokeh Application\",\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1049\",\"attributes\":{\"width\":450,\"height\":300,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1050\"},\"y_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1051\"},\"x_scale\":{\"type\":\"object\",\"name\":\"LogScale\",\"id\":\"p1058\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1059\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1056\"},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1090\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1081\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1082\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1083\"},\"data\":{\"type\":\"map\",\"entries\":[[\"index\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAA=\"},\"shape\":[14],\"dtype\":\"int32\",\"order\":\"little\"}],[\"[IPTG] (mM)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"/Knx0k1iUD97FK5H4XqEP3sUrkfhepQ/uB6F61G4nj97FK5H4XqkP3sUrkfheqQ/uB6F61G4rj+amZmZmZm5PzMzMzMzM9M/MzMzMzMz4z8AAAAAAADwPwAAAAAAAAhAAAAAAAAAGEAAAAAAAAAkQA==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}],[\"normalized GFP expression (a.u.)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"VKnZA63AcD+pE9BE2PCEP9RIS+XtCJc/6UMX1LfMoT+fdvhrskaxPwYrTrUWZuU/Fvn1Q2yw5z9/orJhTeXqP3+kiAyr+O0/b9i2KLPB7j/RV5BmLBruP3e8yW/RSes/5pZWQ+Ie7T+yvRb03pjsPw==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}],[\"sem\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"8rBQa5p3bD+SeHk6V5RiP1daRuo9lXM/+n5qvHSTaD/BUl3Aywx7P6inj8AffrY/a9PYXgt6pz+C/de5aTOuP7WK/tDMk5s/AFRx4xbztz9x4xbzc0OjPyeDo+TVOa4/0nDK3Hwjqj/HuU24V+alPw==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1091\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1092\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1087\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y\":{\"type\":\"field\",\"field\":\"normalized GFP expression (a.u.)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1088\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y\":{\"type\":\"field\",\"field\":\"normalized GFP expression (a.u.)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1089\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y\":{\"type\":\"field\",\"field\":\"normalized GFP expression (a.u.)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1057\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1070\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1071\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1072\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1073\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1078\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1079\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1080\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1065\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1066\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1067\"},\"axis_label\":\"normalized GFP expression (a.u.)\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1068\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LogAxis\",\"id\":\"p1060\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"LogTicker\",\"id\":\"p1061\",\"attributes\":{\"num_minor_ticks\":10,\"mantissas\":[1,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"LogTickFormatter\",\"id\":\"p1062\"},\"axis_label\":\"[IPTG] (mM)\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1063\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1064\",\"attributes\":{\"axis\":{\"id\":\"p1060\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1069\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1065\"}}}]}}]}};\n", + " const render_items = [{\"docid\":\"8dfd08c8-52d1-49a6-be16-821dd0c918f0\",\"roots\":{\"p1049\":\"c6ea1ed9-b393-4d39-8545-a7a86edc68ba\"},\"root_ids\":[\"p1049\"]}];\n", + " void root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1049" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "# Make the plot\n", + "p = bokeh.plotting.figure(\n", + " height=300,\n", + " width=450,\n", + " x_axis_label=x,\n", + " y_axis_label=y,\n", + " x_axis_type='log',\n", + ")\n", + "\n", + "p.scatter(\n", + " source=df,\n", + " x=x,\n", + " y=y,\n", + ")\n", + "\n", + "bokeh.io.show(p)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**c)** We start be adding the tops and bottoms of the error bars." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Add error bars to the DataFrame\n", + "df = df.assign(\n", + " error_low=df[\"normalized GFP expression (a.u.)\"] - 1.96 * df[\"sem\"],\n", + " error_high=df[\"normalized GFP expression (a.u.)\"] + 1.96 * df[\"sem\"],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we add them to the plot using the `segment()` method." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"10b7b572-247e-4f42-b800-3726e7cf69b4\":{\"version\":\"3.4.1\",\"title\":\"Bokeh Application\",\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1049\",\"attributes\":{\"width\":450,\"height\":300,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1050\"},\"y_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1051\"},\"x_scale\":{\"type\":\"object\",\"name\":\"LogScale\",\"id\":\"p1058\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1059\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1056\"},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1090\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1081\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1082\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1083\"},\"data\":{\"type\":\"map\",\"entries\":[[\"index\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAA=\"},\"shape\":[14],\"dtype\":\"int32\",\"order\":\"little\"}],[\"[IPTG] (mM)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"/Knx0k1iUD97FK5H4XqEP3sUrkfhepQ/uB6F61G4nj97FK5H4XqkP3sUrkfheqQ/uB6F61G4rj+amZmZmZm5PzMzMzMzM9M/MzMzMzMz4z8AAAAAAADwPwAAAAAAAAhAAAAAAAAAGEAAAAAAAAAkQA==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}],[\"normalized GFP expression (a.u.)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"VKnZA63AcD+pE9BE2PCEP9RIS+XtCJc/6UMX1LfMoT+fdvhrskaxPwYrTrUWZuU/Fvn1Q2yw5z9/orJhTeXqP3+kiAyr+O0/b9i2KLPB7j/RV5BmLBruP3e8yW/RSes/5pZWQ+Ie7T+yvRb03pjsPw==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}],[\"sem\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"8rBQa5p3bD+SeHk6V5RiP1daRuo9lXM/+n5qvHSTaD/BUl3Aywx7P6inj8AffrY/a9PYXgt6pz+C/de5aTOuP7WK/tDMk5s/AFRx4xbztz9x4xbzc0OjPyeDo+TVOa4/0nDK3Hwjqj/HuU24V+alPw==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1091\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1092\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1087\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y\":{\"type\":\"field\",\"field\":\"normalized GFP expression (a.u.)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1088\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y\":{\"type\":\"field\",\"field\":\"normalized GFP expression (a.u.)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1089\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y\":{\"type\":\"field\",\"field\":\"normalized GFP expression (a.u.)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1106\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1097\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1098\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1099\"},\"data\":{\"type\":\"map\",\"entries\":[[\"index\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAA=\"},\"shape\":[14],\"dtype\":\"int32\",\"order\":\"little\"}],[\"[IPTG] (mM)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"/Knx0k1iUD97FK5H4XqEP3sUrkfhepQ/uB6F61G4nj97FK5H4XqkP3sUrkfheqQ/uB6F61G4rj+amZmZmZm5PzMzMzMzM9M/MzMzMzMz4z8AAAAAAADwPwAAAAAAAAhAAAAAAAAAGEAAAAAAAAAkQA==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}],[\"normalized GFP expression (a.u.)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"VKnZA63AcD+pE9BE2PCEP9RIS+XtCJc/6UMX1LfMoT+fdvhrskaxPwYrTrUWZuU/Fvn1Q2yw5z9/orJhTeXqP3+kiAyr+O0/b9i2KLPB7j/RV5BmLBruP3e8yW/RSes/5pZWQ+Ie7T+yvRb03pjsPw==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}],[\"sem\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"8rBQa5p3bD+SeHk6V5RiP1daRuo9lXM/+n5qvHSTaD/BUl3Aywx7P6inj8AffrY/a9PYXgt6pz+C/de5aTOuP7WK/tDMk5s/AFRx4xbztz9x4xbzc0OjPyeDo+TVOa4/0nDK3Hwjqj/HuU24V+alPw==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}],[\"error_low\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"PLZlwFlKZr/NoRTGeax3P3zIrazh4Io/MT1hiQeUnT9UyPik0eyrP7znflayxt8/OjbIRTHQ5D8VBCxFNDLnP834SmJBSOw/fhQ7O5Xj6D8y5mwJEr7rP6QGLurulec/9WMXNS3r6T+zTDsMGOrpPw==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}],[\"error_high\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"4xbzc0NThj9s1pWmcwuOP7XWH3q1UKA/Oul942vPpD8UiXQF/Ja0Py7iXD/U6Oo/8rsjQqeQ6j/pQDl+ZpjuPzFQxrYUqe8/ME4Zi+hP8j+45NlhIzvwP0pyZfWz/e4/6+TKqEsp8D+xLvLbpUfvPw==\"},\"shape\":[14],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1107\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1108\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Segment\",\"id\":\"p1103\",\"attributes\":{\"x0\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y0\":{\"type\":\"field\",\"field\":\"error_low\"},\"x1\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y1\":{\"type\":\"field\",\"field\":\"error_high\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_width\":{\"type\":\"value\",\"value\":2}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Segment\",\"id\":\"p1104\",\"attributes\":{\"x0\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y0\":{\"type\":\"field\",\"field\":\"error_low\"},\"x1\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y1\":{\"type\":\"field\",\"field\":\"error_high\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"line_width\":{\"type\":\"value\",\"value\":2}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Segment\",\"id\":\"p1105\",\"attributes\":{\"x0\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y0\":{\"type\":\"field\",\"field\":\"error_low\"},\"x1\":{\"type\":\"field\",\"field\":\"[IPTG] (mM)\"},\"y1\":{\"type\":\"field\",\"field\":\"error_high\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"line_width\":{\"type\":\"value\",\"value\":2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1057\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1070\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1071\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1072\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1073\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1078\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1079\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1080\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1065\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1066\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1067\"},\"axis_label\":\"normalized GFP expression (a.u.)\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1068\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LogAxis\",\"id\":\"p1060\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"LogTicker\",\"id\":\"p1061\",\"attributes\":{\"num_minor_ticks\":10,\"mantissas\":[1,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"LogTickFormatter\",\"id\":\"p1062\"},\"axis_label\":\"[IPTG] (mM)\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1063\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1064\",\"attributes\":{\"axis\":{\"id\":\"p1060\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1069\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1065\"}}}]}}]}};\n", + " const render_items = [{\"docid\":\"10b7b572-247e-4f42-b800-3726e7cf69b4\",\"roots\":{\"p1049\":\"d7ad22fe-826d-418e-8fb7-3f510b6b2711\"},\"root_ids\":[\"p1049\"]}];\n", + " void root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1049" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "# Add error bars\n", + "p.segment(\n", + " source=df,\n", + " x0=x,\n", + " y0='error_low',\n", + " x1=x,\n", + " y1='error_high',\n", + " line_width=2,\n", + ")\n", + "\n", + "bokeh.io.show(p)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using the interactivity, you can zoom in on the point with the smalled IPTG concentration. Note the value of interactive graphics here. Even though the error bar is smaller than the dot on the zoomed-out plot, it is resolvable upon zooming in, which is impossible even with vector graphics. Note also a common problem with using an s.e.m. to compute error bars. The result is something unphysical; the error bar extends below zero. In general using s.e.m. for error bars is a not a good idea, and we will cover better ways of computing error bars when we discuss hacker stats in upcoming lessons." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Computing environment" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Python implementation: CPython\n", + "Python version : 3.11.9\n", + "IPython version : 8.20.0\n", + "\n", + "pandas : 2.2.1\n", + "bokeh : 3.4.1\n", + "jupyterlab: 4.0.13\n", + "\n" + ] + } + ], + "source": [ + "%load_ext watermark\n", + "%watermark -v -p pandas,bokeh,jupyterlab" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/2024/_sources/exercise_solutions/exercise_3/exercise_3.5_solution.ipynb.txt b/2024/_sources/exercise_solutions/exercise_3/exercise_3.5_solution.ipynb.txt new file mode 100644 index 00000000..cab7b74f --- /dev/null +++ b/2024/_sources/exercise_solutions/exercise_3/exercise_3.5_solution.ipynb.txt @@ -0,0 +1,643 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Exercise 3.5: Automating scatter plots\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You may notice that we often have to retype things like,\n", + "\n", + "```python\n", + "p = bokeh.plotting.figure(\n", + " frame_width=300,\n", + " frame_height=250,\n", + " x_axis_label='x',\n", + " y_axis_label='y',\n", + ")\n", + "```\n", + "\n", + "and the like when making plots. You may have a certain kind of plot you often make in your work, so you might want make functions to quickly generate the kinds of plots you want. Scatter plots come up very often. Write a function that takes as input a tidy data frame and generates a scatter plot based on two columns of the data frame and colors the glyphs according to a third column that contains categorical variables. The minimal (you can add other kwargs if you want) call signature should be\n", + "\n", + "```python\n", + "scatter(data, x, y, cat)\n", + "```\n", + "\n", + "You will of course test out your function while writing it, and the next exercises give you lots of opportunities to use it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solution\n", + "\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + " \n", + "
\n", + " \n", + " Loading BokehJS ...\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "'use strict';\n", + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const 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", + "const JS_MIME_TYPE = 'application/javascript';\n", + " const HTML_MIME_TYPE = 'text/html';\n", + " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " const CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " const 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", + " function drop(id) {\n", + " const view = Bokeh.index.get_by_id(id)\n", + " if (view != null) {\n", + " view.model.document.clear()\n", + " Bokeh.index.delete(view)\n", + " }\n", + " }\n", + "\n", + " const cell = handle.cell;\n", + "\n", + " const id = cell.output_area._bokeh_element_id;\n", + " const server_id = cell.output_area._bokeh_server_id;\n", + "\n", + " // Clean up Bokeh references\n", + " if (id != null) {\n", + " drop(id)\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " const cmd_clean = \"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_clean, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " const id = msg.content.text.trim()\n", + " drop(id)\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd_destroy);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " const output_area = handle.output_area;\n", + " const output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " const 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", + " const bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " const script_attrs = bk_div.children[0].attributes;\n", + " for (let i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\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", + " const 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", + " const 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", + " const events = require('base/js/events');\n", + " const 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", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " const 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", + " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", + " \"
  • use INLINE resources instead, as so:
  • \\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(error = null) {\n", + " const el = document.getElementById(\"edf6e8a5-cf48-473a-82d6-eb664ae77ce9\");\n", + " if (el != null) {\n", + " const html = (() => {\n", + " if (typeof root.Bokeh === \"undefined\") {\n", + " if (error == null) {\n", + " return \"BokehJS is loading ...\";\n", + " } else {\n", + " return \"BokehJS failed to load.\";\n", + " }\n", + " } else {\n", + " const prefix = `BokehJS ${root.Bokeh.version}`;\n", + " if (error == null) {\n", + " return `${prefix} successfully loaded.`;\n", + " } else {\n", + " return `${prefix} encountered errors while loading and may not function as expected.`;\n", + " }\n", + " }\n", + " })();\n", + " el.innerHTML = html;\n", + "\n", + " if (error != null) {\n", + " const wrapper = document.createElement(\"div\");\n", + " wrapper.style.overflow = \"auto\";\n", + " wrapper.style.height = \"5em\";\n", + " wrapper.style.resize = \"vertical\";\n", + " const content = document.createElement(\"div\");\n", + " content.style.fontFamily = \"monospace\";\n", + " content.style.whiteSpace = \"pre-wrap\";\n", + " content.style.backgroundColor = \"rgb(255, 221, 221)\";\n", + " content.textContent = error.stack ?? error.toString();\n", + " wrapper.append(content);\n", + " el.append(wrapper);\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(() => display_loaded(error), 100);\n", + " }\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"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.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error(url) {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.4.1.min.js\"];\n", + " const css_urls = [];\n", + "\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {\n", + " }\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if (root.Bokeh !== undefined || force === true) {\n", + " try {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }\n", + "\n", + " } catch (error) {display_loaded(error);throw error;\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", + " const cell = $(document.getElementById(\"edf6e8a5-cf48-473a-82d6-eb664ae77ce9\")).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "'use strict';\n(function(root) {\n function now() {\n return new Date();\n }\n\n const 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 if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const 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 \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\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(error = null) {\n const el = document.getElementById(\"edf6e8a5-cf48-473a-82d6-eb664ae77ce9\");\n if (el != null) {\n const html = (() => {\n if (typeof root.Bokeh === \"undefined\") {\n if (error == null) {\n return \"BokehJS is loading ...\";\n } else {\n return \"BokehJS failed to load.\";\n }\n } else {\n const prefix = `BokehJS ${root.Bokeh.version}`;\n if (error == null) {\n return `${prefix} successfully loaded.`;\n } else {\n return `${prefix} encountered errors while loading and may not function as expected.`;\n }\n }\n })();\n el.innerHTML = html;\n\n if (error != null) {\n const wrapper = document.createElement(\"div\");\n wrapper.style.overflow = \"auto\";\n wrapper.style.height = \"5em\";\n wrapper.style.resize = \"vertical\";\n const content = document.createElement(\"div\");\n content.style.fontFamily = \"monospace\";\n content.style.whiteSpace = \"pre-wrap\";\n content.style.backgroundColor = \"rgb(255, 221, 221)\";\n content.textContent = error.stack ?? error.toString();\n wrapper.append(content);\n el.append(wrapper);\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(() => display_loaded(error), 100);\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"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.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.4.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.4.1.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n try {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n\n } catch (error) {display_loaded(error);throw error;\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 const cell = $(document.getElementById(\"edf6e8a5-cf48-473a-82d6-eb664ae77ce9\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "import colorcet\n", + "\n", + "import bokeh.io\n", + "import bokeh.plotting\n", + "\n", + "bokeh.io.output_notebook()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I will offer some more kwargs, as described in the doc string below." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "def scatter(\n", + " data=None,\n", + " x=None,\n", + " y=None,\n", + " cat=None,\n", + " p=None,\n", + " palette=None,\n", + " show_legend=True,\n", + " click_policy=\"hide\",\n", + " marker_kwargs={},\n", + " **kwargs,\n", + "):\n", + " \"\"\"\n", + " Parameters\n", + " ----------\n", + " df : Pandas DataFrame\n", + " DataFrame containing tidy data for plotting.\n", + " x : hashable\n", + " Name of column to use as x-axis.\n", + " y : hashable\n", + " Name of column to use as y-axis.\n", + " cat : hashable\n", + " Name of column to use as categorical variable.\n", + " p : bokeh.plotting.Figure instance, or None (default)\n", + " If None, create a new figure. Otherwise, populate the existing\n", + " figure `p`.\n", + " palette : list of strings of hex colors, or single hex string\n", + " If a list, color palette to use. If a single string representing\n", + " a hex color, all glyphs are colored with that color. Default is\n", + " the Glasbey Catagory 10.\n", + " show_legend : bool, default False\n", + " If True, show legend.\n", + " tooltips : list of 2-tuples\n", + " Specification for tooltips as per Bokeh specifications. For\n", + " example, if we want `col1` and `col2` tooltips, we can use\n", + " `tooltips=[('label 1': '@col1'), ('label 2': '@col2')]`. Ignored\n", + " if `formal` is True.\n", + " show_legend : bool, default False\n", + " If True, show a legend.\n", + " click_policy : str, default \"hide\"\n", + " How to display points when their legend entry is clicked.\n", + " marker_kwargs : dict\n", + " kwargs to be passed to `p.scatter()` when making the scatter plot.\n", + " kwargs\n", + " Any kwargs to be passed to `bokeh.plotting.figure()` when making \n", + " the plot.\n", + "\n", + " Returns\n", + " -------\n", + " output : bokeh.plotting.Figure instance\n", + " Plot populated with jitter plot or box plot.\n", + " \"\"\"\n", + " # Automatically name the axes\n", + " if \"x_axis_label\" not in kwargs:\n", + " kwargs[\"x_axis_label\"] = x\n", + " if \"y_axis_label\" not in kwargs:\n", + " kwargs[\"y_axis_label\"] = y\n", + "\n", + " # Default palette\n", + " if palette is None:\n", + " palette = colorcet.b_glasbey_category10\n", + " elif type(palette) == str:\n", + " palette = [palette]\n", + "\n", + " # Instantiate figure\n", + " if 'toolbar_location' not in kwargs:\n", + " kwargs['toolbar_location'] = 'above'\n", + " if p is None:\n", + " p = bokeh.plotting.figure(**kwargs)\n", + "\n", + " # Build plot (not using color factors) to enable click policies\n", + " legend_items = []\n", + " for i, (name, g) in enumerate(data.groupby(cat, sort=False)):\n", + " marker_kwargs[\"color\"] = palette[i % len(palette)]\n", + " legend_items.append((str(name), [p.scatter(source=g, x=x, y=y, **marker_kwargs)]))\n", + "\n", + " if show_legend:\n", + " # Add the legend\n", + " legend = bokeh.models.Legend(items=legend_items, click_policy=click_policy)\n", + " \n", + " # Add the legend to the right of the plot\n", + " p.add_layout(legend, 'right')\n", + "\n", + " return p" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will test this function out on the frog tongue adhesion data, coloring by frog ID." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"5a642fa2-4ff2-42b3-b0ee-8929f52db5a2\":{\"version\":\"3.4.1\",\"title\":\"Bokeh Application\",\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1001\",\"attributes\":{\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1002\"},\"y_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1003\"},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1010\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1011\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1008\"},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1042\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1033\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1034\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1035\"},\"data\":{\"type\":\"map\",\"entries\":[[\"index\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAARAAAAEgAAABMAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"date\",{\"type\":\"ndarray\",\"array\":[\"2013_02_26\",\"2013_02_26\",\"2013_03_01\",\"2013_03_01\",\"2013_03_01\",\"2013_03_01\",\"2013_03_05\",\"2013_03_05\",\"2013_03_05\",\"2013_03_05\",\"2013_03_12\",\"2013_03_12\",\"2013_03_12\",\"2013_03_12\",\"2013_03_12\",\"2013_03_15\",\"2013_03_15\",\"2013_03_15\",\"2013_03_15\",\"2013_03_15\"],\"shape\":[20],\"dtype\":\"object\",\"order\":\"little\"}],[\"ID\",{\"type\":\"ndarray\",\"array\":[\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\",\"I\"],\"shape\":[20],\"dtype\":\"object\",\"order\":\"little\"}],[\"trial number\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AwAAAAQAAAABAAAAAgAAAAMAAAAEAAAAAQAAAAIAAAADAAAABAAAAAEAAAACAAAAAwAAAAQAAAAFAAAAAQAAAAIAAAADAAAABAAAAAUAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"impact force (mN)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"tQQAAN8JAADRBgAAFAYAAO0BAADkCAAALAIAAIgHAABRCgAAaQcAAGMHAAAJBgAAGwUAAJwGAAAHBgAAAgUAAAcDAADwBwAA2AQAANkBAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"impact time (ms)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"LgAAACwAAAAiAAAAKQAAACQAAAAfAAAAKwAAAC4AAAAyAAAAKQAAACgAAAAwAAAAHQAAAB8AAAAmAAAAHwAAACIAAAA8AAAAIgAAACgAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"impact force / body weight\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"MzMzMzMz/z9SuB6F61EQQI/C9ShcjwZAFK5H4XoUBECamZmZmZnpP3E9CtejcA1AzczMzMzM7D/hehSuR+EIQBSuR+F6FBFAexSuR+F6CEB7FK5H4XoIQAAAAAAAAARA4XoUrkfhAEDXo3A9CtcFQOxRuB6F6wNAj8L1KFyPAEAAAAAAAAD0Pz0K16NwPQpAAAAAAAAAAEBSuB6F61HoPw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"adhesive force (mN)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"7/z//yn8//+u/P//Of7//zL8//+w/f//AP7//9z8//9O/f//Mv7//wL9//81/f//m/3//1v9///w/f//PP7//1L+//90/f//TP3//+j9//8=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"time frog pulls on target (ms)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"dAMAAPgAAADTAAAAAQQAAPMBAADJAwAAQwMAAPwBAADrAQAARwMAAC0EAACJAgAANQcAAJUDAADuAgAAEQMAAEUDAADmAQAAigMAAMIEAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"adhesive force / body weight\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"UrgehetR9D9xPQrXo3D5P+xRuB6F6/U/rkfhehSu5z8fhetRuB75P7gehetRuO4/j8L1KFyP6j/NzMzMzMz0P+xRuB6F6/E/AAAAAAAA6D/Xo3A9CtfzP2ZmZmZmZvI/rkfhehSu7z9xPQrXo3DxPzMzMzMzM+s/XI/C9Shc5z9mZmZmZmbmP83MzMzMzPA/7FG4HoXr8T/Xo3A9CtfrPw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"adhesive impulse (N-s)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"j8L1KFyP0r9eukkMAivHv39qvHSTGMS/w/UoXI/Cxb/fT42XbhLbv7pJDAIrh8a/PQrXo3A90r89CtejcD3Sv2Q730+Nl86/y6FFtvP91L9SuB6F61HYv99PjZduEtO/+n5qvHST6L9zaJHtfD/dv2Q730+Nl9a//tR46SYx0L9Ei2zn+6nRv6abxCCwctC/fT81XrpJ1L+mm8QgsHLYvw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"total contact area (mm2)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"gwEAAGUAAABTAAAASgEAAPUAAABVAQAAZwEAAPYAAAANAQAACgEAAJgBAACNAAAAxwEAALoAAACZAAAAIgEAAAEBAACTAAAAbAEAAAMBAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"contact area without mucus (mm2)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"RgAAAF4AAABPAAAAngAAANgAAABqAAAAbgAAALIAAADgAAAAsAAAACEAAABwAAAAXAAAAIEAAACUAAAAaQAAAHwAAACGAAAABAEAAKgAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"contact area with mucus / contact area without mucus\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"PQrXo3A96j/sUbgeheuxP5qZmZmZmak/pHA9Ctej4D+4HoXrUbi+PxSuR+F6FOY/FK5H4XoU5j/sUbgehevRP8P1KFyPwsU/w/UoXI/C1T9xPQrXo3DtP+F6FK5H4co/mpmZmZmZ6T/Xo3A9CtfTP7gehetRuJ4/exSuR+F65D+kcD0K16PgPwrXo3A9Crc/7FG4HoXr0T9mZmZmZmbWPw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"contact pressure (Pa)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"LQwAAFthAAAcUgAAbhIAANwHAAAUGgAADgYAAJgeAABgJgAA0hsAAB4SAADDKgAAOgsAAIEjAABvJwAAQxEAAMsLAADYNQAATg0AACYHAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"adhesive strength (Pa)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"Evj//yHa//8B2P//m/r//3nw//83+f//bfr//z7z///49f//O/n//6n4//847P//vPr//8zx//+D8v//6/n//3P5//+37v//k/j//+f3//8=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1043\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1044\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1039\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"impact force (mN)\"},\"y\":{\"type\":\"field\",\"field\":\"adhesive force (mN)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b3\"},\"fill_color\":{\"type\":\"value\",\"value\":\"#1f77b3\"},\"hatch_color\":{\"type\":\"value\",\"value\":\"#1f77b3\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1040\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"impact force (mN)\"},\"y\":{\"type\":\"field\",\"field\":\"adhesive force (mN)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b3\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"value\",\"value\":\"#1f77b3\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"value\",\"value\":\"#1f77b3\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1041\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"impact force (mN)\"},\"y\":{\"type\":\"field\",\"field\":\"adhesive force (mN)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b3\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"value\",\"value\":\"#1f77b3\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"value\",\"value\":\"#1f77b3\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1054\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1045\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1046\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1047\"},\"data\":{\"type\":\"map\",\"entries\":[[\"index\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"FAAAABUAAAAWAAAAFwAAABgAAAAZAAAAGgAAABsAAAAcAAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACQAAAAlAAAAJgAAACcAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"date\",{\"type\":\"ndarray\",\"array\":[\"2013_03_19\",\"2013_03_19\",\"2013_03_19\",\"2013_03_19\",\"2013_03_21\",\"2013_03_21\",\"2013_03_21\",\"2013_03_21\",\"2013_03_25\",\"2013_03_25\",\"2013_03_25\",\"2013_03_25\",\"2013_03_28\",\"2013_03_28\",\"2013_04_03\",\"2013_04_03\",\"2013_04_08\",\"2013_04_08\",\"2013_04_08\",\"2013_04_12\"],\"shape\":[20],\"dtype\":\"object\",\"order\":\"little\"}],[\"ID\",{\"type\":\"ndarray\",\"array\":[\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\",\"II\"],\"shape\":[20],\"dtype\":\"object\",\"order\":\"little\"}],[\"trial number\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AQAAAAIAAAADAAAABAAAAAEAAAACAAAAAwAAAAQAAAABAAAAAgAAAAMAAAAEAAAAAQAAAAIAAAABAAAAAgAAAAEAAAACAAAAAwAAAAEAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"impact force (mN)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"TAYAAF0CAABHAQAAsgMAAB0CAAADBgAAEQIAAHQCAACtBQAAKQEAAL8CAAANAQAA7wIAAPUAAACeBAAAAwIAALMBAAB/AQAAyQEAANoCAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"impact time (ms)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"EgAAADcAAAAzAAAAOwAAACEAAAArAAAAHAAAAB8AAABIAAAAKgAAACEAAAA5AAAAJwAAABUAAAAcAAAAHQAAABoAAAAfAAAADwAAACoAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"impact force / body weight\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"UrgehetRDkC4HoXrUbj2P6RwPQrXo+g/16NwPQrXAUBSuB6F61H0P/YoXI/C9QxA16NwPQrX8z+uR+F6FK73P1yPwvUoXAtAZmZmZmZm5j9mZmZmZmb6Pylcj8L1KOQ/UrgehetR/D+PwvUoXI/iPz0K16NwPQZAXI/C9Shc8z9SuB6F61HwP83MzMzMzOw/SOF6FK5H8T+F61G4HoX7Pw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"adhesive force (mN)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"cf3//9z+//8K////C////9f9//9o/f//+/7//039//+k////yv3//yH///8A/v//Hf///8P9///2/f//qf3//5T+//8r/v//tPz//3j9//8=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"time frog pulls on target (ms)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"DwwAAO0EAADkBQAAMQcAADYMAADlAgAAsgkAAOYDAAB0BgAAqAMAAGgIAAC9AAAAqwQAALoFAACtBAAAzgUAAPkDAADOAwAADAMAABIDAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"adhesive force / body weight\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"pHA9Ctej+D8UrkfhehTmP4/C9Shcj+I/j8L1KFyP4j/NzMzMzMz0P/YoXI/C9fg/hetRuB6F4z8UrkfhehT6Pylcj8L1KMw/SOF6FK5H9T+kcD0K16PgPzMzMzMzM/M/9ihcj8L14D+amZmZmZn1P65H4XoUrvM/j8L1KFyP9j+F61G4HoXrP5qZmZmZmfE/16NwPQrX/z9SuB6F61H4Pw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"adhesive impulse (N-s)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"pHA9Ctej2L83iUFg5dDSvz81XrpJDNK/w/UoXI/C1b/ZzvdT46Xbv1pkO99Pjae/5dAi2/l+2r+TGARWDi2yv/yp8dJNYoC/Gy/dJAaBtb+Nl24Sg8DKvylcj8L1KKy/ObTIdr6fmr+F61G4HoXLv2iR7Xw/Nb6/IbByaJHtzL81XrpJDALLv6RwPQrXo9C/y6FFtvP91L9g5dAi2/m+vw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"total contact area (mm2)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"XAEAAPgAAACCAAAAagAAABQBAABVAAAARQEAAPIAAACIAAAAfgAAAO0AAAAdAAAAzgAAAL4AAAAZAQAA2QAAAL0AAADdAAAAqwAAAI4AAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"contact area without mucus (mm2)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"DwAAABgAAAAiAAAAGgAAABAAAAAYAAAAIQAAAEMAAAAAAAAABAAAAAgAAAAcAAAAAAAAAC4AAAAAAAAAAAAAAFkAAABIAAAAagAAACsAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"contact area with mucus / contact area without mucus\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"uB6F61G47j/NzMzMzMzsP65H4XoUruc/UrgehetR6D8UrkfhehTuPwrXo3A9Cuc/zczMzMzM7D8K16NwPQrnPwAAAAAAAPA/CtejcD0K7z8K16NwPQrvP7gehetRuJ4/AAAAAAAA8D9SuB6F61HoPwAAAAAAAPA/AAAAAAAA8D/2KFyPwvXgP3E9CtejcOU/UrgehetR2D9mZmZmZmbmPw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"contact pressure (Pa)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"GRIAAIkJAADVCQAAvSIAAKcHAACZRgAAWwYAACgKAACVKQAAPwkAAJwLAAA/JAAAPw4AAAgFAAB1EAAAQQkAAP4IAADJBgAAaQoAAB0UAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"adhesive strength (Pa)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"p/j//2f7//+a+P//A/f//yz4//+G4f//3fz//9T0//9a/f//Zu7//1L8//8Mu///s/v//zr0//+8+P//O/X//3n4//+v9///w+z//yPu//8=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1055\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1056\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1051\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"impact force (mN)\"},\"y\":{\"type\":\"field\",\"field\":\"adhesive force (mN)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#ff7e0e\"},\"fill_color\":{\"type\":\"value\",\"value\":\"#ff7e0e\"},\"hatch_color\":{\"type\":\"value\",\"value\":\"#ff7e0e\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1052\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"impact force (mN)\"},\"y\":{\"type\":\"field\",\"field\":\"adhesive force (mN)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#ff7e0e\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"value\",\"value\":\"#ff7e0e\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"value\",\"value\":\"#ff7e0e\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1053\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"impact force (mN)\"},\"y\":{\"type\":\"field\",\"field\":\"adhesive force (mN)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#ff7e0e\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"value\",\"value\":\"#ff7e0e\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"value\",\"value\":\"#ff7e0e\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1066\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1057\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1058\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1059\"},\"data\":{\"type\":\"map\",\"entries\":[[\"index\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"KAAAACkAAAAqAAAAKwAAACwAAAAtAAAALgAAAC8AAAAwAAAAMQAAADIAAAAzAAAANAAAADUAAAA2AAAANwAAADgAAAA5AAAAOgAAADsAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"date\",{\"type\":\"ndarray\",\"array\":[\"2013_05_27\",\"2013_05_27\",\"2013_05_27\",\"2013_06_11\",\"2013_06_11\",\"2013_06_11\",\"2013_06_14\",\"2013_06_14\",\"2013_06_18\",\"2013_06_18\",\"2013_06_18\",\"2013_06_18\",\"2013_06_21\",\"2013_06_21\",\"2013_06_21\",\"2013_06_21\",\"2013_06_26\",\"2013_06_26\",\"2013_06_26\",\"2013_06_26\"],\"shape\":[20],\"dtype\":\"object\",\"order\":\"little\"}],[\"ID\",{\"type\":\"ndarray\",\"array\":[\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\",\"III\"],\"shape\":[20],\"dtype\":\"object\",\"order\":\"little\"}],[\"trial number\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AQAAAAIAAAADAAAAAQAAAAIAAAADAAAAAQAAAAIAAAABAAAAAgAAAAMAAAAEAAAAAQAAAAIAAAADAAAABAAAAAEAAAACAAAAAwAAAAQAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"impact force (mN)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"ZgIAAJ4BAABEAQAACAMAAGMCAAAgAgAAGgIAAEMCAAAmAwAAywEAAMoBAAByAgAAbQIAACACAAAXAgAAgQEAAJEBAABmAgAAmQIAAOgBAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"impact time (ms)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"WAAAAI8AAABpAAAAIwAAAB0AAAAQAAAAJgAAAB8AAAAdAAAAIAAAAB4AAAAQAAAAGwAAAB4AAAAjAAAAJwAAACQAAAAiAAAAKAAAACIAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"impact force / body weight\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"w/UoXI/CE0CkcD0K16MKQOF6FK5H4QRA9ihcj8L1GECkcD0K16MTQIXrUbgehRFASOF6FK5HEUCkcD0K16MSQPYoXI/C9RlAmpmZmZmZDUCF61G4HoUNQClcj8L1KBRA9ihcj8L1E0CF61G4HoURQDMzMzMzMxFAuB6F61G4CEDXo3A9CtcJQMP1KFyPwhNAZmZmZmZmFUBxPQrXo3APQA==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"adhesive force (mN)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"ov///13///9U////H////9P+//+j////ff///9/+//+Y////G/////3+//8Z////9f7//07///+F////af///4H///+M/v//FP///3r+//8=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"time frog pulls on target (ms)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"qwIAAPUAAABrAgAAHwcAAJYDAABHBQAA/gYAAO4DAABzAwAAwgQAAI4DAAAmAgAAIQgAAHgBAAAhAQAAXwIAAHQLAACoAgAArQIAABwFAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"adhesive force / body weight\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"UrgehetR6D/2KFyPwvX0PxSuR+F6FPY/9ihcj8L1/D9cj8L1KFwDQAAAAAAAAOg/zczMzMzM8D+kcD0K16MCQOF6FK5H4eo/mpmZmZmZ/T+kcD0K16MAQMP1KFyPwv0/H4XrUbgeAUDhehSuR+H2P65H4XoUru8/hetRuB6F8z9SuB6F61HwP+xRuB6F6wdAZmZmZmZm/j8fhetRuB4JQA==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"adhesive impulse (N-s)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"/Knx0k1iUL/8qfHSTWKgv9NNYhBYObS/TDeJQWDlwL/Xo3A9CtfDvylcj8L1KLy/O99PjZduor/jpZvEILCyvylcj8L1KKy/8KfGSzeJwb+iRbbz/dTIvxsv3SQGgaW/BoGVQ4tsx7+cxCCwcmihvxkEVg4tsp2/y6FFtvP9tL+F61G4HoXLv+xRuB6F68G/aJHtfD81vr85tMh2vp/Kvw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"total contact area (mm2)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"YQAAAGwAAAA3AAAAfAAAAIAAAAArAAAAggAAAHEAAABzAAAAWQAAAFsAAABSAAAAeAAAABMAAAAVAAAAHwAAAI4AAABIAAAAgQAAAHAAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"contact area without mucus (mm2)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"DwAAAAoAAAAXAAAAEQAAACsAAAAiAAAASgAAAAQAAAA3AAAABgAAAFgAAAAXAAAAOgAAABEAAAAdAAAAfgAAAAwAAAABAAAAAAAAADoAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"contact area with mucus / contact area without mucus\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"j8L1KFyP6j8zMzMzMzPjP65H4XoUrtc/pHA9Ctej6D97FK5H4XqUP7gehetRuOY/AAAAAAAA8D+4HoXrUbjePx+F61G4HuU/ZmZmZmZm7j8zMzMzMzPDP3sUrkfheoQ/zczMzMzM7D+amZmZmZmpP5qZmZmZmak/uB6F61G4nj+F61G4HoXrP+F6FK5H4do/exSuR+F6xD/2KFyPwvXYPw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"contact pressure (Pa)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"thgAAPAOAAA6FwAAgBgAAKISAACbMQAAIhAAAPYTAABRGwAALRQAALgTAADRHQAAIBQAAOFvAAB/YwAAeTAAABMLAAAbIQAAMxQAABgRAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"adhesive strength (Pa)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"Ofz//x36//+z8///5vj//872//979///E/z//wX2//96/P//7PX//9n0///99P//W/f//2zb//8t6f//7uz//4D8///w6///1vj//1zy//8=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1067\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1068\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1063\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"impact force (mN)\"},\"y\":{\"type\":\"field\",\"field\":\"adhesive force (mN)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#2ba02b\"},\"fill_color\":{\"type\":\"value\",\"value\":\"#2ba02b\"},\"hatch_color\":{\"type\":\"value\",\"value\":\"#2ba02b\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1064\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"impact force (mN)\"},\"y\":{\"type\":\"field\",\"field\":\"adhesive force (mN)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#2ba02b\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"value\",\"value\":\"#2ba02b\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"value\",\"value\":\"#2ba02b\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1065\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"impact force (mN)\"},\"y\":{\"type\":\"field\",\"field\":\"adhesive force (mN)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#2ba02b\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"value\",\"value\":\"#2ba02b\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"value\",\"value\":\"#2ba02b\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1078\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1069\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1070\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1071\"},\"data\":{\"type\":\"map\",\"entries\":[[\"index\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"PAAAAD0AAAA+AAAAPwAAAEAAAABBAAAAQgAAAEMAAABEAAAARQAAAEYAAABHAAAASAAAAEkAAABKAAAASwAAAEwAAABNAAAATgAAAE8AAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"date\",{\"type\":\"ndarray\",\"array\":[\"2013_05_27\",\"2013_05_27\",\"2013_05_27\",\"2013_05_30\",\"2013_05_30\",\"2013_05_30\",\"2013_06_03\",\"2013_06_11\",\"2013_06_11\",\"2013_06_11\",\"2013_06_11\",\"2013_06_14\",\"2013_06_18\",\"2013_06_18\",\"2013_06_18\",\"2013_06_18\",\"2013_06_21\",\"2013_06_21\",\"2013_06_21\",\"2013_06_21\"],\"shape\":[20],\"dtype\":\"object\",\"order\":\"little\"}],[\"ID\",{\"type\":\"ndarray\",\"array\":[\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\",\"IV\"],\"shape\":[20],\"dtype\":\"object\",\"order\":\"little\"}],[\"trial number\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AgAAAAMAAAAEAAAAAQAAAAIAAAADAAAAAQAAAAEAAAACAAAAAwAAAAQAAAABAAAAAQAAAAIAAAADAAAABAAAAAEAAAACAAAAAwAAAAQAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"impact force (mN)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"rAAAAI4AAAAlAAAAxQEAAGMBAAAWAAAA9gEAABEBAADQAgAARgIAAMYAAADGAAAAVQIAAAQCAAAvAwAAkgEAAF0CAADHAgAAZgIAANQBAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"impact time (ms)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"GgAAABQAAAA3AAAAJgAAAB8AAAAhAAAASgAAABoAAAAbAAAAIQAAABcAAAAGAAAAHQAAAB8AAAAiAAAAJgAAACcAAABMAAAAIQAAACQAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"impact force / body weight\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"exSuR+F69D/NzMzMzMzwP+xRuB6F69E/9ihcj8L1CkAfhetRuB4FQMP1KFyPwsU/7FG4HoXrDUA9CtejcD0AQHE9CtejcBVAXI/C9ShcEUCF61G4HoX3P4XrUbgehfc/w/UoXI/CEUC4HoXrUbgOQEjhehSuRxhAAAAAAAAACEAAAAAAAAASQDMzMzMzMxVASOF6FK5HEkDXo3A9CtcLQA==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"adhesive force (mN)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"OP7//z////8U////H////yf///9f////df////j+//+q/v//Gf///y/////c/v//rf7//43+//+1/v//0v7//yj///9d////kf7//yb///8=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"time frog pulls on target (ms)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"zgEAAPoAAADnAgAATAMAANgCAADYAQAAvwMAAEwDAADrBQAAFwEAAJMFAAA6CwAAmxAAAHICAADmBAAA2gMAAFsGAADlBwAAVgUAAPUEAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"adhesive force / body weight\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"MzMzMzMzC0AK16NwPQr3Pylcj8L1KPw/4XoUrkfh+j/D9Shcj8L5PzMzMzMzM/M/pHA9Ctej8D+F61G4HoX/P2ZmZmZmZgRAhetRuB6F+z/NzMzMzMz4P1yPwvUoXAFAPQrXo3A9BEAUrkfhehQGQMP1KFyPwgNAAAAAAAAAAkDD9Shcj8L5P1yPwvUoXPM/16NwPQrXBUAUrkfhehT6Pw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"adhesive impulse (N-s)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"mpmZmZmZqb+q8dJNYhCovxBYObTIdr6/KVyPwvUovL9aZDvfT42Xvzm0yHa+n6q/YhBYObTItr97FK5H4XrEvyGwcmiR7cy/TDeJQWDloL+HFtnO91PDvxkEVg4tss2/lkOLbOf70b+q8dJNYhC4v4PAyqFFtrO/CKwcWmQ7v7+YbhKDwMrBvy2yne+nxsu/8tJNYhBYyb8IrBxaZDu/vw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"total contact area (mm2)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"hQAAADkAAAAzAAAAjgAAAK4AAAA4AAAAQQAAAHwAAACJAAAAPAAAAG4AAACRAAAAvwAAAFMAAACXAAAAdQAAAHsAAACBAAAAgAAAAIEAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"contact area without mucus (mm2)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAEoAAAAsAAAAbAAAACcAAAAEAAAATQAAAFEAAAAAAAAABAAAAEUAAAAyAAAADAAAABIAAAAUAAAAHgAAABQAAAAqAAAAbAAAAEQAAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"contact area with mucus / contact area without mucus\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"KVyPwvUo7D+PwvUoXI/qP0jhehSuR+E/uB6F61G43j9cj8L1KFzvP3sUrkfhepQ/H4XrUbge7T+PwvUoXI/SP4/C9Shcj+o/uB6F61G4nj/hehSuR+HqP65H4XoUru8/AAAAAAAA8D+4HoXrUbi+P7gehetRuOY/7FG4HoXrsT8AAAAAAADwPwrXo3A9Cu8/cT0K16Nw3T+F61G4HoXjPw==\"},\"shape\":[20],\"dtype\":\"float64\",\"order\":\"little\"}],[\"contact pressure (Pa)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"EQUAAMIJAADfAgAAaQwAAPUHAACNAQAAIR4AAJ0IAACLFAAA6SUAAAEHAABZBQAALAwAACgYAAAKFQAAdg0AAEATAAB6FQAAqBIAACEOAAA=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}],[\"adhesive strength (Pa)\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"kPL//7jy///Z7f//0/n//yP7///O9P//o/f//6j3//8/9v//+fD//5/4//8e+P//FPn//6Hu//9y9///4fX//yH5//8X+///1/T//2j5//8=\"},\"shape\":[20],\"dtype\":\"int32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1079\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1080\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1075\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"impact force (mN)\"},\"y\":{\"type\":\"field\",\"field\":\"adhesive force (mN)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#d62628\"},\"fill_color\":{\"type\":\"value\",\"value\":\"#d62628\"},\"hatch_color\":{\"type\":\"value\",\"value\":\"#d62628\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1076\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"impact force (mN)\"},\"y\":{\"type\":\"field\",\"field\":\"adhesive force (mN)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#d62628\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"value\",\"value\":\"#d62628\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"value\",\"value\":\"#d62628\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Scatter\",\"id\":\"p1077\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"impact force (mN)\"},\"y\":{\"type\":\"field\",\"field\":\"adhesive force (mN)\"},\"line_color\":{\"type\":\"value\",\"value\":\"#d62628\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"value\",\"value\":\"#d62628\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"value\",\"value\":\"#d62628\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1009\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1022\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1023\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1024\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1025\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1030\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1031\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1032\"}]}},\"toolbar_location\":\"above\",\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1017\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1018\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1019\"},\"axis_label\":\"adhesive force (mN)\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1020\"}}}],\"right\":[{\"type\":\"object\",\"name\":\"Legend\",\"id\":\"p1081\",\"attributes\":{\"click_policy\":\"hide\",\"items\":[{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1082\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"I\"},\"renderers\":[{\"id\":\"p1042\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1083\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"II\"},\"renderers\":[{\"id\":\"p1054\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1084\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"III\"},\"renderers\":[{\"id\":\"p1066\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1085\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"IV\"},\"renderers\":[{\"id\":\"p1078\"}]}}]}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1012\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1013\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1014\"},\"axis_label\":\"impact force (mN)\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1015\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1016\",\"attributes\":{\"axis\":{\"id\":\"p1012\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1021\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1017\"}}}],\"frame_width\":450,\"frame_height\":350}}]}};\n", + " const render_items = [{\"docid\":\"5a642fa2-4ff2-42b3-b0ee-8929f52db5a2\",\"roots\":{\"p1001\":\"dda19536-1efc-40ef-9272-fabf2077ce28\"},\"root_ids\":[\"p1001\"]}];\n", + " void root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1001" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "df = pd.read_csv('data/frog_tongue_adhesion.csv', comment='#')\n", + "\n", + "p = scatter(\n", + " data=df,\n", + " x='impact force (mN)',\n", + " y='adhesive force (mN)',\n", + " cat='ID',\n", + " frame_height=350,\n", + " frame_width=450,\n", + ")\n", + "\n", + "bokeh.io.show(p)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Computing environment" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Python implementation: CPython\n", + "Python version : 3.11.9\n", + "IPython version : 8.20.0\n", + "\n", + "pandas : 2.2.1\n", + "bokeh : 3.4.1\n", + "jupyterlab: 4.0.13\n", + "\n" + ] + } + ], + "source": [ + "%load_ext watermark\n", + "%watermark -v -p pandas,bokeh,jupyterlab" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/2024/_sources/exercise_solutions/exercise_3/index.rst.txt b/2024/_sources/exercise_solutions/exercise_3/index.rst.txt new file mode 100644 index 00000000..2d1abcbf --- /dev/null +++ b/2024/_sources/exercise_solutions/exercise_3/index.rst.txt @@ -0,0 +1,12 @@ +****************************************************************** +Exercise 3 solutions +****************************************************************** + +.. toctree:: + :maxdepth: 1 + + exercise_3.1_solution.ipynb + exercise_3.2_solution.ipynb + exercise_3.3_solution.ipynb + exercise_3.4_solution.ipynb + exercise_3.5_solution.ipynb \ No newline at end of file diff --git a/2024/exercise_solutions/exercise_1/exercise_1.1_solution.html b/2024/exercise_solutions/exercise_1/exercise_1.1_solution.html index 0359cc29..0ace1a7f 100644 --- a/2024/exercise_solutions/exercise_1/exercise_1.1_solution.html +++ b/2024/exercise_solutions/exercise_1/exercise_1.1_solution.html @@ -135,6 +135,7 @@
  • Exercise 2 solutions
  • +
  • Exercise 3 solutions
  • Schedule

  • Exercise 2 solutions
  • +
  • Exercise 3 solutions
  • Schedule

  • Exercise 2 solutions
  • +
  • Exercise 3 solutions
  • Schedule

  • Exercise 2 solutions
  • +
  • Exercise 3 solutions
  • Schedule

  • Exercise 2 solutions
  • +
  • Exercise 3 solutions
  • Schedule

  • Exercise 2 solutions
  • +
  • Exercise 3 solutions
  • Schedule

  • Exercise 2 solutions
  • +
  • Exercise 3 solutions
  • Schedule

    +
  • Exercise 3 solutions
  • Schedule

    +
  • Exercise 3 solutions
  • Schedule

    +
  • Exercise 3 solutions
  • Schedule

    +
  • Exercise 3 solutions
  • Schedule

    +
  • Exercise 3 solutions
  • Schedule