{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "s-_LXMfxPYNn"
   },
   "source": [
    "# Scales, Axes, and Legends\n",
    "\n",
    "Visual encoding &ndash; mapping data to visual variables such as position, size, shape, or color &ndash; is the beating heart of data visualization. The workhorse that actually performs this mapping is the *scale*: a function that takes a data value as input (the scale *domain*) and returns a visual value, such as a pixel position or RGB color, as output (the scale *range*).  Of course, a visualization is useless if no one can figure out what it conveys! In addition to graphical marks, a chart needs reference elements, or *guides*, that allow readers to decode the graphic. Guides such as *axes* (which visualize scales with spatial ranges) and *legends* (which visualize scales with color, size, or shape ranges), are the unsung heroes of effective data visualization!\n",
    "\n",
    "In this notebook, we will explore the options Altair provides to support customized designs of scale mappings, axes, and legends, using a running example about the effectiveness of antibiotic drugs.\n",
    "\n",
    "_This notebook is part of the [data visualization curriculum](https://github.com/uwdata/visualization-curriculum)._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "9-iDk57UO3ij"
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import altair as alt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "2bgy9xz4J2vb"
   },
   "source": [
    "## Antibiotics Data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "cXYJkW_p6zGN"
   },
   "source": [
    "After World War II, antibiotics were considered \"wonder drugs\", as they were an easy remedy for what had been intractable ailments. To learn which drug worked most effectively for which bacterial infection, performance of the three most popular antibiotics on 16 bacteria were gathered."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "YRXEnlzG8Cpt"
   },
   "source": [
    "We will be using an antibiotics dataset from the [vega-datasets collection](https://github.com/vega/vega-datasets). In the examples below, we will pass the URL directly to Altair:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "jbtcg3fmJ5_A"
   },
   "outputs": [],
   "source": [
    "antibiotics = 'https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "MGHC8Fft8L2E"
   },
   "source": [
    "We can first load the data with Pandas to view the dataset in its entirety and get acquainted with the available fields:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 545
    },
    "colab_type": "code",
    "id": "WoMzr0HE6ipZ",
    "outputId": "fa9edadf-8744-4514-d8ba-5401b7f66bed"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Bacteria</th>\n",
       "      <th>Penicillin</th>\n",
       "      <th>Streptomycin</th>\n",
       "      <th>Neomycin</th>\n",
       "      <th>Gram_Staining</th>\n",
       "      <th>Genus</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Aerobacter aerogenes</td>\n",
       "      <td>870.000</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.600</td>\n",
       "      <td>negative</td>\n",
       "      <td>other</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Bacillus anthracis</td>\n",
       "      <td>0.001</td>\n",
       "      <td>0.01</td>\n",
       "      <td>0.007</td>\n",
       "      <td>positive</td>\n",
       "      <td>other</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Brucella abortus</td>\n",
       "      <td>1.000</td>\n",
       "      <td>2.00</td>\n",
       "      <td>0.020</td>\n",
       "      <td>negative</td>\n",
       "      <td>other</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Diplococcus pneumoniae</td>\n",
       "      <td>0.005</td>\n",
       "      <td>11.00</td>\n",
       "      <td>10.000</td>\n",
       "      <td>positive</td>\n",
       "      <td>other</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Escherichia coli</td>\n",
       "      <td>100.000</td>\n",
       "      <td>0.40</td>\n",
       "      <td>0.100</td>\n",
       "      <td>negative</td>\n",
       "      <td>other</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Klebsiella pneumoniae</td>\n",
       "      <td>850.000</td>\n",
       "      <td>1.20</td>\n",
       "      <td>1.000</td>\n",
       "      <td>negative</td>\n",
       "      <td>other</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Mycobacterium tuberculosis</td>\n",
       "      <td>800.000</td>\n",
       "      <td>5.00</td>\n",
       "      <td>2.000</td>\n",
       "      <td>negative</td>\n",
       "      <td>other</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Proteus vulgaris</td>\n",
       "      <td>3.000</td>\n",
       "      <td>0.10</td>\n",
       "      <td>0.100</td>\n",
       "      <td>negative</td>\n",
       "      <td>other</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Pseudomonas aeruginosa</td>\n",
       "      <td>850.000</td>\n",
       "      <td>2.00</td>\n",
       "      <td>0.400</td>\n",
       "      <td>negative</td>\n",
       "      <td>other</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>Salmonella (Eberthella) typhosa</td>\n",
       "      <td>1.000</td>\n",
       "      <td>0.40</td>\n",
       "      <td>0.008</td>\n",
       "      <td>negative</td>\n",
       "      <td>Salmonella</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>Salmonella schottmuelleri</td>\n",
       "      <td>10.000</td>\n",
       "      <td>0.80</td>\n",
       "      <td>0.090</td>\n",
       "      <td>negative</td>\n",
       "      <td>Salmonella</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>Staphylococcus albus</td>\n",
       "      <td>0.007</td>\n",
       "      <td>0.10</td>\n",
       "      <td>0.001</td>\n",
       "      <td>positive</td>\n",
       "      <td>Staphylococcus</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>Staphylococcus aureus</td>\n",
       "      <td>0.030</td>\n",
       "      <td>0.03</td>\n",
       "      <td>0.001</td>\n",
       "      <td>positive</td>\n",
       "      <td>Staphylococcus</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>Streptococcus fecalis</td>\n",
       "      <td>1.000</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.100</td>\n",
       "      <td>positive</td>\n",
       "      <td>Streptococcus</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>Streptococcus hemolyticus</td>\n",
       "      <td>0.001</td>\n",
       "      <td>14.00</td>\n",
       "      <td>10.000</td>\n",
       "      <td>positive</td>\n",
       "      <td>Streptococcus</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>Streptococcus viridans</td>\n",
       "      <td>0.005</td>\n",
       "      <td>10.00</td>\n",
       "      <td>40.000</td>\n",
       "      <td>positive</td>\n",
       "      <td>Streptococcus</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                           Bacteria  Penicillin  Streptomycin  Neomycin  \\\n",
       "0              Aerobacter aerogenes     870.000          1.00     1.600   \n",
       "1                Bacillus anthracis       0.001          0.01     0.007   \n",
       "2                  Brucella abortus       1.000          2.00     0.020   \n",
       "3            Diplococcus pneumoniae       0.005         11.00    10.000   \n",
       "4                  Escherichia coli     100.000          0.40     0.100   \n",
       "5             Klebsiella pneumoniae     850.000          1.20     1.000   \n",
       "6        Mycobacterium tuberculosis     800.000          5.00     2.000   \n",
       "7                  Proteus vulgaris       3.000          0.10     0.100   \n",
       "8            Pseudomonas aeruginosa     850.000          2.00     0.400   \n",
       "9   Salmonella (Eberthella) typhosa       1.000          0.40     0.008   \n",
       "10        Salmonella schottmuelleri      10.000          0.80     0.090   \n",
       "11             Staphylococcus albus       0.007          0.10     0.001   \n",
       "12            Staphylococcus aureus       0.030          0.03     0.001   \n",
       "13            Streptococcus fecalis       1.000          1.00     0.100   \n",
       "14        Streptococcus hemolyticus       0.001         14.00    10.000   \n",
       "15           Streptococcus viridans       0.005         10.00    40.000   \n",
       "\n",
       "   Gram_Staining           Genus  \n",
       "0       negative           other  \n",
       "1       positive           other  \n",
       "2       negative           other  \n",
       "3       positive           other  \n",
       "4       negative           other  \n",
       "5       negative           other  \n",
       "6       negative           other  \n",
       "7       negative           other  \n",
       "8       negative           other  \n",
       "9       negative      Salmonella  \n",
       "10      negative      Salmonella  \n",
       "11      positive  Staphylococcus  \n",
       "12      positive  Staphylococcus  \n",
       "13      positive   Streptococcus  \n",
       "14      positive   Streptococcus  \n",
       "15      positive   Streptococcus  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.read_json(antibiotics)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "els3ZQOv7K_9"
   },
   "source": [
    "The numeric values in the table indicate the [minimum inhibitory concentration (MIC)](https://en.wikipedia.org/wiki/Minimum_inhibitory_concentration), a measure of the effectiveness of the antibiotic, which represents the concentration of antibiotic (in micrograms per milliliter) required to prevent growth in vitro. The reaction of the bacteria to a procedure called [Gram staining](https://en.wikipedia.org/wiki/Gram_stain) is described by the nominal field `Gram_Staining`. Bacteria that turn dark blue or violet are Gram-positive. Otherwise, they are Gram-negative.\n",
    "\n",
    "As we examine different visualizations of this dataset, ask yourself: What might we learn about the relative effectiveness of the antibiotics? What might we learn about the bacterial species based on their antibiotic response?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "9ZNMXWOzKvRa"
   },
   "source": [
    "## Configuring Scales and Axes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "dawVYXt1WNJz"
   },
   "source": [
    "### Plotting Antibiotic Resistance: Adjusting the Scale Type\n",
    "\n",
    "Let's start by looking at a simple dot plot of the MIC for Neomycin."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 87
    },
    "colab_type": "code",
    "id": "dBOlbuYpKx6L",
    "outputId": "90dfa88f-a287-4d0f-84ee-02f88f2f4701"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-5c71e9eae8884e748bb3059f7fe3f209\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-5c71e9eae8884e748bb3059f7fe3f209\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-5c71e9eae8884e748bb3059f7fe3f209\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"circle\", \"encoding\": {\"x\": {\"type\": \"quantitative\", \"field\": \"Neomycin\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle().encode(\n",
    "    alt.X('Neomycin:Q')\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "eTBRtG7CWVVX"
   },
   "source": [
    "_We can see that the MIC values span orders of magnitude: most points to cluster on the left, with a few large outliers to the right._\n",
    "\n",
    "By default Altair uses a `linear` mapping between the domain values (MIC) and the range values (pixels). To get a better overview of the data, we can apply a different scale transformation."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "-K94jPdi9xUJ"
   },
   "source": [
    "To change the scale type, we'll set the `scale` attribute, using the `alt.Scale` method and `type` parameter.\n",
    "\n",
    "Here's the result of using a square root (`sqrt`) scale type. Distances in the pixel range now correspond to the square root of distances in the data domain."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 87
    },
    "colab_type": "code",
    "id": "QB5YNBMWLewL",
    "outputId": "45edabce-e14c-4e47-ee0e-838d03eaebb9"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-6a309725d1dd4ae5aa0a54dfc9c3d1b0\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-6a309725d1dd4ae5aa0a54dfc9c3d1b0\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-6a309725d1dd4ae5aa0a54dfc9c3d1b0\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"circle\", \"encoding\": {\"x\": {\"type\": \"quantitative\", \"field\": \"Neomycin\", \"scale\": {\"type\": \"sqrt\"}}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle().encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          scale=alt.Scale(type='sqrt'))\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "qqosAiy5XDKJ"
   },
   "source": [
    "_The points on the left are now better differentiated, but we still see some heavy skew._\n",
    "\n",
    "Let's try using a [logarithmic scale](https://en.wikipedia.org/wiki/Logarithmic_scale) (`log`) instead:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 87
    },
    "colab_type": "code",
    "id": "jGlWyOOMLoQ3",
    "outputId": "6e386312-0477-4f04-a845-f4c9f67a4ac0"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-47ed2d3c58c44801a043be4390eeb15d\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-47ed2d3c58c44801a043be4390eeb15d\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-47ed2d3c58c44801a043be4390eeb15d\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"circle\", \"encoding\": {\"x\": {\"type\": \"quantitative\", \"field\": \"Neomycin\", \"scale\": {\"type\": \"log\"}}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle().encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          scale=alt.Scale(type='log'))\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "MapiFW7hXMOG"
   },
   "source": [
    "_Now the data is much more evenly distributed and we can see the very large differences in concentrations required for different bacteria._\n",
    "\n",
    "In a standard linear scale, a visual (pixel) distance of 10 units might correspond to an *addition* of 10 units in the data domain. A logarithmic transform maps between multiplication and addition, such that `log(u) + log(v) = log(u*v)`. As a result, in a logarithmic scale, a visual distance of 10 units instead corresponds to *multiplication* by 10 units in the data domain, assuming a base 10 logarithm. The `log` scale above defaults to using the logarithm base 10, but we can adjust this by providing a `base` parameter to the scale."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "P3u_mJgLeJGt"
   },
   "source": [
    "### Styling an Axis\n",
    "\n",
    "Lower dosages indicate higher effectiveness. However, some people may expect values that are \"better\" to be \"up and to the right\" within a chart. If we want to cater to this convention, we can reverse the axis to encode \"effectiveness\" as a reversed MIC scale.\n",
    "\n",
    "To do this, we can set the encoding `sort` property to `'descending'`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 87
    },
    "colab_type": "code",
    "id": "4gNdIiP7Lu8_",
    "outputId": "d11f184f-9040-444b-b478-5e63cae4102a"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-01836242c5534f8992e2a07c00be4ca8\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-01836242c5534f8992e2a07c00be4ca8\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-01836242c5534f8992e2a07c00be4ca8\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"circle\", \"encoding\": {\"x\": {\"type\": \"quantitative\", \"field\": \"Neomycin\", \"scale\": {\"type\": \"log\"}, \"sort\": \"descending\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle().encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log'))\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "Wp2lmW6SXxcQ"
   },
   "source": [
    "_Unfortunately the axis is starting to get a bit confusing: we're plotting data on a logarithmic scale, in the reverse direction, and without a clear indication of what our units are!_\n",
    "\n",
    "Let's add a more informative axis title: we'll use the `title` property of the encoding to provide the desired title text:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 87
    },
    "colab_type": "code",
    "id": "aP8fcU36L4iB",
    "outputId": "936f1956-ae09-492e-897d-027093205576"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-1deee85760f94a79b1758e79ec61954b\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-1deee85760f94a79b1758e79ec61954b\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-1deee85760f94a79b1758e79ec61954b\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"circle\", \"encoding\": {\"x\": {\"type\": \"quantitative\", \"field\": \"Neomycin\", \"scale\": {\"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle().encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log'),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)')\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "9tpvPMM3YT2H"
   },
   "source": [
    "Much better!\n",
    "\n",
    "By default, Altair places the x-axis along the bottom of the chart. To change these defaults, we can add an `axis` attribute with `orient='top'`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 87
    },
    "colab_type": "code",
    "id": "GMR7Tg4n-Vgu",
    "outputId": "053818a8-0e6c-4a7c-cb15-a0441406096b"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-1c0d0d67c5b847db99b166a1531e991d\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-1c0d0d67c5b847db99b166a1531e991d\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-1c0d0d67c5b847db99b166a1531e991d\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"circle\", \"encoding\": {\"x\": {\"type\": \"quantitative\", \"axis\": {\"orient\": \"top\"}, \"field\": \"Neomycin\", \"scale\": {\"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle().encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log'),\n",
    "          axis=alt.Axis(orient='top'),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)')\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "opQaDD-g-btc"
   },
   "source": [
    "Similarly, the y-axis defaults to a `'left'` orientation, but can be set to `'right'`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "l1WXNzJC9hxi"
   },
   "source": [
    "### Comparing Antibiotics: Adjusting Grid Lines, Tick Counts, and Sizing\n",
    "\n",
    "_How does neomycin compare to other antibiotics, such as streptomycin and penicillin?_\n",
    "\n",
    "To start answering this question, we can create scatter plots, adding a y-axis encoding for another antibiotic that mirrors the design of our x-axis for neomycin."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 372
    },
    "colab_type": "code",
    "id": "CjDce4pG_SXP",
    "outputId": "9459f0fb-088e-4e60-92f3-5f7992b3509d"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-0ebcaa03b1e64abfbff0d9c40fda8373\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-0ebcaa03b1e64abfbff0d9c40fda8373\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-0ebcaa03b1e64abfbff0d9c40fda8373\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"circle\", \"encoding\": {\"x\": {\"type\": \"quantitative\", \"field\": \"Neomycin\", \"scale\": {\"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"field\": \"Streptomycin\", \"scale\": {\"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Streptomycin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle().encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log'),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Streptomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log'),\n",
    "          title='Streptomycin MIC (μg/ml, reverse log scale)')\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "DnfjvOKo_VI2"
   },
   "source": [
    "_We can see that neomycin and streptomycin appear highly correlated, as the bacterial strains respond similarly to both antibiotics._\n",
    "\n",
    "Let's move on and compare neomycin with penicillin:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 372
    },
    "colab_type": "code",
    "id": "hqc6DFgvNHAT",
    "outputId": "6713ba6b-8879-43be-e7ed-4340974b2c20"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-5731c241c1d147279bef907c152e5f49\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-5731c241c1d147279bef907c152e5f49\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-5731c241c1d147279bef907c152e5f49\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"circle\", \"encoding\": {\"x\": {\"type\": \"quantitative\", \"field\": \"Neomycin\", \"scale\": {\"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"field\": \"Penicillin\", \"scale\": {\"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle().encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log'),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log'),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)')\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "fSdm-7VjYjij"
   },
   "source": [
    "_Now we see a more differentiated response: some bacteria respond well to neomycin but not penicillin, and vice versa!_\n",
    "\n",
    "While this plot is useful, we can make it better. The x and y axes use the same units, but have different extents (the chart width is larger than the height) and different domains (0.001 to 100 for the x-axis, and 0.001 to 1,000 for the y-axis).\n",
    "\n",
    "Let's equalize the axes: we can add explicit `width` and `height` settings for the chart, and specify matching domains  using the scale `domain` property."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "8HdsAzWBNVoB",
    "outputId": "2701bbff-a789-4eb0-f6bd-3f66565be916"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-5a09ab46c03d47de909aa9a469c4cfd4\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-5a09ab46c03d47de909aa9a469c4cfd4\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-5a09ab46c03d47de909aa9a469c4cfd4\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"circle\", \"encoding\": {\"x\": {\"type\": \"quantitative\", \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle().encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)')\n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "oknzZZ-lZYaH"
   },
   "source": [
    "_The resulting plot is more balanced, and less prone to subtle misinterpretations!_\n",
    "\n",
    "However, the grid lines are now rather dense. If we want to remove grid lines altogether, we can add `grid=False` to the `axis` attribute. But what if we instead want to reduce the number of tick marks, for example only including grid lines for each order of magnitude?\n",
    "\n",
    "To change the number of ticks, we can specify a target `tickCount` property for an `Axis` object. The `tickCount` is treated as a *suggestion* to Altair, to be considered alongside other aspects such as using nice, human-friendly intervals. We may not get *exactly* the number of tick marks we request, but we should get something close."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "v4Awwd_kN_bf",
    "outputId": "b047adfe-6491-44f4-d84b-8e22836ad923"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-c517fe1bc40f4caf86df0452703f8552\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-c517fe1bc40f4caf86df0452703f8552\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-c517fe1bc40f4caf86df0452703f8552\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"circle\", \"encoding\": {\"x\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle().encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)')\n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "upaCzdH7aIvu"
   },
   "source": [
    "By setting the `tickCount` to 5, we have the desired effect.\n",
    "\n",
    "Our scatter plot points feel a bit small. Let's change the default size by setting the `size` property of the circle mark. This size value is the *area* of the mark in pixels."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "aERDKc0KOhco",
    "outputId": "e3257bc3-40aa-4539-edea-a923c0329675"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-88ffd47ee4794d01ad2651b145f7fd21\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-88ffd47ee4794d01ad2651b145f7fd21\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-88ffd47ee4794d01ad2651b145f7fd21\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": {\"type\": \"circle\", \"size\": 80}, \"encoding\": {\"x\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle(size=80).encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)'), \n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "I-0rEs3lapPh"
   },
   "source": [
    "Here we've set the circle mark area to 80 pixels. _Further adjust the value as you see fit!_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "AJ8dwejXO9cc"
   },
   "source": [
    "## Configuring Color Legends"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "obwIbbZa_KNd"
   },
   "source": [
    "### Color by Gram Staining\n",
    "\n",
    "_Above we saw that neomycin is more effective for some bacteria, while penicillin is more effective for others. But how can we tell which antibiotic to use if we don't know the specific species of bacteria? Gram staining serves as a diagnostic for discriminating classes of bacteria!_\n",
    "\n",
    "Let's encode `Gram_Staining` on the `color` channel as a nominal data type:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "pkSc_PXyAuGg",
    "outputId": "01446cfb-f968-4dfb-c695-4372f55bd5f1"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-7fcb3cc208654831bc67abf0253c74a4\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-7fcb3cc208654831bc67abf0253c74a4\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-7fcb3cc208654831bc67abf0253c74a4\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": {\"type\": \"circle\", \"size\": 80}, \"encoding\": {\"color\": {\"type\": \"nominal\", \"field\": \"Gram_Staining\"}, \"x\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle(size=80).encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Color('Gram_Staining:N')\n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "a1Ec7fCUBQJn"
   },
   "source": [
    "_We can see that Gram-positive bacteria seem most susceptible to penicillin, whereas neomycin is more effective for Gram-negative bacteria!_\n",
    "\n",
    "The color scheme above was automatically chosen to provide perceptually-distinguishable colors for nominal (equal or not equal) comparisons. However, we might wish to customize the colors used. In this case, Gram staining results in [distinctive physical colorings: pink for Gram-negative, purple for Gram-positive](https://en.wikipedia.org/wiki/Gram_stain#/media/File:Gram_stain_01.jpg).\n",
    "\n",
    "Let's use those colors by specifying an explicit scale mapping from the data `domain` to the color `range`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "XA4UUWriCEox",
    "outputId": "f2ada6d0-d969-4927-a268-6f842c1b65ad"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-9a932809d3c6423e8dc46984e31fa21e\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-9a932809d3c6423e8dc46984e31fa21e\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-9a932809d3c6423e8dc46984e31fa21e\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": {\"type\": \"circle\", \"size\": 80}, \"encoding\": {\"color\": {\"type\": \"nominal\", \"field\": \"Gram_Staining\", \"scale\": {\"domain\": [\"negative\", \"positive\"], \"range\": [\"hotpink\", \"purple\"]}}, \"x\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle(size=80).encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Color('Gram_Staining:N',\n",
    "          scale=alt.Scale(domain=['negative', 'positive'], range=['hotpink', 'purple'])\n",
    "    )\n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "cfgvdp8cBHmZ"
   },
   "source": [
    "By default legends are placed on the right side of the chart. Similar to axes, we can change the legend orientation using the `orient` parameter:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "wlb7-9SNBUdZ",
    "outputId": "32b3e78c-7860-4ef4-850f-9af24cb58edd"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-9e269262e2bb48d59b1b5567e02724b9\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-9e269262e2bb48d59b1b5567e02724b9\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-9e269262e2bb48d59b1b5567e02724b9\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": {\"type\": \"circle\", \"size\": 80}, \"encoding\": {\"color\": {\"type\": \"nominal\", \"field\": \"Gram_Staining\", \"legend\": {\"orient\": \"left\"}, \"scale\": {\"domain\": [\"negative\", \"positive\"], \"range\": [\"hotpink\", \"purple\"]}}, \"x\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle(size=80).encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Color('Gram_Staining:N',\n",
    "          scale=alt.Scale(domain=['negative', 'positive'], range=['hotpink', 'purple']),\n",
    "          legend=alt.Legend(orient='left')\n",
    "    )\n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "nwoOrGb6BtrF"
   },
   "source": [
    "We can also remove a legend entirely by specifying `legend=None`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "YEcweSOABxss",
    "outputId": "a6e539ce-1b2c-4b6f-c504-edbeb659b5d4"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-a6b8ddb783384c66a66c832e5b121b5e\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-a6b8ddb783384c66a66c832e5b121b5e\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-a6b8ddb783384c66a66c832e5b121b5e\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": {\"type\": \"circle\", \"size\": 80}, \"encoding\": {\"color\": {\"type\": \"nominal\", \"field\": \"Gram_Staining\", \"legend\": null, \"scale\": {\"domain\": [\"negative\", \"positive\"], \"range\": [\"hotpink\", \"purple\"]}}, \"x\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle(size=80).encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Color('Gram_Staining:N',\n",
    "          scale=alt.Scale(domain=['negative', 'positive'], range=['hotpink', 'purple']),\n",
    "          legend=None\n",
    "    )\n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "M64uVeFHDIlT"
   },
   "source": [
    "### Color by Species\n",
    "\n",
    "_So far we've considered the effectiveness of antibiotics. Let's turn around and ask a different question: what might antibiotic response teach us about the different species of bacteria?_\n",
    "\n",
    "To start, let's encode `Bacteria` (a nominal data field) using the `color` channel:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "di1mU7ynOq0u",
    "outputId": "4d7a1300-79ea-429c-9a6a-4de170eabddf"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-877341234886482bbcf8dec0be4d8c53\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-877341234886482bbcf8dec0be4d8c53\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-877341234886482bbcf8dec0be4d8c53\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": {\"type\": \"circle\", \"size\": 80}, \"encoding\": {\"color\": {\"type\": \"nominal\", \"field\": \"Bacteria\"}, \"x\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle(size=80).encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Color('Bacteria:N')\n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "8Z02YhSRa6aw"
   },
   "source": [
    "_The result is a bit of a mess!_ There are enough unique bacteria that Altair starts repeating colors from its default 10-color palette for nominal values.\n",
    "\n",
    "To use custom colors, we can update the color encoding `scale` property. One option is to provide explicit scale `domain` and `range` values to indicate the precise color mappings per value, as we did above for Gram staining. Another option is to use an alternative color scheme. Altair includes a variety of built-in color schemes. For a complete list, see the [Vega color scheme documentation](https://vega.github.io/vega/docs/schemes/#reference).\n",
    "\n",
    "Let's try switching to a built-in 20-color scheme, `tableau20`, and set that using the scale `scheme` property."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "wkt58FGQPCU2",
    "outputId": "365fc89f-4ab4-47aa-fe40-70f175c2c58d"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-2914df2e1b7b4d33b319e9ee04804014\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-2914df2e1b7b4d33b319e9ee04804014\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-2914df2e1b7b4d33b319e9ee04804014\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": {\"type\": \"circle\", \"size\": 80}, \"encoding\": {\"color\": {\"type\": \"nominal\", \"field\": \"Bacteria\", \"scale\": {\"scheme\": \"tableau20\"}}, \"x\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle(size=80).encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Color('Bacteria:N',\n",
    "          scale=alt.Scale(scheme='tableau20'))\n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "28Hr54iIbwE4"
   },
   "source": [
    "_We now have a unique color for each bacteria, but the chart is still a mess. Among other issues, the encoding takes no account of bacteria that belong to the same genus. In the chart above, the two different Salmonella strains have very different hues (teal and pink), despite being biological cousins._\n",
    "\n",
    "To try a different scheme, we can also change the data type from nominal to ordinal. The default ordinal scheme uses blue shades, ramping from light to dark:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "L3XSjQqePa-z",
    "outputId": "dd1dad11-c74e-4339-9533-4cd195af12a2"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-20312a0f848f43879613116bf78d84b7\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-20312a0f848f43879613116bf78d84b7\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-20312a0f848f43879613116bf78d84b7\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": {\"type\": \"circle\", \"size\": 80}, \"encoding\": {\"color\": {\"type\": \"ordinal\", \"field\": \"Bacteria\"}, \"x\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle(size=80).encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Color('Bacteria:O')\n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "Me8FkMJlErIi"
   },
   "source": [
    "_Some of those blue shades may be hard to distinguish._\n",
    "\n",
    "For more differentiated colors, we can experiment with alternatives to the default `blues` color scheme. The `viridis` scheme ramps through both hue and luminance:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "r7Jb5izEE1b4",
    "outputId": "3927106a-dd42-43c5-847a-4f030b467c4c"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-309dda6b3c1d4e11af67150b0240555f\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-309dda6b3c1d4e11af67150b0240555f\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-309dda6b3c1d4e11af67150b0240555f\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": {\"type\": \"circle\", \"size\": 80}, \"encoding\": {\"color\": {\"type\": \"ordinal\", \"field\": \"Bacteria\", \"scale\": {\"scheme\": \"viridis\"}}, \"x\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle(size=80).encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Color('Bacteria:O',\n",
    "          scale=alt.Scale(scheme='viridis'))\n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "o98wtYo4cIAz"
   },
   "source": [
    "_Bacteria from the same genus now have more similar colors than before, but the chart still remains confusing. There are many colors, they are hard to look up in the legend accurately, and two bacteria may have similar colors but different genus._"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "Hpjqbi4rAhst"
   },
   "source": [
    "### Color by Genus\n",
    "\n",
    "Let's try to color by genus instead of bacteria. To do so, we will add a `calculate` transform that splits up the bacteria name on space characters and takes the first word in the resulting array. We can then encode the resulting `Genus` field using the `tableau20` color scheme.\n",
    "\n",
    "(Note that the antibiotics dataset includes a pre-calculated `Genus` field, but we will ignore it here in order to further explore Altair's data transformations.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "39g0fVG6cuTG",
    "outputId": "654d3638-bded-4bbc-c88b-2e52c88e541c"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-4715e4e636f145fcadb5d6a198734453\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-4715e4e636f145fcadb5d6a198734453\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-4715e4e636f145fcadb5d6a198734453\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": {\"type\": \"circle\", \"size\": 80}, \"encoding\": {\"color\": {\"type\": \"nominal\", \"field\": \"Genus\", \"scale\": {\"scheme\": \"tableau20\"}}, \"x\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"transform\": [{\"calculate\": \"split(datum.Bacteria, \\\" \\\")[0]\", \"as\": \"Genus\"}], \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle(size=80).transform_calculate(\n",
    "    Genus='split(datum.Bacteria, \" \")[0]'\n",
    ").encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Color('Genus:N',\n",
    "          scale=alt.Scale(scheme='tableau20'))\n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "UMH3wAeWdAXL"
   },
   "source": [
    "_Hmm... While the data are better segregated by genus, this cacapohony of colors doesn't seem particularly useful._\n",
    "\n",
    "_If we look at some of the previous charts carefully, we can see that only a handful of bacteria have a genus shared with another bacteria: Salmonella, Staphylococcus, and Streptococcus. To focus our comparison, we might add colors only for these repeated genus values._\n",
    "\n",
    "Let's add another `calculate` transform that takes a genus name, keeps it if it is one of the repeated values, and otherwise uses the string `\"Other\"`.\n",
    "\n",
    "In addition, we can add custom color encodings using explicit `domain` and `range` arrays for the color encoding `scale`.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 322
    },
    "colab_type": "code",
    "id": "Qmi_geBiPgvr",
    "outputId": "9e06d0a1-756a-4a46-cedf-e2be85e7b09d"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-e1df56b9bd8245c7bc4831a8d899e166\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-e1df56b9bd8245c7bc4831a8d899e166\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-e1df56b9bd8245c7bc4831a8d899e166\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": {\"type\": \"circle\", \"size\": 80}, \"encoding\": {\"color\": {\"type\": \"nominal\", \"field\": \"Genus\", \"scale\": {\"domain\": [\"Salmonella\", \"Staphylococcus\", \"Streptococcus\", \"Other\"], \"range\": [\"rgb(76,120,168)\", \"rgb(84,162,75)\", \"rgb(228,87,86)\", \"rgb(121,112,110)\"]}}, \"x\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Neomycin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Neomycin MIC (\\u03bcg/ml, reverse log scale)\"}, \"y\": {\"type\": \"quantitative\", \"axis\": {\"tickCount\": 5}, \"field\": \"Penicillin\", \"scale\": {\"domain\": [0.001, 1000], \"type\": \"log\"}, \"sort\": \"descending\", \"title\": \"Penicillin MIC (\\u03bcg/ml, reverse log scale)\"}}, \"height\": 250, \"transform\": [{\"calculate\": \"split(datum.Bacteria, \\\" \\\")[0]\", \"as\": \"Split\"}, {\"calculate\": \"indexof([\\\"Salmonella\\\", \\\"Staphylococcus\\\", \\\"Streptococcus\\\"], datum.Split) >= 0 ? datum.Split : \\\"Other\\\"\", \"as\": \"Genus\"}], \"width\": 250, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_circle(size=80).transform_calculate(\n",
    "  Split='split(datum.Bacteria, \" \")[0]'\n",
    ").transform_calculate(\n",
    "  Genus='indexof([\"Salmonella\", \"Staphylococcus\", \"Streptococcus\"], datum.Split) >= 0 ? datum.Split : \"Other\"'\n",
    ").encode(\n",
    "    alt.X('Neomycin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Neomycin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Y('Penicillin:Q',\n",
    "          sort='descending',\n",
    "          scale=alt.Scale(type='log', domain=[0.001, 1000]),\n",
    "          axis=alt.Axis(tickCount=5),\n",
    "          title='Penicillin MIC (μg/ml, reverse log scale)'),\n",
    "    alt.Color('Genus:N',\n",
    "          scale=alt.Scale(\n",
    "            domain=['Salmonella', 'Staphylococcus', 'Streptococcus', 'Other'],\n",
    "            range=['rgb(76,120,168)', 'rgb(84,162,75)', 'rgb(228,87,86)', 'rgb(121,112,110)']\n",
    "          ))\n",
    ").properties(width=250, height=250)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "QQAuRPEDeRjU"
   },
   "source": [
    "_We now have a much more revealing plot, made possible by customizations to the axes and legend. Take a moment to examine the plot above. Notice any surprising groupings?_\n",
    "\n",
    "_The upper-left region has a cluster of red Streptococcus bacteria, but with a grey Other bacteria alongside them. Meanwhile, towards the middle-right we see another red Streptococcus placed far away from it's \"cousins\". Might we expect bacteria from the same genus (and thus presumably more genetically similar) to be grouped closer together?_\n",
    "\n",
    "As it so happens, the underlying dataset actually contains errors. The dataset reflects the species designations used in the early 1950s. However, the scientific consensus has since been overturned. That gray point in the upper-left? It's now considered a Streptococcus! That red point towards the middle-right? It's no longer considered a Streptococcus!\n",
    "\n",
    "Of course, on its own, this dataset doesn't fully justify these reclassifications. Nevertheless, the data contain valuable biological clues that went overlooked for decades! Visualization, when used by an appropriately skilled and inquisitive viewer, can be a powerful tool for discovery.\n",
    "\n",
    "This example also reinforces an important lesson: **_always be skeptical of your data!_**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "QT1isVxqftkU"
   },
   "source": [
    "### Color by Antibiotic Response\n",
    "\n",
    "We might also use the `color` channel to encode quantitative values. Though keep in mind that typically color is not as effective for conveying quantities as position or size encodings!\n",
    "\n",
    "Here is a basic heatmap of penicillin MIC values for each bacteria. We'll use a `rect` mark and sort the bacteria by descending MIC values (from most to least resistant):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 367
    },
    "colab_type": "code",
    "id": "orEjpD5uU2m0",
    "outputId": "0a92631d-1f68-4840-d5cd-26399f559aba"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-73658a5c6a114e279fbc2bf73e22f50f\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-73658a5c6a114e279fbc2bf73e22f50f\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-73658a5c6a114e279fbc2bf73e22f50f\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"rect\", \"encoding\": {\"color\": {\"type\": \"quantitative\", \"field\": \"Penicillin\"}, \"y\": {\"type\": \"nominal\", \"field\": \"Bacteria\", \"sort\": {\"field\": \"Penicillin\", \"op\": \"max\", \"order\": \"descending\"}}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_rect().encode(\n",
    "    alt.Y('Bacteria:N',\n",
    "      sort=alt.EncodingSortField(field='Penicillin', op='max', order='descending')\n",
    "    ),\n",
    "    alt.Color('Penicillin:Q')\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "UjInt4P8Ki5I"
   },
   "source": [
    "We can further improve this chart by combining features we've seen thus far: a log-transformed scale, a change of axis orientation, a custom color scheme (`plasma`), tick count adjustment, and custom title text. We'll also exercise configuration options to adjust the axis title placement and legend title alignment."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 367
    },
    "colab_type": "code",
    "id": "spIpf8S6J1pJ",
    "outputId": "96210f62-39b2-4e61-a528-cd6f8b552f77"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-44e9f9b399274a96886c2d47846fdf8e\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-44e9f9b399274a96886c2d47846fdf8e\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-44e9f9b399274a96886c2d47846fdf8e\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"rect\", \"encoding\": {\"color\": {\"type\": \"quantitative\", \"field\": \"Penicillin\", \"legend\": {\"tickCount\": 5, \"titleOrient\": \"right\"}, \"scale\": {\"nice\": true, \"scheme\": \"plasma\", \"type\": \"log\"}, \"title\": \"Penicillin MIC (\\u03bcg/ml)\"}, \"y\": {\"type\": \"nominal\", \"axis\": {\"orient\": \"right\", \"titleAlign\": \"left\", \"titleAngle\": 0, \"titleX\": 7, \"titleY\": -2}, \"field\": \"Bacteria\", \"sort\": {\"field\": \"Penicillin\", \"op\": \"max\", \"order\": \"descending\"}}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics).mark_rect().encode(\n",
    "    alt.Y('Bacteria:N',\n",
    "      sort=alt.EncodingSortField(field='Penicillin', op='max', order='descending'),\n",
    "      axis=alt.Axis(\n",
    "        orient='right',     # orient axis on right side of chart\n",
    "        titleX=7,           # set x-position to 7 pixels right of chart\n",
    "        titleY=-2,          # set y-position to 2 pixels above chart\n",
    "        titleAlign='left',  # use left-aligned text\n",
    "        titleAngle=0        # undo default title rotation\n",
    "      )\n",
    "    ),\n",
    "    alt.Color('Penicillin:Q',\n",
    "      scale=alt.Scale(type='log', scheme='plasma', nice=True),\n",
    "      legend=alt.Legend(titleOrient='right', tickCount=5),\n",
    "      title='Penicillin MIC (μg/ml)'\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternatively, we can remove the axis title altogether, and use the top-level `title` property to add a title for the entire chart:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-b10095aa35724ebb960e7e9beb2a98ed\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-b10095aa35724ebb960e7e9beb2a98ed\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-b10095aa35724ebb960e7e9beb2a98ed\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.8.1?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function loadScript(lib) {\n",
       "      return new Promise(function(resolve, reject) {\n",
       "        var s = document.createElement('script');\n",
       "        s.src = paths[lib];\n",
       "        s.async = true;\n",
       "        s.onload = () => resolve(paths[lib]);\n",
       "        s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "        document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else if (typeof vegaEmbed === \"function\") {\n",
       "      displayChart(vegaEmbed);\n",
       "    } else {\n",
       "      loadScript(\"vega\")\n",
       "        .then(() => loadScript(\"vega-lite\"))\n",
       "        .then(() => loadScript(\"vega-embed\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}, \"title\": {\"anchor\": \"start\", \"offset\": 5}}, \"data\": {\"url\": \"https://cdn.jsdelivr.net/npm/vega-datasets@1/data/burtin.json\"}, \"mark\": \"rect\", \"encoding\": {\"color\": {\"type\": \"quantitative\", \"field\": \"Penicillin\", \"legend\": {\"tickCount\": 5, \"titleOrient\": \"right\"}, \"scale\": {\"nice\": true, \"scheme\": \"plasma\", \"type\": \"log\"}, \"title\": \"Penicillin MIC (\\u03bcg/ml)\"}, \"y\": {\"type\": \"nominal\", \"axis\": {\"orient\": \"right\", \"title\": null}, \"field\": \"Bacteria\", \"sort\": {\"field\": \"Penicillin\", \"op\": \"max\", \"order\": \"descending\"}}}, \"title\": \"Penicillin Resistance of Bacterial Strains\", \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.8.1.json\"}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alt.Chart(antibiotics, title='Penicillin Resistance of Bacterial Strains').mark_rect().encode(\n",
    "    alt.Y('Bacteria:N',\n",
    "      sort=alt.EncodingSortField(field='Penicillin', op='max', order='descending'),\n",
    "      axis=alt.Axis(orient='right', title=None)\n",
    "    ),\n",
    "    alt.Color('Penicillin:Q',\n",
    "      scale=alt.Scale(type='log', scheme='plasma', nice=True),\n",
    "      legend=alt.Legend(titleOrient='right', tickCount=5),\n",
    "      title='Penicillin MIC (μg/ml)'\n",
    "    )\n",
    ").configure_title(\n",
    "  anchor='start', # anchor and left-align title\n",
    "  offset=5        # set title offset from chart\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "0yZWjogLK8yz"
   },
   "source": [
    "## Summary\n",
    "\n",
    "Integrating what we've learned across the notebooks so far about encodings, data transforms, and customization, you should now be prepared to make a wide variety of statistical graphics. Now you can put Altair into everyday use for exploring and communicating data!\n",
    "\n",
    "Interested in learning more about this topic?\n",
    "\n",
    "- Start with the [Altair Customizing Visualizations documentation](https://altair-viz.github.io/user_guide/customization.html).\n",
    "- For a complementary discussion of scale mappings, see [\"Introducing d3-scale\"](https://medium.com/@mbostock/introducing-d3-scale-61980c51545f).\n",
    "- For a more in-depth exploration of all the ways axes and legends can be styled by the underlying Vega library (which powers Altair and Vega-Lite), see [\"A Guide to Guides: Axes & Legends in Vega\"](https://beta.observablehq.com/@jheer/a-guide-to-guides-axes-legends-in-vega).\n",
    "- For a fascinating history of the antibiotics dataset, see [Wainer &amp; Lysen's \"That's Funny...\"](https://www.americanscientist.org/article/thats-funny) in the _American Scientist_."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
