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",
+ " date | \n",
+ " ID | \n",
+ " trial number | \n",
+ " impact force (mN) | \n",
+ " impact time (ms) | \n",
+ " impact force / body weight | \n",
+ " adhesive force (mN) | \n",
+ " time frog pulls on target (ms) | \n",
+ " adhesive force / body weight | \n",
+ " adhesive impulse (N-s) | \n",
+ " total contact area (mm2) | \n",
+ " contact area without mucus (mm2) | \n",
+ " contact area with mucus / contact area without mucus | \n",
+ " contact pressure (Pa) | \n",
+ " adhesive strength (Pa) | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 2013_02_26 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 1205 | \n",
+ " 46 | \n",
+ " 1.95 | \n",
+ " -785 | \n",
+ " 884 | \n",
+ " 1.27 | \n",
+ " -0.290 | \n",
+ " 387 | \n",
+ " 70 | \n",
+ " 0.82 | \n",
+ " 3117 | \n",
+ " -2030 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 2013_02_26 | \n",
+ " I | \n",
+ " 4 | \n",
+ " 2527 | \n",
+ " 44 | \n",
+ " 4.08 | \n",
+ " -983 | \n",
+ " 248 | \n",
+ " 1.59 | \n",
+ " -0.181 | \n",
+ " 101 | \n",
+ " 94 | \n",
+ " 0.07 | \n",
+ " 24923 | \n",
+ " -9695 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 1 | \n",
+ " 1745 | \n",
+ " 34 | \n",
+ " 2.82 | \n",
+ " -850 | \n",
+ " 211 | \n",
+ " 1.37 | \n",
+ " -0.157 | \n",
+ " 83 | \n",
+ " 79 | \n",
+ " 0.05 | \n",
+ " 21020 | \n",
+ " -10239 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 2 | \n",
+ " 1556 | \n",
+ " 41 | \n",
+ " 2.51 | \n",
+ " -455 | \n",
+ " 1025 | \n",
+ " 0.74 | \n",
+ " -0.170 | \n",
+ " 330 | \n",
+ " 158 | \n",
+ " 0.52 | \n",
+ " 4718 | \n",
+ " -1381 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 493 | \n",
+ " 36 | \n",
+ " 0.80 | \n",
+ " -974 | \n",
+ " 499 | \n",
+ " 1.57 | \n",
+ " -0.423 | \n",
+ " 245 | \n",
+ " 216 | \n",
+ " 0.12 | \n",
+ " 2012 | \n",
+ " -3975 | \n",
+ "
\n",
+ " \n",
+ "
\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",
+ " impact force (mN) | \n",
+ " adhesive force (mN) | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 20 | \n",
+ " 1612 | \n",
+ " -655 | \n",
+ "
\n",
+ " \n",
+ " 21 | \n",
+ " 605 | \n",
+ " -292 | \n",
+ "
\n",
+ " \n",
+ " 22 | \n",
+ " 327 | \n",
+ " -246 | \n",
+ "
\n",
+ " \n",
+ " 23 | \n",
+ " 946 | \n",
+ " -245 | \n",
+ "
\n",
+ " \n",
+ " 24 | \n",
+ " 541 | \n",
+ " -553 | \n",
+ "
\n",
+ " \n",
+ " 25 | \n",
+ " 1539 | \n",
+ " -664 | \n",
+ "
\n",
+ " \n",
+ " 26 | \n",
+ " 529 | \n",
+ " -261 | \n",
+ "
\n",
+ " \n",
+ " 27 | \n",
+ " 628 | \n",
+ " -691 | \n",
+ "
\n",
+ " \n",
+ " 28 | \n",
+ " 1453 | \n",
+ " -92 | \n",
+ "
\n",
+ " \n",
+ " 29 | \n",
+ " 297 | \n",
+ " -566 | \n",
+ "
\n",
+ " \n",
+ " 30 | \n",
+ " 703 | \n",
+ " -223 | \n",
+ "
\n",
+ " \n",
+ " 31 | \n",
+ " 269 | \n",
+ " -512 | \n",
+ "
\n",
+ " \n",
+ " 32 | \n",
+ " 751 | \n",
+ " -227 | \n",
+ "
\n",
+ " \n",
+ " 33 | \n",
+ " 245 | \n",
+ " -573 | \n",
+ "
\n",
+ " \n",
+ " 34 | \n",
+ " 1182 | \n",
+ " -522 | \n",
+ "
\n",
+ " \n",
+ " 35 | \n",
+ " 515 | \n",
+ " -599 | \n",
+ "
\n",
+ " \n",
+ " 36 | \n",
+ " 435 | \n",
+ " -364 | \n",
+ "
\n",
+ " \n",
+ " 37 | \n",
+ " 383 | \n",
+ " -469 | \n",
+ "
\n",
+ " \n",
+ " 38 | \n",
+ " 457 | \n",
+ " -844 | \n",
+ "
\n",
+ " \n",
+ " 39 | \n",
+ " 730 | \n",
+ " -648 | \n",
+ "
\n",
+ " \n",
+ "
\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",
+ " adhesive force (mN) | \n",
+ " time frog pulls on target (ms) | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 40 | \n",
+ " -94 | \n",
+ " 683 | \n",
+ "
\n",
+ " \n",
+ " 41 | \n",
+ " -163 | \n",
+ " 245 | \n",
+ "
\n",
+ " \n",
+ " 42 | \n",
+ " -172 | \n",
+ " 619 | \n",
+ "
\n",
+ " \n",
+ " 43 | \n",
+ " -225 | \n",
+ " 1823 | \n",
+ "
\n",
+ " \n",
+ " 44 | \n",
+ " -301 | \n",
+ " 918 | \n",
+ "
\n",
+ " \n",
+ " 45 | \n",
+ " -93 | \n",
+ " 1351 | \n",
+ "
\n",
+ " \n",
+ " 46 | \n",
+ " -131 | \n",
+ " 1790 | \n",
+ "
\n",
+ " \n",
+ " 47 | \n",
+ " -289 | \n",
+ " 1006 | \n",
+ "
\n",
+ " \n",
+ " 48 | \n",
+ " -104 | \n",
+ " 883 | \n",
+ "
\n",
+ " \n",
+ " 49 | \n",
+ " -229 | \n",
+ " 1218 | \n",
+ "
\n",
+ " \n",
+ " 50 | \n",
+ " -259 | \n",
+ " 910 | \n",
+ "
\n",
+ " \n",
+ " 51 | \n",
+ " -231 | \n",
+ " 550 | \n",
+ "
\n",
+ " \n",
+ " 52 | \n",
+ " -267 | \n",
+ " 2081 | \n",
+ "
\n",
+ " \n",
+ " 53 | \n",
+ " -178 | \n",
+ " 376 | \n",
+ "
\n",
+ " \n",
+ " 54 | \n",
+ " -123 | \n",
+ " 289 | \n",
+ "
\n",
+ " \n",
+ " 55 | \n",
+ " -151 | \n",
+ " 607 | \n",
+ "
\n",
+ " \n",
+ " 56 | \n",
+ " -127 | \n",
+ " 2932 | \n",
+ "
\n",
+ " \n",
+ " 57 | \n",
+ " -372 | \n",
+ " 680 | \n",
+ "
\n",
+ " \n",
+ " 58 | \n",
+ " -236 | \n",
+ " 685 | \n",
+ "
\n",
+ " \n",
+ " 59 | \n",
+ " -390 | \n",
+ " 1308 | \n",
+ "
\n",
+ " \n",
+ " 60 | \n",
+ " -456 | \n",
+ " 462 | \n",
+ "
\n",
+ " \n",
+ " 61 | \n",
+ " -193 | \n",
+ " 250 | \n",
+ "
\n",
+ " \n",
+ " 62 | \n",
+ " -236 | \n",
+ " 743 | \n",
+ "
\n",
+ " \n",
+ " 63 | \n",
+ " -225 | \n",
+ " 844 | \n",
+ "
\n",
+ " \n",
+ " 64 | \n",
+ " -217 | \n",
+ " 728 | \n",
+ "
\n",
+ " \n",
+ " 65 | \n",
+ " -161 | \n",
+ " 472 | \n",
+ "
\n",
+ " \n",
+ " 66 | \n",
+ " -139 | \n",
+ " 959 | \n",
+ "
\n",
+ " \n",
+ " 67 | \n",
+ " -264 | \n",
+ " 844 | \n",
+ "
\n",
+ " \n",
+ " 68 | \n",
+ " -342 | \n",
+ " 1515 | \n",
+ "
\n",
+ " \n",
+ " 69 | \n",
+ " -231 | \n",
+ " 279 | \n",
+ "
\n",
+ " \n",
+ " 70 | \n",
+ " -209 | \n",
+ " 1427 | \n",
+ "
\n",
+ " \n",
+ " 71 | \n",
+ " -292 | \n",
+ " 2874 | \n",
+ "
\n",
+ " \n",
+ " 72 | \n",
+ " -339 | \n",
+ " 4251 | \n",
+ "
\n",
+ " \n",
+ " 73 | \n",
+ " -371 | \n",
+ " 626 | \n",
+ "
\n",
+ " \n",
+ " 74 | \n",
+ " -331 | \n",
+ " 1254 | \n",
+ "
\n",
+ " \n",
+ " 75 | \n",
+ " -302 | \n",
+ " 986 | \n",
+ "
\n",
+ " \n",
+ " 76 | \n",
+ " -216 | \n",
+ " 1627 | \n",
+ "
\n",
+ " \n",
+ " 77 | \n",
+ " -163 | \n",
+ " 2021 | \n",
+ "
\n",
+ " \n",
+ " 78 | \n",
+ " -367 | \n",
+ " 1366 | \n",
+ "
\n",
+ " \n",
+ " 79 | \n",
+ " -218 | \n",
+ " 1269 | \n",
+ "
\n",
+ " \n",
+ "
\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",
+ " ID | \n",
+ " impact force (mN) | \n",
+ " adhesive force (mN) | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " I | \n",
+ " 0.401419 | \n",
+ " 0.247435 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " II | \n",
+ " 0.585033 | \n",
+ " 0.429701 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " III | \n",
+ " 0.220191 | \n",
+ " 0.415435 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " IV | \n",
+ " 0.546212 | \n",
+ " 0.308042 | \n",
+ "
\n",
+ " \n",
+ "
\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",
+ " ID | \n",
+ " impact force (mN) | \n",
+ " adhesive force (mN) | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " I | \n",
+ " 0.401419 | \n",
+ " 0.247435 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " II | \n",
+ " 0.585033 | \n",
+ " 0.429701 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " III | \n",
+ " 0.220191 | \n",
+ " 0.415435 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " IV | \n",
+ " 0.546212 | \n",
+ " 0.308042 | \n",
+ "
\n",
+ " \n",
+ "
\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",
+ " ID | \n",
+ " impact force (mN) | \n",
+ " adhesive force (mN) | \n",
+ "
\n",
+ " \n",
+ " | \n",
+ " | \n",
+ " mean | \n",
+ " median | \n",
+ " std | \n",
+ " coeff_of_var | \n",
+ " mean | \n",
+ " median | \n",
+ " std | \n",
+ " coeff_of_var | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " I | \n",
+ " 1530.20 | \n",
+ " 1550.5 | \n",
+ " 630.207952 | \n",
+ " 0.401419 | \n",
+ " -658.40 | \n",
+ " -664.5 | \n",
+ " 167.143619 | \n",
+ " 0.247435 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " II | \n",
+ " 707.35 | \n",
+ " 573.0 | \n",
+ " 424.573256 | \n",
+ " 0.585033 | \n",
+ " -462.30 | \n",
+ " -517.0 | \n",
+ " 203.811600 | \n",
+ " 0.429701 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " III | \n",
+ " 550.10 | \n",
+ " 544.0 | \n",
+ " 124.273849 | \n",
+ " 0.220191 | \n",
+ " -206.75 | \n",
+ " -201.5 | \n",
+ " 88.122448 | \n",
+ " 0.415435 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " IV | \n",
+ " 419.10 | \n",
+ " 460.5 | \n",
+ " 234.864328 | \n",
+ " 0.546212 | \n",
+ " -263.60 | \n",
+ " -233.5 | \n",
+ " 83.309442 | \n",
+ " 0.308042 | \n",
+ "
\n",
+ " \n",
+ "
\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",
+ " ID | \n",
+ " quantity | \n",
+ " statistic | \n",
+ " value | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " I | \n",
+ " impact force (mN) | \n",
+ " mean | \n",
+ " 1530.200000 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " II | \n",
+ " impact force (mN) | \n",
+ " mean | \n",
+ " 707.350000 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " III | \n",
+ " impact force (mN) | \n",
+ " mean | \n",
+ " 550.100000 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " IV | \n",
+ " impact force (mN) | \n",
+ " mean | \n",
+ " 419.100000 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " I | \n",
+ " impact force (mN) | \n",
+ " median | \n",
+ " 1550.500000 | \n",
+ "
\n",
+ " \n",
+ " 5 | \n",
+ " II | \n",
+ " impact force (mN) | \n",
+ " median | \n",
+ " 573.000000 | \n",
+ "
\n",
+ " \n",
+ " 6 | \n",
+ " III | \n",
+ " impact force (mN) | \n",
+ " median | \n",
+ " 544.000000 | \n",
+ "
\n",
+ " \n",
+ " 7 | \n",
+ " IV | \n",
+ " impact force (mN) | \n",
+ " median | \n",
+ " 460.500000 | \n",
+ "
\n",
+ " \n",
+ " 8 | \n",
+ " I | \n",
+ " impact force (mN) | \n",
+ " std | \n",
+ " 630.207952 | \n",
+ "
\n",
+ " \n",
+ " 9 | \n",
+ " II | \n",
+ " impact force (mN) | \n",
+ " std | \n",
+ " 424.573256 | \n",
+ "
\n",
+ " \n",
+ " 10 | \n",
+ " III | \n",
+ " impact force (mN) | \n",
+ " std | \n",
+ " 124.273849 | \n",
+ "
\n",
+ " \n",
+ " 11 | \n",
+ " IV | \n",
+ " impact force (mN) | \n",
+ " std | \n",
+ " 234.864328 | \n",
+ "
\n",
+ " \n",
+ " 12 | \n",
+ " I | \n",
+ " impact force (mN) | \n",
+ " coeff_of_var | \n",
+ " 0.401419 | \n",
+ "
\n",
+ " \n",
+ " 13 | \n",
+ " II | \n",
+ " impact force (mN) | \n",
+ " coeff_of_var | \n",
+ " 0.585033 | \n",
+ "
\n",
+ " \n",
+ " 14 | \n",
+ " III | \n",
+ " impact force (mN) | \n",
+ " coeff_of_var | \n",
+ " 0.220191 | \n",
+ "
\n",
+ " \n",
+ " 15 | \n",
+ " IV | \n",
+ " impact force (mN) | \n",
+ " coeff_of_var | \n",
+ " 0.546212 | \n",
+ "
\n",
+ " \n",
+ " 16 | \n",
+ " I | \n",
+ " adhesive force (mN) | \n",
+ " mean | \n",
+ " -658.400000 | \n",
+ "
\n",
+ " \n",
+ " 17 | \n",
+ " II | \n",
+ " adhesive force (mN) | \n",
+ " mean | \n",
+ " -462.300000 | \n",
+ "
\n",
+ " \n",
+ " 18 | \n",
+ " III | \n",
+ " adhesive force (mN) | \n",
+ " mean | \n",
+ " -206.750000 | \n",
+ "
\n",
+ " \n",
+ " 19 | \n",
+ " IV | \n",
+ " adhesive force (mN) | \n",
+ " mean | \n",
+ " -263.600000 | \n",
+ "
\n",
+ " \n",
+ " 20 | \n",
+ " I | \n",
+ " adhesive force (mN) | \n",
+ " median | \n",
+ " -664.500000 | \n",
+ "
\n",
+ " \n",
+ " 21 | \n",
+ " II | \n",
+ " adhesive force (mN) | \n",
+ " median | \n",
+ " -517.000000 | \n",
+ "
\n",
+ " \n",
+ " 22 | \n",
+ " III | \n",
+ " adhesive force (mN) | \n",
+ " median | \n",
+ " -201.500000 | \n",
+ "
\n",
+ " \n",
+ " 23 | \n",
+ " IV | \n",
+ " adhesive force (mN) | \n",
+ " median | \n",
+ " -233.500000 | \n",
+ "
\n",
+ " \n",
+ " 24 | \n",
+ " I | \n",
+ " adhesive force (mN) | \n",
+ " std | \n",
+ " 167.143619 | \n",
+ "
\n",
+ " \n",
+ " 25 | \n",
+ " II | \n",
+ " adhesive force (mN) | \n",
+ " std | \n",
+ " 203.811600 | \n",
+ "
\n",
+ " \n",
+ " 26 | \n",
+ " III | \n",
+ " adhesive force (mN) | \n",
+ " std | \n",
+ " 88.122448 | \n",
+ "
\n",
+ " \n",
+ " 27 | \n",
+ " IV | \n",
+ " adhesive force (mN) | \n",
+ " std | \n",
+ " 83.309442 | \n",
+ "
\n",
+ " \n",
+ " 28 | \n",
+ " I | \n",
+ " adhesive force (mN) | \n",
+ " coeff_of_var | \n",
+ " 0.247435 | \n",
+ "
\n",
+ " \n",
+ " 29 | \n",
+ " II | \n",
+ " adhesive force (mN) | \n",
+ " coeff_of_var | \n",
+ " 0.429701 | \n",
+ "
\n",
+ " \n",
+ " 30 | \n",
+ " III | \n",
+ " adhesive force (mN) | \n",
+ " coeff_of_var | \n",
+ " 0.415435 | \n",
+ "
\n",
+ " \n",
+ " 31 | \n",
+ " IV | \n",
+ " adhesive force (mN) | \n",
+ " coeff_of_var | \n",
+ " 0.308042 | \n",
+ "
\n",
+ " \n",
+ "
\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",
+ " date | \n",
+ " ID | \n",
+ " trial number | \n",
+ " impact force (mN) | \n",
+ " impact time (ms) | \n",
+ " impact force / body weight | \n",
+ " adhesive force (mN) | \n",
+ " time frog pulls on target (ms) | \n",
+ " adhesive force / body weight | \n",
+ " adhesive impulse (N-s) | \n",
+ " total contact area (mm2) | \n",
+ " contact area without mucus (mm2) | \n",
+ " contact area with mucus / contact area without mucus | \n",
+ " contact pressure (Pa) | \n",
+ " adhesive strength (Pa) | \n",
+ " age | \n",
+ " SVL (mm) | \n",
+ " weight (g) | \n",
+ " species | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 2013_02_26 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 1205 | \n",
+ " 46 | \n",
+ " 1.95 | \n",
+ " -785 | \n",
+ " 884 | \n",
+ " 1.27 | \n",
+ " -0.290 | \n",
+ " 387 | \n",
+ " 70 | \n",
+ " 0.82 | \n",
+ " 3117 | \n",
+ " -2030 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.1 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 2013_02_26 | \n",
+ " I | \n",
+ " 4 | \n",
+ " 2527 | \n",
+ " 44 | \n",
+ " 4.08 | \n",
+ " -983 | \n",
+ " 248 | \n",
+ " 1.59 | \n",
+ " -0.181 | \n",
+ " 101 | \n",
+ " 94 | \n",
+ " 0.07 | \n",
+ " 24923 | \n",
+ " -9695 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.1 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 1 | \n",
+ " 1745 | \n",
+ " 34 | \n",
+ " 2.82 | \n",
+ " -850 | \n",
+ " 211 | \n",
+ " 1.37 | \n",
+ " -0.157 | \n",
+ " 83 | \n",
+ " 79 | \n",
+ " 0.05 | \n",
+ " 21020 | \n",
+ " -10239 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.1 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 2 | \n",
+ " 1556 | \n",
+ " 41 | \n",
+ " 2.51 | \n",
+ " -455 | \n",
+ " 1025 | \n",
+ " 0.74 | \n",
+ " -0.170 | \n",
+ " 330 | \n",
+ " 158 | \n",
+ " 0.52 | \n",
+ " 4718 | \n",
+ " -1381 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.1 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 493 | \n",
+ " 36 | \n",
+ " 0.80 | \n",
+ " -974 | \n",
+ " 499 | \n",
+ " 1.57 | \n",
+ " -0.423 | \n",
+ " 245 | \n",
+ " 216 | \n",
+ " 0.12 | \n",
+ " 2012 | \n",
+ " -3975 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.1 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ "
\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",
+ " date | \n",
+ " ID | \n",
+ " trial number | \n",
+ " impact force (mN) | \n",
+ " impact time (ms) | \n",
+ " impact force / body weight | \n",
+ " adhesive force (mN) | \n",
+ " time frog pulls on target (ms) | \n",
+ " adhesive force / body weight | \n",
+ " adhesive impulse (N-s) | \n",
+ " total contact area (mm2) | \n",
+ " contact area without mucus (mm2) | \n",
+ " contact area with mucus / contact area without mucus | \n",
+ " contact pressure (Pa) | \n",
+ " adhesive strength (Pa) | \n",
+ " age | \n",
+ " SVL (mm) | \n",
+ " weight (g) | \n",
+ " species | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 2013_02_26 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 1205 | \n",
+ " 46 | \n",
+ " 1.950000 | \n",
+ " -785 | \n",
+ " 884 | \n",
+ " 1.270000 | \n",
+ " -0.290000 | \n",
+ " 387 | \n",
+ " 70 | \n",
+ " 0.820000 | \n",
+ " 3117 | \n",
+ " -2030 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 2013_02_26 | \n",
+ " I | \n",
+ " 4 | \n",
+ " 2527 | \n",
+ " 44 | \n",
+ " 4.080000 | \n",
+ " -983 | \n",
+ " 248 | \n",
+ " 1.590000 | \n",
+ " -0.181000 | \n",
+ " 101 | \n",
+ " 94 | \n",
+ " 0.070000 | \n",
+ " 24923 | \n",
+ " -9695 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 1 | \n",
+ " 1745 | \n",
+ " 34 | \n",
+ " 2.820000 | \n",
+ " -850 | \n",
+ " 211 | \n",
+ " 1.370000 | \n",
+ " -0.157000 | \n",
+ " 83 | \n",
+ " 79 | \n",
+ " 0.050000 | \n",
+ " 21020 | \n",
+ " -10239 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 2 | \n",
+ " 1556 | \n",
+ " 41 | \n",
+ " 2.510000 | \n",
+ " -455 | \n",
+ " 1025 | \n",
+ " 0.740000 | \n",
+ " -0.170000 | \n",
+ " 330 | \n",
+ " 158 | \n",
+ " 0.520000 | \n",
+ " 4718 | \n",
+ " -1381 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 493 | \n",
+ " 36 | \n",
+ " 0.800000 | \n",
+ " -974 | \n",
+ " 499 | \n",
+ " 1.570000 | \n",
+ " -0.423000 | \n",
+ " 245 | \n",
+ " 216 | \n",
+ " 0.120000 | \n",
+ " 2012 | \n",
+ " -3975 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 5 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 4 | \n",
+ " 2276 | \n",
+ " 31 | \n",
+ " 3.680000 | \n",
+ " -592 | \n",
+ " 969 | \n",
+ " 0.960000 | \n",
+ " -0.176000 | \n",
+ " 341 | \n",
+ " 106 | \n",
+ " 0.690000 | \n",
+ " 6676 | \n",
+ " -1737 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 6 | \n",
+ " 2013_03_05 | \n",
+ " I | \n",
+ " 1 | \n",
+ " 556 | \n",
+ " 43 | \n",
+ " 0.900000 | \n",
+ " -512 | \n",
+ " 835 | \n",
+ " 0.830000 | \n",
+ " -0.285000 | \n",
+ " 359 | \n",
+ " 110 | \n",
+ " 0.690000 | \n",
+ " 1550 | \n",
+ " -1427 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 7 | \n",
+ " 2013_03_05 | \n",
+ " I | \n",
+ " 2 | \n",
+ " 1928 | \n",
+ " 46 | \n",
+ " 3.110000 | \n",
+ " -804 | \n",
+ " 508 | \n",
+ " 1.300000 | \n",
+ " -0.285000 | \n",
+ " 246 | \n",
+ " 178 | \n",
+ " 0.280000 | \n",
+ " 7832 | \n",
+ " -3266 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 8 | \n",
+ " 2013_03_05 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 2641 | \n",
+ " 50 | \n",
+ " 4.270000 | \n",
+ " -690 | \n",
+ " 491 | \n",
+ " 1.120000 | \n",
+ " -0.239000 | \n",
+ " 269 | \n",
+ " 224 | \n",
+ " 0.170000 | \n",
+ " 9824 | \n",
+ " -2568 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 9 | \n",
+ " 2013_03_05 | \n",
+ " I | \n",
+ " 4 | \n",
+ " 1897 | \n",
+ " 41 | \n",
+ " 3.060000 | \n",
+ " -462 | \n",
+ " 839 | \n",
+ " 0.750000 | \n",
+ " -0.328000 | \n",
+ " 266 | \n",
+ " 176 | \n",
+ " 0.340000 | \n",
+ " 7122 | \n",
+ " -1733 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 10 | \n",
+ " 2013_03_12 | \n",
+ " I | \n",
+ " 1 | \n",
+ " 1891 | \n",
+ " 40 | \n",
+ " 3.060000 | \n",
+ " -766 | \n",
+ " 1069 | \n",
+ " 1.240000 | \n",
+ " -0.380000 | \n",
+ " 408 | \n",
+ " 33 | \n",
+ " 0.920000 | \n",
+ " 4638 | \n",
+ " -1879 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 11 | \n",
+ " 2013_03_12 | \n",
+ " I | \n",
+ " 2 | \n",
+ " 1545 | \n",
+ " 48 | \n",
+ " 2.500000 | \n",
+ " -715 | \n",
+ " 649 | \n",
+ " 1.150000 | \n",
+ " -0.298000 | \n",
+ " 141 | \n",
+ " 112 | \n",
+ " 0.210000 | \n",
+ " 10947 | \n",
+ " -5064 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 12 | \n",
+ " 2013_03_12 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 1307 | \n",
+ " 29 | \n",
+ " 2.110000 | \n",
+ " -613 | \n",
+ " 1845 | \n",
+ " 0.990000 | \n",
+ " -0.768000 | \n",
+ " 455 | \n",
+ " 92 | \n",
+ " 0.800000 | \n",
+ " 2874 | \n",
+ " -1348 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 13 | \n",
+ " 2013_03_12 | \n",
+ " I | \n",
+ " 4 | \n",
+ " 1692 | \n",
+ " 31 | \n",
+ " 2.730000 | \n",
+ " -677 | \n",
+ " 917 | \n",
+ " 1.090000 | \n",
+ " -0.457000 | \n",
+ " 186 | \n",
+ " 129 | \n",
+ " 0.310000 | \n",
+ " 9089 | \n",
+ " -3636 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 14 | \n",
+ " 2013_03_12 | \n",
+ " I | \n",
+ " 5 | \n",
+ " 1543 | \n",
+ " 38 | \n",
+ " 2.490000 | \n",
+ " -528 | \n",
+ " 750 | \n",
+ " 0.850000 | \n",
+ " -0.353000 | \n",
+ " 153 | \n",
+ " 148 | \n",
+ " 0.030000 | \n",
+ " 10095 | \n",
+ " -3453 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 15 | \n",
+ " 2013_03_15 | \n",
+ " I | \n",
+ " 1 | \n",
+ " 1282 | \n",
+ " 31 | \n",
+ " 2.070000 | \n",
+ " -452 | \n",
+ " 785 | \n",
+ " 0.730000 | \n",
+ " -0.253000 | \n",
+ " 290 | \n",
+ " 105 | \n",
+ " 0.640000 | \n",
+ " 4419 | \n",
+ " -1557 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 16 | \n",
+ " 2013_03_15 | \n",
+ " I | \n",
+ " 2 | \n",
+ " 775 | \n",
+ " 34 | \n",
+ " 1.250000 | \n",
+ " -430 | \n",
+ " 837 | \n",
+ " 0.700000 | \n",
+ " -0.276000 | \n",
+ " 257 | \n",
+ " 124 | \n",
+ " 0.520000 | \n",
+ " 3019 | \n",
+ " -1677 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 17 | \n",
+ " 2013_03_15 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 2032 | \n",
+ " 60 | \n",
+ " 3.280000 | \n",
+ " -652 | \n",
+ " 486 | \n",
+ " 1.050000 | \n",
+ " -0.257000 | \n",
+ " 147 | \n",
+ " 134 | \n",
+ " 0.090000 | \n",
+ " 13784 | \n",
+ " -4425 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 18 | \n",
+ " 2013_03_15 | \n",
+ " I | \n",
+ " 4 | \n",
+ " 1240 | \n",
+ " 34 | \n",
+ " 2.000000 | \n",
+ " -692 | \n",
+ " 906 | \n",
+ " 1.120000 | \n",
+ " -0.317000 | \n",
+ " 364 | \n",
+ " 260 | \n",
+ " 0.280000 | \n",
+ " 3406 | \n",
+ " -1901 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 19 | \n",
+ " 2013_03_15 | \n",
+ " I | \n",
+ " 5 | \n",
+ " 473 | \n",
+ " 40 | \n",
+ " 0.760000 | \n",
+ " -536 | \n",
+ " 1218 | \n",
+ " 0.870000 | \n",
+ " -0.382000 | \n",
+ " 259 | \n",
+ " 168 | \n",
+ " 0.350000 | \n",
+ " 1830 | \n",
+ " -2073 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 20 | \n",
+ " 2013_03_19 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 1612 | \n",
+ " 18 | \n",
+ " 3.790000 | \n",
+ " -655 | \n",
+ " 3087 | \n",
+ " 1.540000 | \n",
+ " -0.385000 | \n",
+ " 348 | \n",
+ " 15 | \n",
+ " 0.960000 | \n",
+ " 4633 | \n",
+ " -1881 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 21 | \n",
+ " 2013_03_19 | \n",
+ " II | \n",
+ " 2 | \n",
+ " 605 | \n",
+ " 55 | \n",
+ " 1.420000 | \n",
+ " -292 | \n",
+ " 1261 | \n",
+ " 0.690000 | \n",
+ " -0.294000 | \n",
+ " 248 | \n",
+ " 24 | \n",
+ " 0.900000 | \n",
+ " 2441 | \n",
+ " -1177 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 22 | \n",
+ " 2013_03_19 | \n",
+ " II | \n",
+ " 3 | \n",
+ " 327 | \n",
+ " 51 | \n",
+ " 0.770000 | \n",
+ " -246 | \n",
+ " 1508 | \n",
+ " 0.580000 | \n",
+ " -0.282000 | \n",
+ " 130 | \n",
+ " 34 | \n",
+ " 0.740000 | \n",
+ " 2517 | \n",
+ " -1894 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 23 | \n",
+ " 2013_03_19 | \n",
+ " II | \n",
+ " 4 | \n",
+ " 946 | \n",
+ " 59 | \n",
+ " 2.230000 | \n",
+ " -245 | \n",
+ " 1841 | \n",
+ " 0.580000 | \n",
+ " -0.340000 | \n",
+ " 106 | \n",
+ " 26 | \n",
+ " 0.760000 | \n",
+ " 8893 | \n",
+ " -2301 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 24 | \n",
+ " 2013_03_21 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 541 | \n",
+ " 33 | \n",
+ " 1.270000 | \n",
+ " -553 | \n",
+ " 3126 | \n",
+ " 1.300000 | \n",
+ " -0.432000 | \n",
+ " 276 | \n",
+ " 16 | \n",
+ " 0.940000 | \n",
+ " 1959 | \n",
+ " -2004 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 25 | \n",
+ " 2013_03_21 | \n",
+ " II | \n",
+ " 2 | \n",
+ " 1539 | \n",
+ " 43 | \n",
+ " 3.620000 | \n",
+ " -664 | \n",
+ " 741 | \n",
+ " 1.560000 | \n",
+ " -0.046000 | \n",
+ " 85 | \n",
+ " 24 | \n",
+ " 0.720000 | \n",
+ " 18073 | \n",
+ " -7802 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 26 | \n",
+ " 2013_03_21 | \n",
+ " II | \n",
+ " 3 | \n",
+ " 529 | \n",
+ " 28 | \n",
+ " 1.240000 | \n",
+ " -261 | \n",
+ " 2482 | \n",
+ " 0.610000 | \n",
+ " -0.414000 | \n",
+ " 325 | \n",
+ " 33 | \n",
+ " 0.900000 | \n",
+ " 1627 | \n",
+ " -803 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 27 | \n",
+ " 2013_03_21 | \n",
+ " II | \n",
+ " 4 | \n",
+ " 628 | \n",
+ " 31 | \n",
+ " 1.480000 | \n",
+ " -691 | \n",
+ " 998 | \n",
+ " 1.630000 | \n",
+ " -0.071000 | \n",
+ " 242 | \n",
+ " 67 | \n",
+ " 0.720000 | \n",
+ " 2600 | \n",
+ " -2860 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 28 | \n",
+ " 2013_03_25 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 1453 | \n",
+ " 72 | \n",
+ " 3.420000 | \n",
+ " -92 | \n",
+ " 1652 | \n",
+ " 0.220000 | \n",
+ " -0.008000 | \n",
+ " 136 | \n",
+ " 0 | \n",
+ " 1.000000 | \n",
+ " 10645 | \n",
+ " -678 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 29 | \n",
+ " 2013_03_25 | \n",
+ " II | \n",
+ " 2 | \n",
+ " 297 | \n",
+ " 42 | \n",
+ " 0.700000 | \n",
+ " -566 | \n",
+ " 936 | \n",
+ " 1.330000 | \n",
+ " -0.084000 | \n",
+ " 126 | \n",
+ " 4 | \n",
+ " 0.970000 | \n",
+ " 2367 | \n",
+ " -4506 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 30 | \n",
+ " 2013_03_25 | \n",
+ " II | \n",
+ " 3 | \n",
+ " 703 | \n",
+ " 33 | \n",
+ " 1.650000 | \n",
+ " -223 | \n",
+ " 2152 | \n",
+ " 0.520000 | \n",
+ " -0.209000 | \n",
+ " 237 | \n",
+ " 8 | \n",
+ " 0.970000 | \n",
+ " 2972 | \n",
+ " -942 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 31 | \n",
+ " 2013_03_25 | \n",
+ " II | \n",
+ " 4 | \n",
+ " 269 | \n",
+ " 57 | \n",
+ " 0.630000 | \n",
+ " -512 | \n",
+ " 189 | \n",
+ " 1.200000 | \n",
+ " -0.055000 | \n",
+ " 29 | \n",
+ " 28 | \n",
+ " 0.030000 | \n",
+ " 9279 | \n",
+ " -17652 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 32 | \n",
+ " 2013_03_28 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 751 | \n",
+ " 39 | \n",
+ " 1.770000 | \n",
+ " -227 | \n",
+ " 1195 | \n",
+ " 0.530000 | \n",
+ " -0.026000 | \n",
+ " 206 | \n",
+ " 0 | \n",
+ " 1.000000 | \n",
+ " 3647 | \n",
+ " -1101 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 33 | \n",
+ " 2013_03_28 | \n",
+ " II | \n",
+ " 2 | \n",
+ " 245 | \n",
+ " 21 | \n",
+ " 0.580000 | \n",
+ " -573 | \n",
+ " 1466 | \n",
+ " 1.350000 | \n",
+ " -0.215000 | \n",
+ " 190 | \n",
+ " 46 | \n",
+ " 0.760000 | \n",
+ " 1288 | \n",
+ " -3014 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 34 | \n",
+ " 2013_04_03 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 1182 | \n",
+ " 28 | \n",
+ " 2.780000 | \n",
+ " -522 | \n",
+ " 1197 | \n",
+ " 1.230000 | \n",
+ " -0.118000 | \n",
+ " 281 | \n",
+ " 0 | \n",
+ " 1.000000 | \n",
+ " 4213 | \n",
+ " -1860 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 35 | \n",
+ " 2013_04_03 | \n",
+ " II | \n",
+ " 2 | \n",
+ " 515 | \n",
+ " 29 | \n",
+ " 1.210000 | \n",
+ " -599 | \n",
+ " 1486 | \n",
+ " 1.410000 | \n",
+ " -0.226000 | \n",
+ " 217 | \n",
+ " 0 | \n",
+ " 1.000000 | \n",
+ " 2369 | \n",
+ " -2757 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 36 | \n",
+ " 2013_04_08 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 435 | \n",
+ " 26 | \n",
+ " 1.020000 | \n",
+ " -364 | \n",
+ " 1017 | \n",
+ " 0.860000 | \n",
+ " -0.211000 | \n",
+ " 189 | \n",
+ " 89 | \n",
+ " 0.530000 | \n",
+ " 2302 | \n",
+ " -1927 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 37 | \n",
+ " 2013_04_08 | \n",
+ " II | \n",
+ " 2 | \n",
+ " 383 | \n",
+ " 31 | \n",
+ " 0.900000 | \n",
+ " -469 | \n",
+ " 974 | \n",
+ " 1.100000 | \n",
+ " -0.260000 | \n",
+ " 221 | \n",
+ " 72 | \n",
+ " 0.670000 | \n",
+ " 1737 | \n",
+ " -2129 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 38 | \n",
+ " 2013_04_08 | \n",
+ " II | \n",
+ " 3 | \n",
+ " 457 | \n",
+ " 15 | \n",
+ " 1.080000 | \n",
+ " -844 | \n",
+ " 780 | \n",
+ " 1.990000 | \n",
+ " -0.328000 | \n",
+ " 171 | \n",
+ " 106 | \n",
+ " 0.380000 | \n",
+ " 2665 | \n",
+ " -4925 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 39 | \n",
+ " 2013_04_12 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 730 | \n",
+ " 42 | \n",
+ " 1.720000 | \n",
+ " -648 | \n",
+ " 786 | \n",
+ " 1.520000 | \n",
+ " -0.121000 | \n",
+ " 142 | \n",
+ " 43 | \n",
+ " 0.700000 | \n",
+ " 5149 | \n",
+ " -4573 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ "
\n",
+ " \n",
+ " 40 | \n",
+ " 2013_05_27 | \n",
+ " III | \n",
+ " 1 | \n",
+ " 614 | \n",
+ " 88 | \n",
+ " 4.940000 | \n",
+ " -94 | \n",
+ " 683 | \n",
+ " 0.760000 | \n",
+ " -0.001000 | \n",
+ " 97 | \n",
+ " 15 | \n",
+ " 0.830000 | \n",
+ " 6326 | \n",
+ " -967 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 41 | \n",
+ " 2013_05_27 | \n",
+ " III | \n",
+ " 2 | \n",
+ " 414 | \n",
+ " 143 | \n",
+ " 3.330000 | \n",
+ " -163 | \n",
+ " 245 | \n",
+ " 1.310000 | \n",
+ " -0.032000 | \n",
+ " 108 | \n",
+ " 10 | \n",
+ " 0.600000 | \n",
+ " 3824 | \n",
+ " -1507 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 42 | \n",
+ " 2013_05_27 | \n",
+ " III | \n",
+ " 3 | \n",
+ " 324 | \n",
+ " 105 | \n",
+ " 2.610000 | \n",
+ " -172 | \n",
+ " 619 | \n",
+ " 1.380000 | \n",
+ " -0.079000 | \n",
+ " 55 | \n",
+ " 23 | \n",
+ " 0.370000 | \n",
+ " 5946 | \n",
+ " -3149 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 43 | \n",
+ " 2013_06_11 | \n",
+ " III | \n",
+ " 1 | \n",
+ " 776 | \n",
+ " 35 | \n",
+ " 6.240000 | \n",
+ " -225 | \n",
+ " 1823 | \n",
+ " 1.810000 | \n",
+ " -0.132000 | \n",
+ " 124 | \n",
+ " 17 | \n",
+ " 0.770000 | \n",
+ " 6272 | \n",
+ " -1818 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 44 | \n",
+ " 2013_06_11 | \n",
+ " III | \n",
+ " 2 | \n",
+ " 611 | \n",
+ " 29 | \n",
+ " 4.910000 | \n",
+ " -301 | \n",
+ " 918 | \n",
+ " 2.420000 | \n",
+ " -0.155000 | \n",
+ " 128 | \n",
+ " 43 | \n",
+ " 0.020000 | \n",
+ " 4770 | \n",
+ " -2354 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 45 | \n",
+ " 2013_06_11 | \n",
+ " III | \n",
+ " 3 | \n",
+ " 544 | \n",
+ " 16 | \n",
+ " 4.380000 | \n",
+ " -93 | \n",
+ " 1351 | \n",
+ " 0.750000 | \n",
+ " -0.110000 | \n",
+ " 43 | \n",
+ " 34 | \n",
+ " 0.710000 | \n",
+ " 12699 | \n",
+ " -2181 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 46 | \n",
+ " 2013_06_14 | \n",
+ " III | \n",
+ " 1 | \n",
+ " 538 | \n",
+ " 38 | \n",
+ " 4.320000 | \n",
+ " -131 | \n",
+ " 1790 | \n",
+ " 1.050000 | \n",
+ " -0.036000 | \n",
+ " 130 | \n",
+ " 74 | \n",
+ " 1.000000 | \n",
+ " 4130 | \n",
+ " -1005 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 47 | \n",
+ " 2013_06_14 | \n",
+ " III | \n",
+ " 2 | \n",
+ " 579 | \n",
+ " 31 | \n",
+ " 4.660000 | \n",
+ " -289 | \n",
+ " 1006 | \n",
+ " 2.330000 | \n",
+ " -0.073000 | \n",
+ " 113 | \n",
+ " 4 | \n",
+ " 0.480000 | \n",
+ " 5110 | \n",
+ " -2555 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 48 | \n",
+ " 2013_06_18 | \n",
+ " III | \n",
+ " 1 | \n",
+ " 806 | \n",
+ " 29 | \n",
+ " 6.490000 | \n",
+ " -104 | \n",
+ " 883 | \n",
+ " 0.840000 | \n",
+ " -0.055000 | \n",
+ " 115 | \n",
+ " 55 | \n",
+ " 0.660000 | \n",
+ " 6993 | \n",
+ " -902 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 49 | \n",
+ " 2013_06_18 | \n",
+ " III | \n",
+ " 2 | \n",
+ " 459 | \n",
+ " 32 | \n",
+ " 3.700000 | \n",
+ " -229 | \n",
+ " 1218 | \n",
+ " 1.850000 | \n",
+ " -0.137000 | \n",
+ " 89 | \n",
+ " 6 | \n",
+ " 0.950000 | \n",
+ " 5165 | \n",
+ " -2580 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 50 | \n",
+ " 2013_06_18 | \n",
+ " III | \n",
+ " 3 | \n",
+ " 458 | \n",
+ " 30 | \n",
+ " 3.690000 | \n",
+ " -259 | \n",
+ " 910 | \n",
+ " 2.080000 | \n",
+ " -0.194000 | \n",
+ " 91 | \n",
+ " 88 | \n",
+ " 0.150000 | \n",
+ " 5048 | \n",
+ " -2855 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 51 | \n",
+ " 2013_06_18 | \n",
+ " III | \n",
+ " 4 | \n",
+ " 626 | \n",
+ " 16 | \n",
+ " 5.040000 | \n",
+ " -231 | \n",
+ " 550 | \n",
+ " 1.860000 | \n",
+ " -0.042000 | \n",
+ " 82 | \n",
+ " 23 | \n",
+ " 0.010000 | \n",
+ " 7633 | \n",
+ " -2819 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 52 | \n",
+ " 2013_06_21 | \n",
+ " III | \n",
+ " 1 | \n",
+ " 621 | \n",
+ " 27 | \n",
+ " 4.990000 | \n",
+ " -267 | \n",
+ " 2081 | \n",
+ " 2.140000 | \n",
+ " -0.183000 | \n",
+ " 120 | \n",
+ " 58 | \n",
+ " 0.900000 | \n",
+ " 5152 | \n",
+ " -2213 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 53 | \n",
+ " 2013_06_21 | \n",
+ " III | \n",
+ " 2 | \n",
+ " 544 | \n",
+ " 30 | \n",
+ " 4.380000 | \n",
+ " -178 | \n",
+ " 376 | \n",
+ " 1.430000 | \n",
+ " -0.034000 | \n",
+ " 19 | \n",
+ " 17 | \n",
+ " 0.050000 | \n",
+ " 28641 | \n",
+ " -9364 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 54 | \n",
+ " 2013_06_21 | \n",
+ " III | \n",
+ " 3 | \n",
+ " 535 | \n",
+ " 35 | \n",
+ " 4.300000 | \n",
+ " -123 | \n",
+ " 289 | \n",
+ " 0.990000 | \n",
+ " -0.029000 | \n",
+ " 21 | \n",
+ " 29 | \n",
+ " 0.050000 | \n",
+ " 25471 | \n",
+ " -5843 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 55 | \n",
+ " 2013_06_21 | \n",
+ " III | \n",
+ " 4 | \n",
+ " 385 | \n",
+ " 39 | \n",
+ " 3.090000 | \n",
+ " -151 | \n",
+ " 607 | \n",
+ " 1.220000 | \n",
+ " -0.082000 | \n",
+ " 31 | \n",
+ " 126 | \n",
+ " 0.030000 | \n",
+ " 12409 | \n",
+ " -4882 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 56 | \n",
+ " 2013_06_26 | \n",
+ " III | \n",
+ " 1 | \n",
+ " 401 | \n",
+ " 36 | \n",
+ " 3.230000 | \n",
+ " -127 | \n",
+ " 2932 | \n",
+ " 1.020000 | \n",
+ " -0.215000 | \n",
+ " 142 | \n",
+ " 12 | \n",
+ " 0.860000 | \n",
+ " 2835 | \n",
+ " -896 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 57 | \n",
+ " 2013_06_26 | \n",
+ " III | \n",
+ " 2 | \n",
+ " 614 | \n",
+ " 34 | \n",
+ " 4.940000 | \n",
+ " -372 | \n",
+ " 680 | \n",
+ " 2.990000 | \n",
+ " -0.140000 | \n",
+ " 72 | \n",
+ " 1 | \n",
+ " 0.420000 | \n",
+ " 8475 | \n",
+ " -5136 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 58 | \n",
+ " 2013_06_26 | \n",
+ " III | \n",
+ " 3 | \n",
+ " 665 | \n",
+ " 40 | \n",
+ " 5.350000 | \n",
+ " -236 | \n",
+ " 685 | \n",
+ " 1.900000 | \n",
+ " -0.118000 | \n",
+ " 129 | \n",
+ " 0 | \n",
+ " 0.160000 | \n",
+ " 5171 | \n",
+ " -1834 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 59 | \n",
+ " 2013_06_26 | \n",
+ " III | \n",
+ " 4 | \n",
+ " 488 | \n",
+ " 34 | \n",
+ " 3.930000 | \n",
+ " -390 | \n",
+ " 1308 | \n",
+ " 3.140000 | \n",
+ " -0.208000 | \n",
+ " 112 | \n",
+ " 58 | \n",
+ " 0.390000 | \n",
+ " 4376 | \n",
+ " -3492 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 60 | \n",
+ " 2013_05_27 | \n",
+ " IV | \n",
+ " 2 | \n",
+ " 172 | \n",
+ " 26 | \n",
+ " 1.280000 | \n",
+ " -456 | \n",
+ " 462 | \n",
+ " 3.400000 | \n",
+ " -0.050000 | \n",
+ " 133 | \n",
+ " 0 | \n",
+ " 0.880000 | \n",
+ " 1297 | \n",
+ " -3440 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 61 | \n",
+ " 2013_05_27 | \n",
+ " IV | \n",
+ " 3 | \n",
+ " 142 | \n",
+ " 20 | \n",
+ " 1.050000 | \n",
+ " -193 | \n",
+ " 250 | \n",
+ " 1.440000 | \n",
+ " -0.047000 | \n",
+ " 57 | \n",
+ " 74 | \n",
+ " 0.830000 | \n",
+ " 2498 | \n",
+ " -3400 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 62 | \n",
+ " 2013_05_27 | \n",
+ " IV | \n",
+ " 4 | \n",
+ " 37 | \n",
+ " 55 | \n",
+ " 0.280000 | \n",
+ " -236 | \n",
+ " 743 | \n",
+ " 1.760000 | \n",
+ " -0.119000 | \n",
+ " 51 | \n",
+ " 44 | \n",
+ " 0.540000 | \n",
+ " 735 | \n",
+ " -4647 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 63 | \n",
+ " 2013_05_30 | \n",
+ " IV | \n",
+ " 1 | \n",
+ " 453 | \n",
+ " 38 | \n",
+ " 3.370000 | \n",
+ " -225 | \n",
+ " 844 | \n",
+ " 1.680000 | \n",
+ " -0.110000 | \n",
+ " 142 | \n",
+ " 108 | \n",
+ " 0.480000 | \n",
+ " 3177 | \n",
+ " -1581 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 64 | \n",
+ " 2013_05_30 | \n",
+ " IV | \n",
+ " 2 | \n",
+ " 355 | \n",
+ " 31 | \n",
+ " 2.640000 | \n",
+ " -217 | \n",
+ " 728 | \n",
+ " 1.610000 | \n",
+ " -0.023000 | \n",
+ " 174 | \n",
+ " 39 | \n",
+ " 0.980000 | \n",
+ " 2037 | \n",
+ " -1245 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 65 | \n",
+ " 2013_05_30 | \n",
+ " IV | \n",
+ " 3 | \n",
+ " 22 | \n",
+ " 33 | \n",
+ " 0.170000 | \n",
+ " -161 | \n",
+ " 472 | \n",
+ " 1.200000 | \n",
+ " -0.052000 | \n",
+ " 56 | \n",
+ " 4 | \n",
+ " 0.020000 | \n",
+ " 397 | \n",
+ " -2866 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 66 | \n",
+ " 2013_06_03 | \n",
+ " IV | \n",
+ " 1 | \n",
+ " 502 | \n",
+ " 74 | \n",
+ " 3.740000 | \n",
+ " -139 | \n",
+ " 959 | \n",
+ " 1.040000 | \n",
+ " -0.089000 | \n",
+ " 65 | \n",
+ " 77 | \n",
+ " 0.910000 | \n",
+ " 7713 | \n",
+ " -2141 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 67 | \n",
+ " 2013_06_11 | \n",
+ " IV | \n",
+ " 1 | \n",
+ " 273 | \n",
+ " 26 | \n",
+ " 2.030000 | \n",
+ " -264 | \n",
+ " 844 | \n",
+ " 1.970000 | \n",
+ " -0.160000 | \n",
+ " 124 | \n",
+ " 81 | \n",
+ " 0.290000 | \n",
+ " 2205 | \n",
+ " -2136 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 68 | \n",
+ " 2013_06_11 | \n",
+ " IV | \n",
+ " 2 | \n",
+ " 720 | \n",
+ " 27 | \n",
+ " 5.360000 | \n",
+ " -342 | \n",
+ " 1515 | \n",
+ " 2.550000 | \n",
+ " -0.226000 | \n",
+ " 137 | \n",
+ " 0 | \n",
+ " 0.830000 | \n",
+ " 5259 | \n",
+ " -2497 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 69 | \n",
+ " 2013_06_11 | \n",
+ " IV | \n",
+ " 3 | \n",
+ " 582 | \n",
+ " 33 | \n",
+ " 4.340000 | \n",
+ " -231 | \n",
+ " 279 | \n",
+ " 1.720000 | \n",
+ " -0.033000 | \n",
+ " 60 | \n",
+ " 4 | \n",
+ " 0.030000 | \n",
+ " 9705 | \n",
+ " -3847 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 70 | \n",
+ " 2013_06_11 | \n",
+ " IV | \n",
+ " 4 | \n",
+ " 198 | \n",
+ " 23 | \n",
+ " 1.470000 | \n",
+ " -209 | \n",
+ " 1427 | \n",
+ " 1.550000 | \n",
+ " -0.151000 | \n",
+ " 110 | \n",
+ " 69 | \n",
+ " 0.840000 | \n",
+ " 1793 | \n",
+ " -1889 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 71 | \n",
+ " 2013_06_14 | \n",
+ " IV | \n",
+ " 1 | \n",
+ " 198 | \n",
+ " 6 | \n",
+ " 1.470000 | \n",
+ " -292 | \n",
+ " 2874 | \n",
+ " 2.170000 | \n",
+ " -0.232000 | \n",
+ " 145 | \n",
+ " 50 | \n",
+ " 0.990000 | \n",
+ " 1369 | \n",
+ " -2018 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 72 | \n",
+ " 2013_06_18 | \n",
+ " IV | \n",
+ " 1 | \n",
+ " 597 | \n",
+ " 29 | \n",
+ " 4.440000 | \n",
+ " -339 | \n",
+ " 4251 | \n",
+ " 2.530000 | \n",
+ " -0.281000 | \n",
+ " 191 | \n",
+ " 12 | \n",
+ " 1.000000 | \n",
+ " 3116 | \n",
+ " -1772 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 73 | \n",
+ " 2013_06_18 | \n",
+ " IV | \n",
+ " 2 | \n",
+ " 516 | \n",
+ " 31 | \n",
+ " 3.840000 | \n",
+ " -371 | \n",
+ " 626 | \n",
+ " 2.760000 | \n",
+ " -0.094000 | \n",
+ " 83 | \n",
+ " 18 | \n",
+ " 0.120000 | \n",
+ " 6184 | \n",
+ " -4447 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 74 | \n",
+ " 2013_06_18 | \n",
+ " IV | \n",
+ " 3 | \n",
+ " 815 | \n",
+ " 34 | \n",
+ " 6.070000 | \n",
+ " -331 | \n",
+ " 1254 | \n",
+ " 2.470000 | \n",
+ " -0.077000 | \n",
+ " 151 | \n",
+ " 20 | \n",
+ " 0.710000 | \n",
+ " 5386 | \n",
+ " -2190 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 75 | \n",
+ " 2013_06_18 | \n",
+ " IV | \n",
+ " 4 | \n",
+ " 402 | \n",
+ " 38 | \n",
+ " 3.000000 | \n",
+ " -302 | \n",
+ " 986 | \n",
+ " 2.250000 | \n",
+ " -0.122000 | \n",
+ " 117 | \n",
+ " 30 | \n",
+ " 0.070000 | \n",
+ " 3446 | \n",
+ " -2591 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 76 | \n",
+ " 2013_06_21 | \n",
+ " IV | \n",
+ " 1 | \n",
+ " 605 | \n",
+ " 39 | \n",
+ " 4.500000 | \n",
+ " -216 | \n",
+ " 1627 | \n",
+ " 1.610000 | \n",
+ " -0.139000 | \n",
+ " 123 | \n",
+ " 20 | \n",
+ " 1.000000 | \n",
+ " 4928 | \n",
+ " -1759 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 77 | \n",
+ " 2013_06_21 | \n",
+ " IV | \n",
+ " 2 | \n",
+ " 711 | \n",
+ " 76 | \n",
+ " 5.300000 | \n",
+ " -163 | \n",
+ " 2021 | \n",
+ " 1.210000 | \n",
+ " -0.217000 | \n",
+ " 129 | \n",
+ " 42 | \n",
+ " 0.970000 | \n",
+ " 5498 | \n",
+ " -1257 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 78 | \n",
+ " 2013_06_21 | \n",
+ " IV | \n",
+ " 3 | \n",
+ " 614 | \n",
+ " 33 | \n",
+ " 4.570000 | \n",
+ " -367 | \n",
+ " 1366 | \n",
+ " 2.730000 | \n",
+ " -0.198000 | \n",
+ " 128 | \n",
+ " 108 | \n",
+ " 0.460000 | \n",
+ " 4776 | \n",
+ " -2857 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ " 79 | \n",
+ " 2013_06_21 | \n",
+ " IV | \n",
+ " 4 | \n",
+ " 468 | \n",
+ " 36 | \n",
+ " 3.480000 | \n",
+ " -218 | \n",
+ " 1269 | \n",
+ " 1.630000 | \n",
+ " -0.122000 | \n",
+ " 129 | \n",
+ " 68 | \n",
+ " 0.610000 | \n",
+ " 3617 | \n",
+ " -1688 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ "
\n",
+ " \n",
+ "
\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",
+ " date | \n",
+ " ID | \n",
+ " trial number | \n",
+ " impact force (mN) | \n",
+ " impact time (ms) | \n",
+ " impact force / body weight | \n",
+ " adhesive force (mN) | \n",
+ " time frog pulls on target (ms) | \n",
+ " adhesive force / body weight | \n",
+ " adhesive impulse (N-s) | \n",
+ " total contact area (mm2) | \n",
+ " contact area without mucus (mm2) | \n",
+ " contact area with mucus / contact area without mucus | \n",
+ " contact pressure (Pa) | \n",
+ " adhesive strength (Pa) | \n",
+ " age | \n",
+ " SVL (mm) | \n",
+ " weight (g) | \n",
+ " species | \n",
+ " max_strike | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 2013_02_26 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 1205 | \n",
+ " 46 | \n",
+ " 1.950000 | \n",
+ " -785 | \n",
+ " 884 | \n",
+ " 1.270000 | \n",
+ " -0.290000 | \n",
+ " 387 | \n",
+ " 70 | \n",
+ " 0.820000 | \n",
+ " 3117 | \n",
+ " -2030 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 2013_02_26 | \n",
+ " I | \n",
+ " 4 | \n",
+ " 2527 | \n",
+ " 44 | \n",
+ " 4.080000 | \n",
+ " -983 | \n",
+ " 248 | \n",
+ " 1.590000 | \n",
+ " -0.181000 | \n",
+ " 101 | \n",
+ " 94 | \n",
+ " 0.070000 | \n",
+ " 24923 | \n",
+ " -9695 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 1 | \n",
+ " 1745 | \n",
+ " 34 | \n",
+ " 2.820000 | \n",
+ " -850 | \n",
+ " 211 | \n",
+ " 1.370000 | \n",
+ " -0.157000 | \n",
+ " 83 | \n",
+ " 79 | \n",
+ " 0.050000 | \n",
+ " 21020 | \n",
+ " -10239 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 2 | \n",
+ " 1556 | \n",
+ " 41 | \n",
+ " 2.510000 | \n",
+ " -455 | \n",
+ " 1025 | \n",
+ " 0.740000 | \n",
+ " -0.170000 | \n",
+ " 330 | \n",
+ " 158 | \n",
+ " 0.520000 | \n",
+ " 4718 | \n",
+ " -1381 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 493 | \n",
+ " 36 | \n",
+ " 0.800000 | \n",
+ " -974 | \n",
+ " 499 | \n",
+ " 1.570000 | \n",
+ " -0.423000 | \n",
+ " 245 | \n",
+ " 216 | \n",
+ " 0.120000 | \n",
+ " 2012 | \n",
+ " -3975 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 5 | \n",
+ " 2013_03_01 | \n",
+ " I | \n",
+ " 4 | \n",
+ " 2276 | \n",
+ " 31 | \n",
+ " 3.680000 | \n",
+ " -592 | \n",
+ " 969 | \n",
+ " 0.960000 | \n",
+ " -0.176000 | \n",
+ " 341 | \n",
+ " 106 | \n",
+ " 0.690000 | \n",
+ " 6676 | \n",
+ " -1737 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 6 | \n",
+ " 2013_03_05 | \n",
+ " I | \n",
+ " 1 | \n",
+ " 556 | \n",
+ " 43 | \n",
+ " 0.900000 | \n",
+ " -512 | \n",
+ " 835 | \n",
+ " 0.830000 | \n",
+ " -0.285000 | \n",
+ " 359 | \n",
+ " 110 | \n",
+ " 0.690000 | \n",
+ " 1550 | \n",
+ " -1427 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 7 | \n",
+ " 2013_03_05 | \n",
+ " I | \n",
+ " 2 | \n",
+ " 1928 | \n",
+ " 46 | \n",
+ " 3.110000 | \n",
+ " -804 | \n",
+ " 508 | \n",
+ " 1.300000 | \n",
+ " -0.285000 | \n",
+ " 246 | \n",
+ " 178 | \n",
+ " 0.280000 | \n",
+ " 7832 | \n",
+ " -3266 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 8 | \n",
+ " 2013_03_05 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 2641 | \n",
+ " 50 | \n",
+ " 4.270000 | \n",
+ " -690 | \n",
+ " 491 | \n",
+ " 1.120000 | \n",
+ " -0.239000 | \n",
+ " 269 | \n",
+ " 224 | \n",
+ " 0.170000 | \n",
+ " 9824 | \n",
+ " -2568 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " True | \n",
+ "
\n",
+ " \n",
+ " 9 | \n",
+ " 2013_03_05 | \n",
+ " I | \n",
+ " 4 | \n",
+ " 1897 | \n",
+ " 41 | \n",
+ " 3.060000 | \n",
+ " -462 | \n",
+ " 839 | \n",
+ " 0.750000 | \n",
+ " -0.328000 | \n",
+ " 266 | \n",
+ " 176 | \n",
+ " 0.340000 | \n",
+ " 7122 | \n",
+ " -1733 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 10 | \n",
+ " 2013_03_12 | \n",
+ " I | \n",
+ " 1 | \n",
+ " 1891 | \n",
+ " 40 | \n",
+ " 3.060000 | \n",
+ " -766 | \n",
+ " 1069 | \n",
+ " 1.240000 | \n",
+ " -0.380000 | \n",
+ " 408 | \n",
+ " 33 | \n",
+ " 0.920000 | \n",
+ " 4638 | \n",
+ " -1879 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 11 | \n",
+ " 2013_03_12 | \n",
+ " I | \n",
+ " 2 | \n",
+ " 1545 | \n",
+ " 48 | \n",
+ " 2.500000 | \n",
+ " -715 | \n",
+ " 649 | \n",
+ " 1.150000 | \n",
+ " -0.298000 | \n",
+ " 141 | \n",
+ " 112 | \n",
+ " 0.210000 | \n",
+ " 10947 | \n",
+ " -5064 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 12 | \n",
+ " 2013_03_12 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 1307 | \n",
+ " 29 | \n",
+ " 2.110000 | \n",
+ " -613 | \n",
+ " 1845 | \n",
+ " 0.990000 | \n",
+ " -0.768000 | \n",
+ " 455 | \n",
+ " 92 | \n",
+ " 0.800000 | \n",
+ " 2874 | \n",
+ " -1348 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 13 | \n",
+ " 2013_03_12 | \n",
+ " I | \n",
+ " 4 | \n",
+ " 1692 | \n",
+ " 31 | \n",
+ " 2.730000 | \n",
+ " -677 | \n",
+ " 917 | \n",
+ " 1.090000 | \n",
+ " -0.457000 | \n",
+ " 186 | \n",
+ " 129 | \n",
+ " 0.310000 | \n",
+ " 9089 | \n",
+ " -3636 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 14 | \n",
+ " 2013_03_12 | \n",
+ " I | \n",
+ " 5 | \n",
+ " 1543 | \n",
+ " 38 | \n",
+ " 2.490000 | \n",
+ " -528 | \n",
+ " 750 | \n",
+ " 0.850000 | \n",
+ " -0.353000 | \n",
+ " 153 | \n",
+ " 148 | \n",
+ " 0.030000 | \n",
+ " 10095 | \n",
+ " -3453 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 15 | \n",
+ " 2013_03_15 | \n",
+ " I | \n",
+ " 1 | \n",
+ " 1282 | \n",
+ " 31 | \n",
+ " 2.070000 | \n",
+ " -452 | \n",
+ " 785 | \n",
+ " 0.730000 | \n",
+ " -0.253000 | \n",
+ " 290 | \n",
+ " 105 | \n",
+ " 0.640000 | \n",
+ " 4419 | \n",
+ " -1557 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 16 | \n",
+ " 2013_03_15 | \n",
+ " I | \n",
+ " 2 | \n",
+ " 775 | \n",
+ " 34 | \n",
+ " 1.250000 | \n",
+ " -430 | \n",
+ " 837 | \n",
+ " 0.700000 | \n",
+ " -0.276000 | \n",
+ " 257 | \n",
+ " 124 | \n",
+ " 0.520000 | \n",
+ " 3019 | \n",
+ " -1677 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 17 | \n",
+ " 2013_03_15 | \n",
+ " I | \n",
+ " 3 | \n",
+ " 2032 | \n",
+ " 60 | \n",
+ " 3.280000 | \n",
+ " -652 | \n",
+ " 486 | \n",
+ " 1.050000 | \n",
+ " -0.257000 | \n",
+ " 147 | \n",
+ " 134 | \n",
+ " 0.090000 | \n",
+ " 13784 | \n",
+ " -4425 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 18 | \n",
+ " 2013_03_15 | \n",
+ " I | \n",
+ " 4 | \n",
+ " 1240 | \n",
+ " 34 | \n",
+ " 2.000000 | \n",
+ " -692 | \n",
+ " 906 | \n",
+ " 1.120000 | \n",
+ " -0.317000 | \n",
+ " 364 | \n",
+ " 260 | \n",
+ " 0.280000 | \n",
+ " 3406 | \n",
+ " -1901 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 19 | \n",
+ " 2013_03_15 | \n",
+ " I | \n",
+ " 5 | \n",
+ " 473 | \n",
+ " 40 | \n",
+ " 0.760000 | \n",
+ " -536 | \n",
+ " 1218 | \n",
+ " 0.870000 | \n",
+ " -0.382000 | \n",
+ " 259 | \n",
+ " 168 | \n",
+ " 0.350000 | \n",
+ " 1830 | \n",
+ " -2073 | \n",
+ " adult | \n",
+ " 63 | \n",
+ " 63.100000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 20 | \n",
+ " 2013_03_19 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 1612 | \n",
+ " 18 | \n",
+ " 3.790000 | \n",
+ " -655 | \n",
+ " 3087 | \n",
+ " 1.540000 | \n",
+ " -0.385000 | \n",
+ " 348 | \n",
+ " 15 | \n",
+ " 0.960000 | \n",
+ " 4633 | \n",
+ " -1881 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " True | \n",
+ "
\n",
+ " \n",
+ " 21 | \n",
+ " 2013_03_19 | \n",
+ " II | \n",
+ " 2 | \n",
+ " 605 | \n",
+ " 55 | \n",
+ " 1.420000 | \n",
+ " -292 | \n",
+ " 1261 | \n",
+ " 0.690000 | \n",
+ " -0.294000 | \n",
+ " 248 | \n",
+ " 24 | \n",
+ " 0.900000 | \n",
+ " 2441 | \n",
+ " -1177 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 22 | \n",
+ " 2013_03_19 | \n",
+ " II | \n",
+ " 3 | \n",
+ " 327 | \n",
+ " 51 | \n",
+ " 0.770000 | \n",
+ " -246 | \n",
+ " 1508 | \n",
+ " 0.580000 | \n",
+ " -0.282000 | \n",
+ " 130 | \n",
+ " 34 | \n",
+ " 0.740000 | \n",
+ " 2517 | \n",
+ " -1894 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 23 | \n",
+ " 2013_03_19 | \n",
+ " II | \n",
+ " 4 | \n",
+ " 946 | \n",
+ " 59 | \n",
+ " 2.230000 | \n",
+ " -245 | \n",
+ " 1841 | \n",
+ " 0.580000 | \n",
+ " -0.340000 | \n",
+ " 106 | \n",
+ " 26 | \n",
+ " 0.760000 | \n",
+ " 8893 | \n",
+ " -2301 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 24 | \n",
+ " 2013_03_21 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 541 | \n",
+ " 33 | \n",
+ " 1.270000 | \n",
+ " -553 | \n",
+ " 3126 | \n",
+ " 1.300000 | \n",
+ " -0.432000 | \n",
+ " 276 | \n",
+ " 16 | \n",
+ " 0.940000 | \n",
+ " 1959 | \n",
+ " -2004 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 25 | \n",
+ " 2013_03_21 | \n",
+ " II | \n",
+ " 2 | \n",
+ " 1539 | \n",
+ " 43 | \n",
+ " 3.620000 | \n",
+ " -664 | \n",
+ " 741 | \n",
+ " 1.560000 | \n",
+ " -0.046000 | \n",
+ " 85 | \n",
+ " 24 | \n",
+ " 0.720000 | \n",
+ " 18073 | \n",
+ " -7802 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 26 | \n",
+ " 2013_03_21 | \n",
+ " II | \n",
+ " 3 | \n",
+ " 529 | \n",
+ " 28 | \n",
+ " 1.240000 | \n",
+ " -261 | \n",
+ " 2482 | \n",
+ " 0.610000 | \n",
+ " -0.414000 | \n",
+ " 325 | \n",
+ " 33 | \n",
+ " 0.900000 | \n",
+ " 1627 | \n",
+ " -803 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 27 | \n",
+ " 2013_03_21 | \n",
+ " II | \n",
+ " 4 | \n",
+ " 628 | \n",
+ " 31 | \n",
+ " 1.480000 | \n",
+ " -691 | \n",
+ " 998 | \n",
+ " 1.630000 | \n",
+ " -0.071000 | \n",
+ " 242 | \n",
+ " 67 | \n",
+ " 0.720000 | \n",
+ " 2600 | \n",
+ " -2860 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 28 | \n",
+ " 2013_03_25 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 1453 | \n",
+ " 72 | \n",
+ " 3.420000 | \n",
+ " -92 | \n",
+ " 1652 | \n",
+ " 0.220000 | \n",
+ " -0.008000 | \n",
+ " 136 | \n",
+ " 0 | \n",
+ " 1.000000 | \n",
+ " 10645 | \n",
+ " -678 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 29 | \n",
+ " 2013_03_25 | \n",
+ " II | \n",
+ " 2 | \n",
+ " 297 | \n",
+ " 42 | \n",
+ " 0.700000 | \n",
+ " -566 | \n",
+ " 936 | \n",
+ " 1.330000 | \n",
+ " -0.084000 | \n",
+ " 126 | \n",
+ " 4 | \n",
+ " 0.970000 | \n",
+ " 2367 | \n",
+ " -4506 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 30 | \n",
+ " 2013_03_25 | \n",
+ " II | \n",
+ " 3 | \n",
+ " 703 | \n",
+ " 33 | \n",
+ " 1.650000 | \n",
+ " -223 | \n",
+ " 2152 | \n",
+ " 0.520000 | \n",
+ " -0.209000 | \n",
+ " 237 | \n",
+ " 8 | \n",
+ " 0.970000 | \n",
+ " 2972 | \n",
+ " -942 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 31 | \n",
+ " 2013_03_25 | \n",
+ " II | \n",
+ " 4 | \n",
+ " 269 | \n",
+ " 57 | \n",
+ " 0.630000 | \n",
+ " -512 | \n",
+ " 189 | \n",
+ " 1.200000 | \n",
+ " -0.055000 | \n",
+ " 29 | \n",
+ " 28 | \n",
+ " 0.030000 | \n",
+ " 9279 | \n",
+ " -17652 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 32 | \n",
+ " 2013_03_28 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 751 | \n",
+ " 39 | \n",
+ " 1.770000 | \n",
+ " -227 | \n",
+ " 1195 | \n",
+ " 0.530000 | \n",
+ " -0.026000 | \n",
+ " 206 | \n",
+ " 0 | \n",
+ " 1.000000 | \n",
+ " 3647 | \n",
+ " -1101 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 33 | \n",
+ " 2013_03_28 | \n",
+ " II | \n",
+ " 2 | \n",
+ " 245 | \n",
+ " 21 | \n",
+ " 0.580000 | \n",
+ " -573 | \n",
+ " 1466 | \n",
+ " 1.350000 | \n",
+ " -0.215000 | \n",
+ " 190 | \n",
+ " 46 | \n",
+ " 0.760000 | \n",
+ " 1288 | \n",
+ " -3014 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 34 | \n",
+ " 2013_04_03 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 1182 | \n",
+ " 28 | \n",
+ " 2.780000 | \n",
+ " -522 | \n",
+ " 1197 | \n",
+ " 1.230000 | \n",
+ " -0.118000 | \n",
+ " 281 | \n",
+ " 0 | \n",
+ " 1.000000 | \n",
+ " 4213 | \n",
+ " -1860 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 35 | \n",
+ " 2013_04_03 | \n",
+ " II | \n",
+ " 2 | \n",
+ " 515 | \n",
+ " 29 | \n",
+ " 1.210000 | \n",
+ " -599 | \n",
+ " 1486 | \n",
+ " 1.410000 | \n",
+ " -0.226000 | \n",
+ " 217 | \n",
+ " 0 | \n",
+ " 1.000000 | \n",
+ " 2369 | \n",
+ " -2757 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 36 | \n",
+ " 2013_04_08 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 435 | \n",
+ " 26 | \n",
+ " 1.020000 | \n",
+ " -364 | \n",
+ " 1017 | \n",
+ " 0.860000 | \n",
+ " -0.211000 | \n",
+ " 189 | \n",
+ " 89 | \n",
+ " 0.530000 | \n",
+ " 2302 | \n",
+ " -1927 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 37 | \n",
+ " 2013_04_08 | \n",
+ " II | \n",
+ " 2 | \n",
+ " 383 | \n",
+ " 31 | \n",
+ " 0.900000 | \n",
+ " -469 | \n",
+ " 974 | \n",
+ " 1.100000 | \n",
+ " -0.260000 | \n",
+ " 221 | \n",
+ " 72 | \n",
+ " 0.670000 | \n",
+ " 1737 | \n",
+ " -2129 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 38 | \n",
+ " 2013_04_08 | \n",
+ " II | \n",
+ " 3 | \n",
+ " 457 | \n",
+ " 15 | \n",
+ " 1.080000 | \n",
+ " -844 | \n",
+ " 780 | \n",
+ " 1.990000 | \n",
+ " -0.328000 | \n",
+ " 171 | \n",
+ " 106 | \n",
+ " 0.380000 | \n",
+ " 2665 | \n",
+ " -4925 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 39 | \n",
+ " 2013_04_12 | \n",
+ " II | \n",
+ " 1 | \n",
+ " 730 | \n",
+ " 42 | \n",
+ " 1.720000 | \n",
+ " -648 | \n",
+ " 786 | \n",
+ " 1.520000 | \n",
+ " -0.121000 | \n",
+ " 142 | \n",
+ " 43 | \n",
+ " 0.700000 | \n",
+ " 5149 | \n",
+ " -4573 | \n",
+ " adult | \n",
+ " 70 | \n",
+ " 72.700000 | \n",
+ " cross | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 40 | \n",
+ " 2013_05_27 | \n",
+ " III | \n",
+ " 1 | \n",
+ " 614 | \n",
+ " 88 | \n",
+ " 4.940000 | \n",
+ " -94 | \n",
+ " 683 | \n",
+ " 0.760000 | \n",
+ " -0.001000 | \n",
+ " 97 | \n",
+ " 15 | \n",
+ " 0.830000 | \n",
+ " 6326 | \n",
+ " -967 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 41 | \n",
+ " 2013_05_27 | \n",
+ " III | \n",
+ " 2 | \n",
+ " 414 | \n",
+ " 143 | \n",
+ " 3.330000 | \n",
+ " -163 | \n",
+ " 245 | \n",
+ " 1.310000 | \n",
+ " -0.032000 | \n",
+ " 108 | \n",
+ " 10 | \n",
+ " 0.600000 | \n",
+ " 3824 | \n",
+ " -1507 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 42 | \n",
+ " 2013_05_27 | \n",
+ " III | \n",
+ " 3 | \n",
+ " 324 | \n",
+ " 105 | \n",
+ " 2.610000 | \n",
+ " -172 | \n",
+ " 619 | \n",
+ " 1.380000 | \n",
+ " -0.079000 | \n",
+ " 55 | \n",
+ " 23 | \n",
+ " 0.370000 | \n",
+ " 5946 | \n",
+ " -3149 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 43 | \n",
+ " 2013_06_11 | \n",
+ " III | \n",
+ " 1 | \n",
+ " 776 | \n",
+ " 35 | \n",
+ " 6.240000 | \n",
+ " -225 | \n",
+ " 1823 | \n",
+ " 1.810000 | \n",
+ " -0.132000 | \n",
+ " 124 | \n",
+ " 17 | \n",
+ " 0.770000 | \n",
+ " 6272 | \n",
+ " -1818 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 44 | \n",
+ " 2013_06_11 | \n",
+ " III | \n",
+ " 2 | \n",
+ " 611 | \n",
+ " 29 | \n",
+ " 4.910000 | \n",
+ " -301 | \n",
+ " 918 | \n",
+ " 2.420000 | \n",
+ " -0.155000 | \n",
+ " 128 | \n",
+ " 43 | \n",
+ " 0.020000 | \n",
+ " 4770 | \n",
+ " -2354 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 45 | \n",
+ " 2013_06_11 | \n",
+ " III | \n",
+ " 3 | \n",
+ " 544 | \n",
+ " 16 | \n",
+ " 4.380000 | \n",
+ " -93 | \n",
+ " 1351 | \n",
+ " 0.750000 | \n",
+ " -0.110000 | \n",
+ " 43 | \n",
+ " 34 | \n",
+ " 0.710000 | \n",
+ " 12699 | \n",
+ " -2181 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 46 | \n",
+ " 2013_06_14 | \n",
+ " III | \n",
+ " 1 | \n",
+ " 538 | \n",
+ " 38 | \n",
+ " 4.320000 | \n",
+ " -131 | \n",
+ " 1790 | \n",
+ " 1.050000 | \n",
+ " -0.036000 | \n",
+ " 130 | \n",
+ " 74 | \n",
+ " 1.000000 | \n",
+ " 4130 | \n",
+ " -1005 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 47 | \n",
+ " 2013_06_14 | \n",
+ " III | \n",
+ " 2 | \n",
+ " 579 | \n",
+ " 31 | \n",
+ " 4.660000 | \n",
+ " -289 | \n",
+ " 1006 | \n",
+ " 2.330000 | \n",
+ " -0.073000 | \n",
+ " 113 | \n",
+ " 4 | \n",
+ " 0.480000 | \n",
+ " 5110 | \n",
+ " -2555 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 48 | \n",
+ " 2013_06_18 | \n",
+ " III | \n",
+ " 1 | \n",
+ " 806 | \n",
+ " 29 | \n",
+ " 6.490000 | \n",
+ " -104 | \n",
+ " 883 | \n",
+ " 0.840000 | \n",
+ " -0.055000 | \n",
+ " 115 | \n",
+ " 55 | \n",
+ " 0.660000 | \n",
+ " 6993 | \n",
+ " -902 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " True | \n",
+ "
\n",
+ " \n",
+ " 49 | \n",
+ " 2013_06_18 | \n",
+ " III | \n",
+ " 2 | \n",
+ " 459 | \n",
+ " 32 | \n",
+ " 3.700000 | \n",
+ " -229 | \n",
+ " 1218 | \n",
+ " 1.850000 | \n",
+ " -0.137000 | \n",
+ " 89 | \n",
+ " 6 | \n",
+ " 0.950000 | \n",
+ " 5165 | \n",
+ " -2580 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 50 | \n",
+ " 2013_06_18 | \n",
+ " III | \n",
+ " 3 | \n",
+ " 458 | \n",
+ " 30 | \n",
+ " 3.690000 | \n",
+ " -259 | \n",
+ " 910 | \n",
+ " 2.080000 | \n",
+ " -0.194000 | \n",
+ " 91 | \n",
+ " 88 | \n",
+ " 0.150000 | \n",
+ " 5048 | \n",
+ " -2855 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 51 | \n",
+ " 2013_06_18 | \n",
+ " III | \n",
+ " 4 | \n",
+ " 626 | \n",
+ " 16 | \n",
+ " 5.040000 | \n",
+ " -231 | \n",
+ " 550 | \n",
+ " 1.860000 | \n",
+ " -0.042000 | \n",
+ " 82 | \n",
+ " 23 | \n",
+ " 0.010000 | \n",
+ " 7633 | \n",
+ " -2819 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 52 | \n",
+ " 2013_06_21 | \n",
+ " III | \n",
+ " 1 | \n",
+ " 621 | \n",
+ " 27 | \n",
+ " 4.990000 | \n",
+ " -267 | \n",
+ " 2081 | \n",
+ " 2.140000 | \n",
+ " -0.183000 | \n",
+ " 120 | \n",
+ " 58 | \n",
+ " 0.900000 | \n",
+ " 5152 | \n",
+ " -2213 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 53 | \n",
+ " 2013_06_21 | \n",
+ " III | \n",
+ " 2 | \n",
+ " 544 | \n",
+ " 30 | \n",
+ " 4.380000 | \n",
+ " -178 | \n",
+ " 376 | \n",
+ " 1.430000 | \n",
+ " -0.034000 | \n",
+ " 19 | \n",
+ " 17 | \n",
+ " 0.050000 | \n",
+ " 28641 | \n",
+ " -9364 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 54 | \n",
+ " 2013_06_21 | \n",
+ " III | \n",
+ " 3 | \n",
+ " 535 | \n",
+ " 35 | \n",
+ " 4.300000 | \n",
+ " -123 | \n",
+ " 289 | \n",
+ " 0.990000 | \n",
+ " -0.029000 | \n",
+ " 21 | \n",
+ " 29 | \n",
+ " 0.050000 | \n",
+ " 25471 | \n",
+ " -5843 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 55 | \n",
+ " 2013_06_21 | \n",
+ " III | \n",
+ " 4 | \n",
+ " 385 | \n",
+ " 39 | \n",
+ " 3.090000 | \n",
+ " -151 | \n",
+ " 607 | \n",
+ " 1.220000 | \n",
+ " -0.082000 | \n",
+ " 31 | \n",
+ " 126 | \n",
+ " 0.030000 | \n",
+ " 12409 | \n",
+ " -4882 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 56 | \n",
+ " 2013_06_26 | \n",
+ " III | \n",
+ " 1 | \n",
+ " 401 | \n",
+ " 36 | \n",
+ " 3.230000 | \n",
+ " -127 | \n",
+ " 2932 | \n",
+ " 1.020000 | \n",
+ " -0.215000 | \n",
+ " 142 | \n",
+ " 12 | \n",
+ " 0.860000 | \n",
+ " 2835 | \n",
+ " -896 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 57 | \n",
+ " 2013_06_26 | \n",
+ " III | \n",
+ " 2 | \n",
+ " 614 | \n",
+ " 34 | \n",
+ " 4.940000 | \n",
+ " -372 | \n",
+ " 680 | \n",
+ " 2.990000 | \n",
+ " -0.140000 | \n",
+ " 72 | \n",
+ " 1 | \n",
+ " 0.420000 | \n",
+ " 8475 | \n",
+ " -5136 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 58 | \n",
+ " 2013_06_26 | \n",
+ " III | \n",
+ " 3 | \n",
+ " 665 | \n",
+ " 40 | \n",
+ " 5.350000 | \n",
+ " -236 | \n",
+ " 685 | \n",
+ " 1.900000 | \n",
+ " -0.118000 | \n",
+ " 129 | \n",
+ " 0 | \n",
+ " 0.160000 | \n",
+ " 5171 | \n",
+ " -1834 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 59 | \n",
+ " 2013_06_26 | \n",
+ " III | \n",
+ " 4 | \n",
+ " 488 | \n",
+ " 34 | \n",
+ " 3.930000 | \n",
+ " -390 | \n",
+ " 1308 | \n",
+ " 3.140000 | \n",
+ " -0.208000 | \n",
+ " 112 | \n",
+ " 58 | \n",
+ " 0.390000 | \n",
+ " 4376 | \n",
+ " -3492 | \n",
+ " juvenile | \n",
+ " 28 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 60 | \n",
+ " 2013_05_27 | \n",
+ " IV | \n",
+ " 2 | \n",
+ " 172 | \n",
+ " 26 | \n",
+ " 1.280000 | \n",
+ " -456 | \n",
+ " 462 | \n",
+ " 3.400000 | \n",
+ " -0.050000 | \n",
+ " 133 | \n",
+ " 0 | \n",
+ " 0.880000 | \n",
+ " 1297 | \n",
+ " -3440 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 61 | \n",
+ " 2013_05_27 | \n",
+ " IV | \n",
+ " 3 | \n",
+ " 142 | \n",
+ " 20 | \n",
+ " 1.050000 | \n",
+ " -193 | \n",
+ " 250 | \n",
+ " 1.440000 | \n",
+ " -0.047000 | \n",
+ " 57 | \n",
+ " 74 | \n",
+ " 0.830000 | \n",
+ " 2498 | \n",
+ " -3400 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 62 | \n",
+ " 2013_05_27 | \n",
+ " IV | \n",
+ " 4 | \n",
+ " 37 | \n",
+ " 55 | \n",
+ " 0.280000 | \n",
+ " -236 | \n",
+ " 743 | \n",
+ " 1.760000 | \n",
+ " -0.119000 | \n",
+ " 51 | \n",
+ " 44 | \n",
+ " 0.540000 | \n",
+ " 735 | \n",
+ " -4647 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 63 | \n",
+ " 2013_05_30 | \n",
+ " IV | \n",
+ " 1 | \n",
+ " 453 | \n",
+ " 38 | \n",
+ " 3.370000 | \n",
+ " -225 | \n",
+ " 844 | \n",
+ " 1.680000 | \n",
+ " -0.110000 | \n",
+ " 142 | \n",
+ " 108 | \n",
+ " 0.480000 | \n",
+ " 3177 | \n",
+ " -1581 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 64 | \n",
+ " 2013_05_30 | \n",
+ " IV | \n",
+ " 2 | \n",
+ " 355 | \n",
+ " 31 | \n",
+ " 2.640000 | \n",
+ " -217 | \n",
+ " 728 | \n",
+ " 1.610000 | \n",
+ " -0.023000 | \n",
+ " 174 | \n",
+ " 39 | \n",
+ " 0.980000 | \n",
+ " 2037 | \n",
+ " -1245 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 65 | \n",
+ " 2013_05_30 | \n",
+ " IV | \n",
+ " 3 | \n",
+ " 22 | \n",
+ " 33 | \n",
+ " 0.170000 | \n",
+ " -161 | \n",
+ " 472 | \n",
+ " 1.200000 | \n",
+ " -0.052000 | \n",
+ " 56 | \n",
+ " 4 | \n",
+ " 0.020000 | \n",
+ " 397 | \n",
+ " -2866 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 66 | \n",
+ " 2013_06_03 | \n",
+ " IV | \n",
+ " 1 | \n",
+ " 502 | \n",
+ " 74 | \n",
+ " 3.740000 | \n",
+ " -139 | \n",
+ " 959 | \n",
+ " 1.040000 | \n",
+ " -0.089000 | \n",
+ " 65 | \n",
+ " 77 | \n",
+ " 0.910000 | \n",
+ " 7713 | \n",
+ " -2141 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 67 | \n",
+ " 2013_06_11 | \n",
+ " IV | \n",
+ " 1 | \n",
+ " 273 | \n",
+ " 26 | \n",
+ " 2.030000 | \n",
+ " -264 | \n",
+ " 844 | \n",
+ " 1.970000 | \n",
+ " -0.160000 | \n",
+ " 124 | \n",
+ " 81 | \n",
+ " 0.290000 | \n",
+ " 2205 | \n",
+ " -2136 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 68 | \n",
+ " 2013_06_11 | \n",
+ " IV | \n",
+ " 2 | \n",
+ " 720 | \n",
+ " 27 | \n",
+ " 5.360000 | \n",
+ " -342 | \n",
+ " 1515 | \n",
+ " 2.550000 | \n",
+ " -0.226000 | \n",
+ " 137 | \n",
+ " 0 | \n",
+ " 0.830000 | \n",
+ " 5259 | \n",
+ " -2497 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 69 | \n",
+ " 2013_06_11 | \n",
+ " IV | \n",
+ " 3 | \n",
+ " 582 | \n",
+ " 33 | \n",
+ " 4.340000 | \n",
+ " -231 | \n",
+ " 279 | \n",
+ " 1.720000 | \n",
+ " -0.033000 | \n",
+ " 60 | \n",
+ " 4 | \n",
+ " 0.030000 | \n",
+ " 9705 | \n",
+ " -3847 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 70 | \n",
+ " 2013_06_11 | \n",
+ " IV | \n",
+ " 4 | \n",
+ " 198 | \n",
+ " 23 | \n",
+ " 1.470000 | \n",
+ " -209 | \n",
+ " 1427 | \n",
+ " 1.550000 | \n",
+ " -0.151000 | \n",
+ " 110 | \n",
+ " 69 | \n",
+ " 0.840000 | \n",
+ " 1793 | \n",
+ " -1889 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 71 | \n",
+ " 2013_06_14 | \n",
+ " IV | \n",
+ " 1 | \n",
+ " 198 | \n",
+ " 6 | \n",
+ " 1.470000 | \n",
+ " -292 | \n",
+ " 2874 | \n",
+ " 2.170000 | \n",
+ " -0.232000 | \n",
+ " 145 | \n",
+ " 50 | \n",
+ " 0.990000 | \n",
+ " 1369 | \n",
+ " -2018 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 72 | \n",
+ " 2013_06_18 | \n",
+ " IV | \n",
+ " 1 | \n",
+ " 597 | \n",
+ " 29 | \n",
+ " 4.440000 | \n",
+ " -339 | \n",
+ " 4251 | \n",
+ " 2.530000 | \n",
+ " -0.281000 | \n",
+ " 191 | \n",
+ " 12 | \n",
+ " 1.000000 | \n",
+ " 3116 | \n",
+ " -1772 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 73 | \n",
+ " 2013_06_18 | \n",
+ " IV | \n",
+ " 2 | \n",
+ " 516 | \n",
+ " 31 | \n",
+ " 3.840000 | \n",
+ " -371 | \n",
+ " 626 | \n",
+ " 2.760000 | \n",
+ " -0.094000 | \n",
+ " 83 | \n",
+ " 18 | \n",
+ " 0.120000 | \n",
+ " 6184 | \n",
+ " -4447 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 74 | \n",
+ " 2013_06_18 | \n",
+ " IV | \n",
+ " 3 | \n",
+ " 815 | \n",
+ " 34 | \n",
+ " 6.070000 | \n",
+ " -331 | \n",
+ " 1254 | \n",
+ " 2.470000 | \n",
+ " -0.077000 | \n",
+ " 151 | \n",
+ " 20 | \n",
+ " 0.710000 | \n",
+ " 5386 | \n",
+ " -2190 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " True | \n",
+ "
\n",
+ " \n",
+ " 75 | \n",
+ " 2013_06_18 | \n",
+ " IV | \n",
+ " 4 | \n",
+ " 402 | \n",
+ " 38 | \n",
+ " 3.000000 | \n",
+ " -302 | \n",
+ " 986 | \n",
+ " 2.250000 | \n",
+ " -0.122000 | \n",
+ " 117 | \n",
+ " 30 | \n",
+ " 0.070000 | \n",
+ " 3446 | \n",
+ " -2591 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 76 | \n",
+ " 2013_06_21 | \n",
+ " IV | \n",
+ " 1 | \n",
+ " 605 | \n",
+ " 39 | \n",
+ " 4.500000 | \n",
+ " -216 | \n",
+ " 1627 | \n",
+ " 1.610000 | \n",
+ " -0.139000 | \n",
+ " 123 | \n",
+ " 20 | \n",
+ " 1.000000 | \n",
+ " 4928 | \n",
+ " -1759 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 77 | \n",
+ " 2013_06_21 | \n",
+ " IV | \n",
+ " 2 | \n",
+ " 711 | \n",
+ " 76 | \n",
+ " 5.300000 | \n",
+ " -163 | \n",
+ " 2021 | \n",
+ " 1.210000 | \n",
+ " -0.217000 | \n",
+ " 129 | \n",
+ " 42 | \n",
+ " 0.970000 | \n",
+ " 5498 | \n",
+ " -1257 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 78 | \n",
+ " 2013_06_21 | \n",
+ " IV | \n",
+ " 3 | \n",
+ " 614 | \n",
+ " 33 | \n",
+ " 4.570000 | \n",
+ " -367 | \n",
+ " 1366 | \n",
+ " 2.730000 | \n",
+ " -0.198000 | \n",
+ " 128 | \n",
+ " 108 | \n",
+ " 0.460000 | \n",
+ " 4776 | \n",
+ " -2857 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ " 79 | \n",
+ " 2013_06_21 | \n",
+ " IV | \n",
+ " 4 | \n",
+ " 468 | \n",
+ " 36 | \n",
+ " 3.480000 | \n",
+ " -218 | \n",
+ " 1269 | \n",
+ " 1.630000 | \n",
+ " -0.122000 | \n",
+ " 129 | \n",
+ " 68 | \n",
+ " 0.610000 | \n",
+ " 3617 | \n",
+ " -1688 | \n",
+ " juvenile | \n",
+ " 31 | \n",
+ " 12.700000 | \n",
+ " cranwelli | \n",
+ " False | \n",
+ "
\n",
+ " \n",
+ "
\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
@@ -221,11 +222,11 @@ Solution
Exercise 2 solutions
+Exercise 3 solutions
Schedule
@@ -253,11 +254,11 @@ Solution
Exercise 2 solutions
+Exercise 3 solutions
Schedule
@@ -267,11 +268,11 @@ Computing environment
Exercise 2 solutions
+Exercise 3 solutions
Schedule
@@ -339,11 +340,11 @@ Computing environment
Exercise 2 solutions
+Exercise 3 solutions
Schedule
@@ -343,11 +344,11 @@ Computing environment
Exercise 2 solutions
+Exercise 3 solutions
Schedule
@@ -526,11 +527,11 @@ Computing environment
Exercise 2 solutions
+Exercise 3 solutions
Schedule
@@ -203,11 +204,11 @@ Exercise 1 solutions
+Exercise 3 solutions
Schedule
@@ -335,11 +336,11 @@ Computing environment
+Exercise 3 solutions
Schedule
@@ -406,11 +407,11 @@ Computing environment
+Exercise 3 solutions
Schedule
@@ -705,11 +706,11 @@ Computing environment
+Exercise 3 solutions
Schedule
@@ -813,18 +814,18 @@ Computing environment
+Exercise 3 solutions
Schedule
@@ -199,11 +200,11 @@ Exercise 2 solutions