1100 lines
59 KiB
Plaintext
1100 lines
59 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "b30269d6-9c9d-4a1f-a5e2-95c94a4877d6",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Introduction to Altair\n",
|
|
"\n",
|
|
"## Before we start: Jupyter Notebooks\n",
|
|
"\n",
|
|
"- Made up of \"cells\" which can be Python, markdown, or with extensions, any language.\n",
|
|
"- Cells execute individually, and can execute out of order. Always re-order cells to be logical and make use of comments and/or markdown cells to make your notebook a narrative.\n",
|
|
"- Tip: Before submitting a notebook, restart the kernel and run all cells in order. (See Kernel menu for options.) Ensure that you didn't inadvertently break things.\n",
|
|
"- Not particularly Git friendly as the contents of the notebook are stored in JSON. (Still keep them in Git! even if suboptimal better than losing work!)\n",
|
|
"- An alternative is `marimo` notebooks, which fix a few of the above issues. Still new & there are some rough edges still so I'll be sticking with Jupyter.\n",
|
|
"\n",
|
|
"`uv run jupyter lab` or `uv run jupyter notebook` will start the local notebook server (Lab is a newer UI, Notebook is the traditional one). You may opt to use VS Code, but I personallyh find their interface for notebooks more confusing than helpful.\n",
|
|
"\n",
|
|
"### Style Addendum (for all assignments in this course)\n",
|
|
"\n",
|
|
"- Notebook style imports allowed/preferred.\n",
|
|
"- Limited use of global variables permitted with useful names and comments.\n",
|
|
"- Notebooks must execute sequentially!"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "MJUe",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Altair expects \"tidy\" data\n",
|
|
"\n",
|
|
"Altair expects our data to be [tidy](http://vita.had.co.nz/papers/tidy-data.html).\n",
|
|
"\n",
|
|
"- Each variable is a column.\n",
|
|
"- Each observation is a row.\n",
|
|
"- Each type of observational unit is a table.\n",
|
|
"\n",
|
|
"You may use `pandas` or `polars` DataFrames. \n",
|
|
"Class examples will focus on pre-cleaned data, and I will use polars in examples, though rarely will what I show differ significantly in pandas."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"id": "Hbol",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# best to follow convention, \"notebook\" style imports are allowed/preferred\n",
|
|
"import marimo as mo\n",
|
|
"import altair as alt\n",
|
|
"import polars as pl\n",
|
|
"from pathlib import Path"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 22,
|
|
"id": "vblA",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div><style>\n",
|
|
".dataframe > thead > tr,\n",
|
|
".dataframe > tbody > tr {\n",
|
|
" text-align: right;\n",
|
|
" white-space: pre-wrap;\n",
|
|
"}\n",
|
|
"</style>\n",
|
|
"<small>shape: (12, 3)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>state</th><th>session_start_year</th><th>num_bills</th></tr><tr><td>str</td><td>i64</td><td>i64</td></tr></thead><tbody><tr><td>"IL"</td><td>2017</td><td>13616</td></tr><tr><td>"IL"</td><td>2019</td><td>12760</td></tr><tr><td>"IL"</td><td>2021</td><td>12847</td></tr><tr><td>"IL"</td><td>2023</td><td>11951</td></tr><tr><td>"MI"</td><td>2017</td><td>4818</td></tr><tr><td>…</td><td>…</td><td>…</td></tr><tr><td>"MI"</td><td>2023</td><td>3424</td></tr><tr><td>"WI"</td><td>2017</td><td>1820</td></tr><tr><td>"WI"</td><td>2019</td><td>2264</td></tr><tr><td>"WI"</td><td>2021</td><td>2618</td></tr><tr><td>"WI"</td><td>2023</td><td>2656</td></tr></tbody></table></div>"
|
|
],
|
|
"text/plain": [
|
|
"shape: (12, 3)\n",
|
|
"┌───────┬────────────────────┬───────────┐\n",
|
|
"│ state ┆ session_start_year ┆ num_bills │\n",
|
|
"│ --- ┆ --- ┆ --- │\n",
|
|
"│ str ┆ i64 ┆ i64 │\n",
|
|
"╞═══════╪════════════════════╪═══════════╡\n",
|
|
"│ IL ┆ 2017 ┆ 13616 │\n",
|
|
"│ IL ┆ 2019 ┆ 12760 │\n",
|
|
"│ IL ┆ 2021 ┆ 12847 │\n",
|
|
"│ IL ┆ 2023 ┆ 11951 │\n",
|
|
"│ MI ┆ 2017 ┆ 4818 │\n",
|
|
"│ … ┆ … ┆ … │\n",
|
|
"│ MI ┆ 2023 ┆ 3424 │\n",
|
|
"│ WI ┆ 2017 ┆ 1820 │\n",
|
|
"│ WI ┆ 2019 ┆ 2264 │\n",
|
|
"│ WI ┆ 2021 ┆ 2618 │\n",
|
|
"│ WI ┆ 2023 ┆ 2656 │\n",
|
|
"└───────┴────────────────────┴───────────┘"
|
|
]
|
|
},
|
|
"execution_count": 22,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Also OK, limited use of global variables.\n",
|
|
"#\n",
|
|
"# Avoid `df` though because that is a common parameter name and not helpful in a global context.\n",
|
|
"# Also to avoid: `df2`, `df_pure`, `df_final_final_final_final_v4_v9`.\n",
|
|
"\n",
|
|
"# first let's load and look at a dataframe with three columns\n",
|
|
"# there is an observation for each state legislature, showing how many bills they introduced in a given year\n",
|
|
"bills = pl.read_csv(\"midwest_bills.csv\")\n",
|
|
"\n",
|
|
"# Having a dataframe or chart variable as the last line in a notebook cell will automatically display it.\n",
|
|
"# Use sparingly, and typically only for final chart in your own work, but in tutorials I will show intermediate steps.\n",
|
|
"bills"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"id": "bkHC",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Let's make our own charts of this data, first we bind the data to a new chart object\n",
|
|
"chart = alt.Chart(df)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"id": "lEQa",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
"<style>\n",
|
|
" #altair-viz-ce76917b42b6429cac34c70b23e012b3.vega-embed {\n",
|
|
" width: 100%;\n",
|
|
" display: flex;\n",
|
|
" }\n",
|
|
"\n",
|
|
" #altair-viz-ce76917b42b6429cac34c70b23e012b3.vega-embed details,\n",
|
|
" #altair-viz-ce76917b42b6429cac34c70b23e012b3.vega-embed details summary {\n",
|
|
" position: relative;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<div id=\"altair-viz-ce76917b42b6429cac34c70b23e012b3\"></div>\n",
|
|
"<script type=\"text/javascript\">\n",
|
|
" var VEGA_DEBUG = (typeof VEGA_DEBUG == \"undefined\") ? {} : VEGA_DEBUG;\n",
|
|
" (function(spec, embedOpt){\n",
|
|
" let outputDiv = document.currentScript.previousElementSibling;\n",
|
|
" if (outputDiv.id !== \"altair-viz-ce76917b42b6429cac34c70b23e012b3\") {\n",
|
|
" outputDiv = document.getElementById(\"altair-viz-ce76917b42b6429cac34c70b23e012b3\");\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@5.20.1?noext\",\n",
|
|
" \"vega-embed\": \"https://cdn.jsdelivr.net/npm/vega-embed@6?noext\",\n",
|
|
" };\n",
|
|
"\n",
|
|
" function maybeLoadScript(lib, version) {\n",
|
|
" var key = `${lib.replace(\"-\", \"\")}_version`;\n",
|
|
" return (VEGA_DEBUG[key] == version) ?\n",
|
|
" Promise.resolve(paths[lib]) :\n",
|
|
" new Promise(function(resolve, reject) {\n",
|
|
" var s = document.createElement('script');\n",
|
|
" document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
|
|
" s.async = true;\n",
|
|
" s.onload = () => {\n",
|
|
" VEGA_DEBUG[key] = version;\n",
|
|
" return resolve(paths[lib]);\n",
|
|
" };\n",
|
|
" s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
|
|
" s.src = paths[lib];\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 {\n",
|
|
" maybeLoadScript(\"vega\", \"5\")\n",
|
|
" .then(() => maybeLoadScript(\"vega-lite\", \"5.20.1\"))\n",
|
|
" .then(() => maybeLoadScript(\"vega-embed\", \"6\"))\n",
|
|
" .catch(showError)\n",
|
|
" .then(() => displayChart(vegaEmbed));\n",
|
|
" }\n",
|
|
" })({\"config\": {\"view\": {\"continuousWidth\": 300, \"continuousHeight\": 300}}, \"data\": {\"name\": \"data-7819b1facf2e5fc9998dcf4cad0b99f8\"}, \"mark\": {\"type\": \"point\"}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.20.1.json\", \"datasets\": {\"data-7819b1facf2e5fc9998dcf4cad0b99f8\": [{\"state\": \"IL\", \"session_start_year\": 2017, \"num_bills\": 13616}, {\"state\": \"IL\", \"session_start_year\": 2019, \"num_bills\": 12760}, {\"state\": \"IL\", \"session_start_year\": 2021, \"num_bills\": 12847}, {\"state\": \"IL\", \"session_start_year\": 2023, \"num_bills\": 11951}, {\"state\": \"MI\", \"session_start_year\": 2017, \"num_bills\": 4818}, {\"state\": \"MI\", \"session_start_year\": 2019, \"num_bills\": 4450}, {\"state\": \"MI\", \"session_start_year\": 2021, \"num_bills\": 4520}, {\"state\": \"MI\", \"session_start_year\": 2023, \"num_bills\": 3424}, {\"state\": \"WI\", \"session_start_year\": 2017, \"num_bills\": 1820}, {\"state\": \"WI\", \"session_start_year\": 2019, \"num_bills\": 2264}, {\"state\": \"WI\", \"session_start_year\": 2021, \"num_bills\": 2618}, {\"state\": \"WI\", \"session_start_year\": 2023, \"num_bills\": 2656}]}}, {\"mode\": \"vega-lite\"});\n",
|
|
"</script>"
|
|
],
|
|
"text/plain": [
|
|
"alt.Chart(...)"
|
|
]
|
|
},
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# we add a geometry, we'll start with a point (at this point *something* can be displayed, but it won't be useful)\n",
|
|
"chart.mark_point()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 29,
|
|
"id": "PKri",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
"<style>\n",
|
|
" #altair-viz-14388f53e0d5400b802ade3cdfacd6b8.vega-embed {\n",
|
|
" width: 100%;\n",
|
|
" display: flex;\n",
|
|
" }\n",
|
|
"\n",
|
|
" #altair-viz-14388f53e0d5400b802ade3cdfacd6b8.vega-embed details,\n",
|
|
" #altair-viz-14388f53e0d5400b802ade3cdfacd6b8.vega-embed details summary {\n",
|
|
" position: relative;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<div id=\"altair-viz-14388f53e0d5400b802ade3cdfacd6b8\"></div>\n",
|
|
"<script type=\"text/javascript\">\n",
|
|
" var VEGA_DEBUG = (typeof VEGA_DEBUG == \"undefined\") ? {} : VEGA_DEBUG;\n",
|
|
" (function(spec, embedOpt){\n",
|
|
" let outputDiv = document.currentScript.previousElementSibling;\n",
|
|
" if (outputDiv.id !== \"altair-viz-14388f53e0d5400b802ade3cdfacd6b8\") {\n",
|
|
" outputDiv = document.getElementById(\"altair-viz-14388f53e0d5400b802ade3cdfacd6b8\");\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@5.20.1?noext\",\n",
|
|
" \"vega-embed\": \"https://cdn.jsdelivr.net/npm/vega-embed@6?noext\",\n",
|
|
" };\n",
|
|
"\n",
|
|
" function maybeLoadScript(lib, version) {\n",
|
|
" var key = `${lib.replace(\"-\", \"\")}_version`;\n",
|
|
" return (VEGA_DEBUG[key] == version) ?\n",
|
|
" Promise.resolve(paths[lib]) :\n",
|
|
" new Promise(function(resolve, reject) {\n",
|
|
" var s = document.createElement('script');\n",
|
|
" document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
|
|
" s.async = true;\n",
|
|
" s.onload = () => {\n",
|
|
" VEGA_DEBUG[key] = version;\n",
|
|
" return resolve(paths[lib]);\n",
|
|
" };\n",
|
|
" s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
|
|
" s.src = paths[lib];\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 {\n",
|
|
" maybeLoadScript(\"vega\", \"5\")\n",
|
|
" .then(() => maybeLoadScript(\"vega-lite\", \"5.20.1\"))\n",
|
|
" .then(() => maybeLoadScript(\"vega-embed\", \"6\"))\n",
|
|
" .catch(showError)\n",
|
|
" .then(() => displayChart(vegaEmbed));\n",
|
|
" }\n",
|
|
" })({\"config\": {\"view\": {\"continuousWidth\": 300, \"continuousHeight\": 300}}, \"data\": {\"name\": \"data-7819b1facf2e5fc9998dcf4cad0b99f8\"}, \"mark\": {\"type\": \"point\"}, \"encoding\": {\"x\": {\"field\": \"num_bills\", \"type\": \"quantitative\"}, \"y\": {\"field\": \"state\", \"type\": \"nominal\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.20.1.json\", \"datasets\": {\"data-7819b1facf2e5fc9998dcf4cad0b99f8\": [{\"state\": \"IL\", \"session_start_year\": 2017, \"num_bills\": 13616}, {\"state\": \"IL\", \"session_start_year\": 2019, \"num_bills\": 12760}, {\"state\": \"IL\", \"session_start_year\": 2021, \"num_bills\": 12847}, {\"state\": \"IL\", \"session_start_year\": 2023, \"num_bills\": 11951}, {\"state\": \"MI\", \"session_start_year\": 2017, \"num_bills\": 4818}, {\"state\": \"MI\", \"session_start_year\": 2019, \"num_bills\": 4450}, {\"state\": \"MI\", \"session_start_year\": 2021, \"num_bills\": 4520}, {\"state\": \"MI\", \"session_start_year\": 2023, \"num_bills\": 3424}, {\"state\": \"WI\", \"session_start_year\": 2017, \"num_bills\": 1820}, {\"state\": \"WI\", \"session_start_year\": 2019, \"num_bills\": 2264}, {\"state\": \"WI\", \"session_start_year\": 2021, \"num_bills\": 2618}, {\"state\": \"WI\", \"session_start_year\": 2023, \"num_bills\": 2656}]}}, {\"mode\": \"vega-lite\"});\n",
|
|
"</script>"
|
|
],
|
|
"text/plain": [
|
|
"alt.Chart(...)"
|
|
]
|
|
},
|
|
"execution_count": 29,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 1\n",
|
|
"# We use encodings to map our data to particular dimensions.\n",
|
|
"# Altair will make then make appropriate choices based upon the type of data.\n",
|
|
"\n",
|
|
"chart.mark_point().encode(\n",
|
|
" y=\"state\",\n",
|
|
" x=\"num_bills\"\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"id": "SFPL",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
"<style>\n",
|
|
" #altair-viz-c0984a148f9845b7be3b4dc92f7faa3c.vega-embed {\n",
|
|
" width: 100%;\n",
|
|
" display: flex;\n",
|
|
" }\n",
|
|
"\n",
|
|
" #altair-viz-c0984a148f9845b7be3b4dc92f7faa3c.vega-embed details,\n",
|
|
" #altair-viz-c0984a148f9845b7be3b4dc92f7faa3c.vega-embed details summary {\n",
|
|
" position: relative;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<div id=\"altair-viz-c0984a148f9845b7be3b4dc92f7faa3c\"></div>\n",
|
|
"<script type=\"text/javascript\">\n",
|
|
" var VEGA_DEBUG = (typeof VEGA_DEBUG == \"undefined\") ? {} : VEGA_DEBUG;\n",
|
|
" (function(spec, embedOpt){\n",
|
|
" let outputDiv = document.currentScript.previousElementSibling;\n",
|
|
" if (outputDiv.id !== \"altair-viz-c0984a148f9845b7be3b4dc92f7faa3c\") {\n",
|
|
" outputDiv = document.getElementById(\"altair-viz-c0984a148f9845b7be3b4dc92f7faa3c\");\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@5.20.1?noext\",\n",
|
|
" \"vega-embed\": \"https://cdn.jsdelivr.net/npm/vega-embed@6?noext\",\n",
|
|
" };\n",
|
|
"\n",
|
|
" function maybeLoadScript(lib, version) {\n",
|
|
" var key = `${lib.replace(\"-\", \"\")}_version`;\n",
|
|
" return (VEGA_DEBUG[key] == version) ?\n",
|
|
" Promise.resolve(paths[lib]) :\n",
|
|
" new Promise(function(resolve, reject) {\n",
|
|
" var s = document.createElement('script');\n",
|
|
" document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
|
|
" s.async = true;\n",
|
|
" s.onload = () => {\n",
|
|
" VEGA_DEBUG[key] = version;\n",
|
|
" return resolve(paths[lib]);\n",
|
|
" };\n",
|
|
" s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
|
|
" s.src = paths[lib];\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 {\n",
|
|
" maybeLoadScript(\"vega\", \"5\")\n",
|
|
" .then(() => maybeLoadScript(\"vega-lite\", \"5.20.1\"))\n",
|
|
" .then(() => maybeLoadScript(\"vega-embed\", \"6\"))\n",
|
|
" .catch(showError)\n",
|
|
" .then(() => displayChart(vegaEmbed));\n",
|
|
" }\n",
|
|
" })({\"config\": {\"view\": {\"continuousWidth\": 300, \"continuousHeight\": 300}}, \"data\": {\"name\": \"data-7819b1facf2e5fc9998dcf4cad0b99f8\"}, \"mark\": {\"type\": \"point\"}, \"encoding\": {\"color\": {\"field\": \"session_start_year\", \"type\": \"quantitative\"}, \"x\": {\"field\": \"num_bills\", \"type\": \"quantitative\"}, \"y\": {\"field\": \"state\", \"type\": \"nominal\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.20.1.json\", \"datasets\": {\"data-7819b1facf2e5fc9998dcf4cad0b99f8\": [{\"state\": \"IL\", \"session_start_year\": 2017, \"num_bills\": 13616}, {\"state\": \"IL\", \"session_start_year\": 2019, \"num_bills\": 12760}, {\"state\": \"IL\", \"session_start_year\": 2021, \"num_bills\": 12847}, {\"state\": \"IL\", \"session_start_year\": 2023, \"num_bills\": 11951}, {\"state\": \"MI\", \"session_start_year\": 2017, \"num_bills\": 4818}, {\"state\": \"MI\", \"session_start_year\": 2019, \"num_bills\": 4450}, {\"state\": \"MI\", \"session_start_year\": 2021, \"num_bills\": 4520}, {\"state\": \"MI\", \"session_start_year\": 2023, \"num_bills\": 3424}, {\"state\": \"WI\", \"session_start_year\": 2017, \"num_bills\": 1820}, {\"state\": \"WI\", \"session_start_year\": 2019, \"num_bills\": 2264}, {\"state\": \"WI\", \"session_start_year\": 2021, \"num_bills\": 2618}, {\"state\": \"WI\", \"session_start_year\": 2023, \"num_bills\": 2656}]}}, {\"mode\": \"vega-lite\"});\n",
|
|
"</script>"
|
|
],
|
|
"text/plain": [
|
|
"alt.Chart(...)"
|
|
]
|
|
},
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 2 - what happens when we try to add color?\n",
|
|
"chart.mark_point().encode(\n",
|
|
" alt.Y(\"state\"),\n",
|
|
" alt.X(\"num_bills\"),\n",
|
|
" alt.Color(\"session_start_year\"),\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 32,
|
|
"id": "BYtC",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
"<style>\n",
|
|
" #altair-viz-aea0a88137694b9a82ca539c11313c96.vega-embed {\n",
|
|
" width: 100%;\n",
|
|
" display: flex;\n",
|
|
" }\n",
|
|
"\n",
|
|
" #altair-viz-aea0a88137694b9a82ca539c11313c96.vega-embed details,\n",
|
|
" #altair-viz-aea0a88137694b9a82ca539c11313c96.vega-embed details summary {\n",
|
|
" position: relative;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<div id=\"altair-viz-aea0a88137694b9a82ca539c11313c96\"></div>\n",
|
|
"<script type=\"text/javascript\">\n",
|
|
" var VEGA_DEBUG = (typeof VEGA_DEBUG == \"undefined\") ? {} : VEGA_DEBUG;\n",
|
|
" (function(spec, embedOpt){\n",
|
|
" let outputDiv = document.currentScript.previousElementSibling;\n",
|
|
" if (outputDiv.id !== \"altair-viz-aea0a88137694b9a82ca539c11313c96\") {\n",
|
|
" outputDiv = document.getElementById(\"altair-viz-aea0a88137694b9a82ca539c11313c96\");\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@5.20.1?noext\",\n",
|
|
" \"vega-embed\": \"https://cdn.jsdelivr.net/npm/vega-embed@6?noext\",\n",
|
|
" };\n",
|
|
"\n",
|
|
" function maybeLoadScript(lib, version) {\n",
|
|
" var key = `${lib.replace(\"-\", \"\")}_version`;\n",
|
|
" return (VEGA_DEBUG[key] == version) ?\n",
|
|
" Promise.resolve(paths[lib]) :\n",
|
|
" new Promise(function(resolve, reject) {\n",
|
|
" var s = document.createElement('script');\n",
|
|
" document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
|
|
" s.async = true;\n",
|
|
" s.onload = () => {\n",
|
|
" VEGA_DEBUG[key] = version;\n",
|
|
" return resolve(paths[lib]);\n",
|
|
" };\n",
|
|
" s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
|
|
" s.src = paths[lib];\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 {\n",
|
|
" maybeLoadScript(\"vega\", \"5\")\n",
|
|
" .then(() => maybeLoadScript(\"vega-lite\", \"5.20.1\"))\n",
|
|
" .then(() => maybeLoadScript(\"vega-embed\", \"6\"))\n",
|
|
" .catch(showError)\n",
|
|
" .then(() => displayChart(vegaEmbed));\n",
|
|
" }\n",
|
|
" })({\"config\": {\"view\": {\"continuousWidth\": 300, \"continuousHeight\": 300}}, \"data\": {\"name\": \"data-7819b1facf2e5fc9998dcf4cad0b99f8\"}, \"mark\": {\"type\": \"point\"}, \"encoding\": {\"color\": {\"field\": \"session_start_year\", \"type\": \"nominal\"}, \"x\": {\"field\": \"num_bills\", \"type\": \"quantitative\"}, \"y\": {\"field\": \"state\", \"type\": \"nominal\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.20.1.json\", \"datasets\": {\"data-7819b1facf2e5fc9998dcf4cad0b99f8\": [{\"state\": \"IL\", \"session_start_year\": 2017, \"num_bills\": 13616}, {\"state\": \"IL\", \"session_start_year\": 2019, \"num_bills\": 12760}, {\"state\": \"IL\", \"session_start_year\": 2021, \"num_bills\": 12847}, {\"state\": \"IL\", \"session_start_year\": 2023, \"num_bills\": 11951}, {\"state\": \"MI\", \"session_start_year\": 2017, \"num_bills\": 4818}, {\"state\": \"MI\", \"session_start_year\": 2019, \"num_bills\": 4450}, {\"state\": \"MI\", \"session_start_year\": 2021, \"num_bills\": 4520}, {\"state\": \"MI\", \"session_start_year\": 2023, \"num_bills\": 3424}, {\"state\": \"WI\", \"session_start_year\": 2017, \"num_bills\": 1820}, {\"state\": \"WI\", \"session_start_year\": 2019, \"num_bills\": 2264}, {\"state\": \"WI\", \"session_start_year\": 2021, \"num_bills\": 2618}, {\"state\": \"WI\", \"session_start_year\": 2023, \"num_bills\": 2656}]}}, {\"mode\": \"vega-lite\"});\n",
|
|
"</script>"
|
|
],
|
|
"text/plain": [
|
|
"alt.Chart(...)"
|
|
]
|
|
},
|
|
"execution_count": 32,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 3\n",
|
|
"# The prior example treated year as an Ordinal because it was numeric,\n",
|
|
"# instead we would treat it as Nominal for this data.\n",
|
|
"# We can use :Q, :O, :N, :T to mark the type that should be used.\n",
|
|
"\n",
|
|
"by_year = chart.mark_point().encode(\n",
|
|
" alt.Y(\"state:N\"),\n",
|
|
" alt.X(\"num_bills:Q\"),\n",
|
|
" alt.Color(\"session_start_year:N\"),\n",
|
|
")\n",
|
|
"\n",
|
|
"# we're saving this one for later, so repeat the variable name to see it\n",
|
|
"by_year"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 34,
|
|
"id": "RGSE",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
"<style>\n",
|
|
" #altair-viz-95590e473fb24ba09fde2dc67ddfb3e8.vega-embed {\n",
|
|
" width: 100%;\n",
|
|
" display: flex;\n",
|
|
" }\n",
|
|
"\n",
|
|
" #altair-viz-95590e473fb24ba09fde2dc67ddfb3e8.vega-embed details,\n",
|
|
" #altair-viz-95590e473fb24ba09fde2dc67ddfb3e8.vega-embed details summary {\n",
|
|
" position: relative;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<div id=\"altair-viz-95590e473fb24ba09fde2dc67ddfb3e8\"></div>\n",
|
|
"<script type=\"text/javascript\">\n",
|
|
" var VEGA_DEBUG = (typeof VEGA_DEBUG == \"undefined\") ? {} : VEGA_DEBUG;\n",
|
|
" (function(spec, embedOpt){\n",
|
|
" let outputDiv = document.currentScript.previousElementSibling;\n",
|
|
" if (outputDiv.id !== \"altair-viz-95590e473fb24ba09fde2dc67ddfb3e8\") {\n",
|
|
" outputDiv = document.getElementById(\"altair-viz-95590e473fb24ba09fde2dc67ddfb3e8\");\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@5.20.1?noext\",\n",
|
|
" \"vega-embed\": \"https://cdn.jsdelivr.net/npm/vega-embed@6?noext\",\n",
|
|
" };\n",
|
|
"\n",
|
|
" function maybeLoadScript(lib, version) {\n",
|
|
" var key = `${lib.replace(\"-\", \"\")}_version`;\n",
|
|
" return (VEGA_DEBUG[key] == version) ?\n",
|
|
" Promise.resolve(paths[lib]) :\n",
|
|
" new Promise(function(resolve, reject) {\n",
|
|
" var s = document.createElement('script');\n",
|
|
" document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
|
|
" s.async = true;\n",
|
|
" s.onload = () => {\n",
|
|
" VEGA_DEBUG[key] = version;\n",
|
|
" return resolve(paths[lib]);\n",
|
|
" };\n",
|
|
" s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
|
|
" s.src = paths[lib];\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 {\n",
|
|
" maybeLoadScript(\"vega\", \"5\")\n",
|
|
" .then(() => maybeLoadScript(\"vega-lite\", \"5.20.1\"))\n",
|
|
" .then(() => maybeLoadScript(\"vega-embed\", \"6\"))\n",
|
|
" .catch(showError)\n",
|
|
" .then(() => displayChart(vegaEmbed));\n",
|
|
" }\n",
|
|
" })({\"config\": {\"view\": {\"continuousWidth\": 300, \"continuousHeight\": 300}}, \"data\": {\"name\": \"data-7819b1facf2e5fc9998dcf4cad0b99f8\"}, \"mark\": {\"type\": \"point\", \"shape\": \"wedge\"}, \"encoding\": {\"x\": {\"aggregate\": \"average\", \"field\": \"num_bills\", \"type\": \"quantitative\"}, \"y\": {\"field\": \"state\", \"type\": \"nominal\"}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.20.1.json\", \"datasets\": {\"data-7819b1facf2e5fc9998dcf4cad0b99f8\": [{\"state\": \"IL\", \"session_start_year\": 2017, \"num_bills\": 13616}, {\"state\": \"IL\", \"session_start_year\": 2019, \"num_bills\": 12760}, {\"state\": \"IL\", \"session_start_year\": 2021, \"num_bills\": 12847}, {\"state\": \"IL\", \"session_start_year\": 2023, \"num_bills\": 11951}, {\"state\": \"MI\", \"session_start_year\": 2017, \"num_bills\": 4818}, {\"state\": \"MI\", \"session_start_year\": 2019, \"num_bills\": 4450}, {\"state\": \"MI\", \"session_start_year\": 2021, \"num_bills\": 4520}, {\"state\": \"MI\", \"session_start_year\": 2023, \"num_bills\": 3424}, {\"state\": \"WI\", \"session_start_year\": 2017, \"num_bills\": 1820}, {\"state\": \"WI\", \"session_start_year\": 2019, \"num_bills\": 2264}, {\"state\": \"WI\", \"session_start_year\": 2021, \"num_bills\": 2618}, {\"state\": \"WI\", \"session_start_year\": 2023, \"num_bills\": 2656}]}}, {\"mode\": \"vega-lite\"});\n",
|
|
"</script>"
|
|
],
|
|
"text/plain": [
|
|
"alt.Chart(...)"
|
|
]
|
|
},
|
|
"execution_count": 34,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 4\n",
|
|
"# Here we make a different chart from the same base data \n",
|
|
"# by re-using our `chart` variable.\n",
|
|
"#\n",
|
|
"# We choose a different shape (parameters that don't need to vary can be passed into the mark_* functions)\n",
|
|
"# We also use an aggregate function average(num_bills)\n",
|
|
"\n",
|
|
"avgs = chart.mark_point(shape=\"wedge\").encode(\n",
|
|
" alt.Y(\"state:N\"),\n",
|
|
" alt.X(\"average(num_bills)\"),\n",
|
|
")\n",
|
|
"avgs"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 36,
|
|
"id": "Kclp",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
"<style>\n",
|
|
" #altair-viz-84be3b793e6b4ba5970b06e34046c01c.vega-embed {\n",
|
|
" width: 100%;\n",
|
|
" display: flex;\n",
|
|
" }\n",
|
|
"\n",
|
|
" #altair-viz-84be3b793e6b4ba5970b06e34046c01c.vega-embed details,\n",
|
|
" #altair-viz-84be3b793e6b4ba5970b06e34046c01c.vega-embed details summary {\n",
|
|
" position: relative;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<div id=\"altair-viz-84be3b793e6b4ba5970b06e34046c01c\"></div>\n",
|
|
"<script type=\"text/javascript\">\n",
|
|
" var VEGA_DEBUG = (typeof VEGA_DEBUG == \"undefined\") ? {} : VEGA_DEBUG;\n",
|
|
" (function(spec, embedOpt){\n",
|
|
" let outputDiv = document.currentScript.previousElementSibling;\n",
|
|
" if (outputDiv.id !== \"altair-viz-84be3b793e6b4ba5970b06e34046c01c\") {\n",
|
|
" outputDiv = document.getElementById(\"altair-viz-84be3b793e6b4ba5970b06e34046c01c\");\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@5.20.1?noext\",\n",
|
|
" \"vega-embed\": \"https://cdn.jsdelivr.net/npm/vega-embed@6?noext\",\n",
|
|
" };\n",
|
|
"\n",
|
|
" function maybeLoadScript(lib, version) {\n",
|
|
" var key = `${lib.replace(\"-\", \"\")}_version`;\n",
|
|
" return (VEGA_DEBUG[key] == version) ?\n",
|
|
" Promise.resolve(paths[lib]) :\n",
|
|
" new Promise(function(resolve, reject) {\n",
|
|
" var s = document.createElement('script');\n",
|
|
" document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
|
|
" s.async = true;\n",
|
|
" s.onload = () => {\n",
|
|
" VEGA_DEBUG[key] = version;\n",
|
|
" return resolve(paths[lib]);\n",
|
|
" };\n",
|
|
" s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
|
|
" s.src = paths[lib];\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 {\n",
|
|
" maybeLoadScript(\"vega\", \"5\")\n",
|
|
" .then(() => maybeLoadScript(\"vega-lite\", \"5.20.1\"))\n",
|
|
" .then(() => maybeLoadScript(\"vega-embed\", \"6\"))\n",
|
|
" .catch(showError)\n",
|
|
" .then(() => displayChart(vegaEmbed));\n",
|
|
" }\n",
|
|
" })({\"config\": {\"view\": {\"continuousWidth\": 300, \"continuousHeight\": 300}}, \"layer\": [{\"mark\": {\"type\": \"point\"}, \"encoding\": {\"color\": {\"field\": \"session_start_year\", \"type\": \"nominal\"}, \"x\": {\"field\": \"num_bills\", \"type\": \"quantitative\"}, \"y\": {\"field\": \"state\", \"type\": \"nominal\"}}}, {\"mark\": {\"type\": \"point\", \"shape\": \"wedge\"}, \"encoding\": {\"x\": {\"aggregate\": \"average\", \"field\": \"num_bills\", \"type\": \"quantitative\"}, \"y\": {\"field\": \"state\", \"type\": \"nominal\"}}}], \"data\": {\"name\": \"data-7819b1facf2e5fc9998dcf4cad0b99f8\"}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.20.1.json\", \"datasets\": {\"data-7819b1facf2e5fc9998dcf4cad0b99f8\": [{\"state\": \"IL\", \"session_start_year\": 2017, \"num_bills\": 13616}, {\"state\": \"IL\", \"session_start_year\": 2019, \"num_bills\": 12760}, {\"state\": \"IL\", \"session_start_year\": 2021, \"num_bills\": 12847}, {\"state\": \"IL\", \"session_start_year\": 2023, \"num_bills\": 11951}, {\"state\": \"MI\", \"session_start_year\": 2017, \"num_bills\": 4818}, {\"state\": \"MI\", \"session_start_year\": 2019, \"num_bills\": 4450}, {\"state\": \"MI\", \"session_start_year\": 2021, \"num_bills\": 4520}, {\"state\": \"MI\", \"session_start_year\": 2023, \"num_bills\": 3424}, {\"state\": \"WI\", \"session_start_year\": 2017, \"num_bills\": 1820}, {\"state\": \"WI\", \"session_start_year\": 2019, \"num_bills\": 2264}, {\"state\": \"WI\", \"session_start_year\": 2021, \"num_bills\": 2618}, {\"state\": \"WI\", \"session_start_year\": 2023, \"num_bills\": 2656}]}}, {\"mode\": \"vega-lite\"});\n",
|
|
"</script>"
|
|
],
|
|
"text/plain": [
|
|
"alt.LayerChart(...)"
|
|
]
|
|
},
|
|
"execution_count": 36,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 5\n",
|
|
"# We can combine compatible charts by using `+` to layer them.\n",
|
|
"# There are other operators you'll encounter that allow placing charts side by side.\n",
|
|
"by_year + avgs"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 41,
|
|
"id": "Hstk",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
"<style>\n",
|
|
" #altair-viz-73b896755fac48a784ac7b5d2ae8c928.vega-embed {\n",
|
|
" width: 100%;\n",
|
|
" display: flex;\n",
|
|
" }\n",
|
|
"\n",
|
|
" #altair-viz-73b896755fac48a784ac7b5d2ae8c928.vega-embed details,\n",
|
|
" #altair-viz-73b896755fac48a784ac7b5d2ae8c928.vega-embed details summary {\n",
|
|
" position: relative;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<div id=\"altair-viz-73b896755fac48a784ac7b5d2ae8c928\"></div>\n",
|
|
"<script type=\"text/javascript\">\n",
|
|
" var VEGA_DEBUG = (typeof VEGA_DEBUG == \"undefined\") ? {} : VEGA_DEBUG;\n",
|
|
" (function(spec, embedOpt){\n",
|
|
" let outputDiv = document.currentScript.previousElementSibling;\n",
|
|
" if (outputDiv.id !== \"altair-viz-73b896755fac48a784ac7b5d2ae8c928\") {\n",
|
|
" outputDiv = document.getElementById(\"altair-viz-73b896755fac48a784ac7b5d2ae8c928\");\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@5.20.1?noext\",\n",
|
|
" \"vega-embed\": \"https://cdn.jsdelivr.net/npm/vega-embed@6?noext\",\n",
|
|
" };\n",
|
|
"\n",
|
|
" function maybeLoadScript(lib, version) {\n",
|
|
" var key = `${lib.replace(\"-\", \"\")}_version`;\n",
|
|
" return (VEGA_DEBUG[key] == version) ?\n",
|
|
" Promise.resolve(paths[lib]) :\n",
|
|
" new Promise(function(resolve, reject) {\n",
|
|
" var s = document.createElement('script');\n",
|
|
" document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
|
|
" s.async = true;\n",
|
|
" s.onload = () => {\n",
|
|
" VEGA_DEBUG[key] = version;\n",
|
|
" return resolve(paths[lib]);\n",
|
|
" };\n",
|
|
" s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
|
|
" s.src = paths[lib];\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 {\n",
|
|
" maybeLoadScript(\"vega\", \"5\")\n",
|
|
" .then(() => maybeLoadScript(\"vega-lite\", \"5.20.1\"))\n",
|
|
" .then(() => maybeLoadScript(\"vega-embed\", \"6\"))\n",
|
|
" .catch(showError)\n",
|
|
" .then(() => displayChart(vegaEmbed));\n",
|
|
" }\n",
|
|
" })({\"config\": {\"view\": {\"continuousWidth\": 300, \"continuousHeight\": 300}}, \"layer\": [{\"mark\": {\"type\": \"bar\", \"color\": \"#ccc\"}, \"encoding\": {\"x\": {\"aggregate\": \"average\", \"field\": \"num_bills\", \"type\": \"quantitative\"}, \"y\": {\"field\": \"state\", \"type\": \"nominal\"}}}, {\"mark\": {\"type\": \"point\"}, \"encoding\": {\"color\": {\"field\": \"session_start_year\", \"type\": \"nominal\"}, \"x\": {\"field\": \"num_bills\", \"type\": \"quantitative\"}, \"y\": {\"field\": \"state\", \"type\": \"nominal\"}}}], \"data\": {\"name\": \"data-7819b1facf2e5fc9998dcf4cad0b99f8\"}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.20.1.json\", \"datasets\": {\"data-7819b1facf2e5fc9998dcf4cad0b99f8\": [{\"state\": \"IL\", \"session_start_year\": 2017, \"num_bills\": 13616}, {\"state\": \"IL\", \"session_start_year\": 2019, \"num_bills\": 12760}, {\"state\": \"IL\", \"session_start_year\": 2021, \"num_bills\": 12847}, {\"state\": \"IL\", \"session_start_year\": 2023, \"num_bills\": 11951}, {\"state\": \"MI\", \"session_start_year\": 2017, \"num_bills\": 4818}, {\"state\": \"MI\", \"session_start_year\": 2019, \"num_bills\": 4450}, {\"state\": \"MI\", \"session_start_year\": 2021, \"num_bills\": 4520}, {\"state\": \"MI\", \"session_start_year\": 2023, \"num_bills\": 3424}, {\"state\": \"WI\", \"session_start_year\": 2017, \"num_bills\": 1820}, {\"state\": \"WI\", \"session_start_year\": 2019, \"num_bills\": 2264}, {\"state\": \"WI\", \"session_start_year\": 2021, \"num_bills\": 2618}, {\"state\": \"WI\", \"session_start_year\": 2023, \"num_bills\": 2656}]}}, {\"mode\": \"vega-lite\"});\n",
|
|
"</script>"
|
|
],
|
|
"text/plain": [
|
|
"alt.LayerChart(...)"
|
|
]
|
|
},
|
|
"execution_count": 41,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 6\n",
|
|
"# perhaps we don't want to use mark_point anymore, maybe a bar?\n",
|
|
"bar_avgs = chart.mark_bar(color=\"#ccc\").encode(\n",
|
|
" alt.Y(\"state\"),\n",
|
|
" alt.X(\"average(num_bills)\"),\n",
|
|
")\n",
|
|
"bar_avgs + by_year"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 42,
|
|
"id": "nWHF",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
"<style>\n",
|
|
" #altair-viz-0c92a68553c042fba9cde6540507b9cb.vega-embed {\n",
|
|
" width: 100%;\n",
|
|
" display: flex;\n",
|
|
" }\n",
|
|
"\n",
|
|
" #altair-viz-0c92a68553c042fba9cde6540507b9cb.vega-embed details,\n",
|
|
" #altair-viz-0c92a68553c042fba9cde6540507b9cb.vega-embed details summary {\n",
|
|
" position: relative;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<div id=\"altair-viz-0c92a68553c042fba9cde6540507b9cb\"></div>\n",
|
|
"<script type=\"text/javascript\">\n",
|
|
" var VEGA_DEBUG = (typeof VEGA_DEBUG == \"undefined\") ? {} : VEGA_DEBUG;\n",
|
|
" (function(spec, embedOpt){\n",
|
|
" let outputDiv = document.currentScript.previousElementSibling;\n",
|
|
" if (outputDiv.id !== \"altair-viz-0c92a68553c042fba9cde6540507b9cb\") {\n",
|
|
" outputDiv = document.getElementById(\"altair-viz-0c92a68553c042fba9cde6540507b9cb\");\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@5.20.1?noext\",\n",
|
|
" \"vega-embed\": \"https://cdn.jsdelivr.net/npm/vega-embed@6?noext\",\n",
|
|
" };\n",
|
|
"\n",
|
|
" function maybeLoadScript(lib, version) {\n",
|
|
" var key = `${lib.replace(\"-\", \"\")}_version`;\n",
|
|
" return (VEGA_DEBUG[key] == version) ?\n",
|
|
" Promise.resolve(paths[lib]) :\n",
|
|
" new Promise(function(resolve, reject) {\n",
|
|
" var s = document.createElement('script');\n",
|
|
" document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
|
|
" s.async = true;\n",
|
|
" s.onload = () => {\n",
|
|
" VEGA_DEBUG[key] = version;\n",
|
|
" return resolve(paths[lib]);\n",
|
|
" };\n",
|
|
" s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
|
|
" s.src = paths[lib];\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 {\n",
|
|
" maybeLoadScript(\"vega\", \"5\")\n",
|
|
" .then(() => maybeLoadScript(\"vega-lite\", \"5.20.1\"))\n",
|
|
" .then(() => maybeLoadScript(\"vega-embed\", \"6\"))\n",
|
|
" .catch(showError)\n",
|
|
" .then(() => displayChart(vegaEmbed));\n",
|
|
" }\n",
|
|
" })({\"config\": {\"view\": {\"continuousWidth\": 300, \"continuousHeight\": 300}}, \"layer\": [{\"mark\": {\"type\": \"point\", \"shape\": \"diamond\"}, \"encoding\": {\"color\": {\"field\": \"session_start_year\", \"title\": \"Session Year\", \"type\": \"nominal\"}, \"x\": {\"field\": \"num_bills\", \"type\": \"quantitative\"}, \"y\": {\"field\": \"state\", \"type\": \"nominal\"}}}, {\"mark\": {\"type\": \"bar\", \"color\": \"#70905050\"}, \"encoding\": {\"x\": {\"aggregate\": \"average\", \"field\": \"num_bills\", \"title\": \"Number of Bills Introduced\", \"type\": \"quantitative\"}, \"y\": {\"field\": \"state\", \"type\": \"nominal\"}}}], \"background\": \"#f5f5dc\", \"data\": {\"name\": \"data-7819b1facf2e5fc9998dcf4cad0b99f8\"}, \"title\": \"Midwest Bills by State\", \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.20.1.json\", \"datasets\": {\"data-7819b1facf2e5fc9998dcf4cad0b99f8\": [{\"state\": \"IL\", \"session_start_year\": 2017, \"num_bills\": 13616}, {\"state\": \"IL\", \"session_start_year\": 2019, \"num_bills\": 12760}, {\"state\": \"IL\", \"session_start_year\": 2021, \"num_bills\": 12847}, {\"state\": \"IL\", \"session_start_year\": 2023, \"num_bills\": 11951}, {\"state\": \"MI\", \"session_start_year\": 2017, \"num_bills\": 4818}, {\"state\": \"MI\", \"session_start_year\": 2019, \"num_bills\": 4450}, {\"state\": \"MI\", \"session_start_year\": 2021, \"num_bills\": 4520}, {\"state\": \"MI\", \"session_start_year\": 2023, \"num_bills\": 3424}, {\"state\": \"WI\", \"session_start_year\": 2017, \"num_bills\": 1820}, {\"state\": \"WI\", \"session_start_year\": 2019, \"num_bills\": 2264}, {\"state\": \"WI\", \"session_start_year\": 2021, \"num_bills\": 2618}, {\"state\": \"WI\", \"session_start_year\": 2023, \"num_bills\": 2656}]}}, {\"mode\": \"vega-lite\"});\n",
|
|
"</script>"
|
|
],
|
|
"text/plain": [
|
|
"alt.LayerChart(...)"
|
|
]
|
|
},
|
|
"execution_count": 42,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 7\n",
|
|
"# We can customize titles and other details by using `.title` and `.properties`\n",
|
|
"# the latter sets chart-wide properties.\n",
|
|
"\n",
|
|
"final = chart.mark_point(shape=\"diamond\").encode(\n",
|
|
" alt.Y(\"state:N\"),\n",
|
|
" alt.X(\"num_bills:Q\"),\n",
|
|
" alt.Color(\"session_start_year:N\").title(\"Session Year\"),\n",
|
|
") + chart.mark_bar(color=\"#70905050\").encode(\n",
|
|
" alt.Y(\"state\"),\n",
|
|
" alt.X(\"average(num_bills)\").title(\"Number of Bills Introduced\"),\n",
|
|
")\n",
|
|
"final.properties(\n",
|
|
" title='Midwest Bills by State',\n",
|
|
" background='#f5f5dc'\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "93b3a8bc-be56-452d-a443-7b4711e339cb",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Exercise\n",
|
|
"\n",
|
|
"Let's say we instead want to see if there are trends by year.\n",
|
|
"Try and create a new chart that:\n",
|
|
"- has year on X axis, and bills on Y\n",
|
|
"- is print & colorblind friendly (using multiple channels for encoding state)\n",
|
|
"- uses a custom color scale, not the default (to avoid confusion with the colors used in our earlier chart)\n",
|
|
"\n",
|
|
"Try completing this below, before continuing on to look at my version."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 43,
|
|
"id": "3506dd11-76ba-40b0-8e1f-2210dcd3defd",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# YOUR SOLUTION HERE"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "ZHCJ",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Altair User Guide / Next Steps\n",
|
|
"\n",
|
|
"See <https://capp30239.netlify.app/readings/> for details.\n",
|
|
"\n",
|
|
"You'll want to work your way through the recommended material at your own pace, which will help you learn the material much better than me reading library documentation to you would. :)\n",
|
|
"\n",
|
|
"**You aren't on your own**, we're here to help -- start with documentation and ask questions on Ed, in class, and in office hours.\n",
|
|
"\n",
|
|
"Once you've read the guide and worked through the assignment you will have the core ideas of Altair.\n",
|
|
"\n",
|
|
"The next steps towards mastery are using it a lot and asking questions to deepen understanding, *not leaning on GenAI too much*.\n",
|
|
"\n",
|
|
"You're reading a fairly small subset of the library's documentation. \n",
|
|
"The remaining sections are useful as reference, and as you use Altair you will find your way to them as you ask yourself questions like \"how do I work with geospatial data\" or \"how can I combine these axes\"?\n",
|
|
"\n",
|
|
"It's likely the most common thing you will use the documentation for is \"what arguments can I pass to this?\"\n",
|
|
"\n",
|
|
"For that, use the [API Reference](https://altair-viz.github.io/user_guide/api.html) and find the class you're working with.\n",
|
|
"\n",
|
|
"Example:\n",
|
|
"\n",
|
|
"- Let's say we want to adjust the color scheme, start with <https://altair-viz.github.io/user_guide/generated/channels/altair.Color.html>\n",
|
|
"- Note that it can take a scale, and click to <https://altair-viz.github.io/user_guide/generated/core/altair.Scale.html#altair.Scale>\n",
|
|
"- We find ourselves on Vega documentation, here <https://vega.github.io/vega-lite/docs/scale.html#scheme> before long. Vega documentation can be very helpful for understanding the options that are available, since Altair is an interface to those."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 54,
|
|
"id": "iLit",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
"<style>\n",
|
|
" #altair-viz-8d10ab61b28f4f6cbb22061c07d924ea.vega-embed {\n",
|
|
" width: 100%;\n",
|
|
" display: flex;\n",
|
|
" }\n",
|
|
"\n",
|
|
" #altair-viz-8d10ab61b28f4f6cbb22061c07d924ea.vega-embed details,\n",
|
|
" #altair-viz-8d10ab61b28f4f6cbb22061c07d924ea.vega-embed details summary {\n",
|
|
" position: relative;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<div id=\"altair-viz-8d10ab61b28f4f6cbb22061c07d924ea\"></div>\n",
|
|
"<script type=\"text/javascript\">\n",
|
|
" var VEGA_DEBUG = (typeof VEGA_DEBUG == \"undefined\") ? {} : VEGA_DEBUG;\n",
|
|
" (function(spec, embedOpt){\n",
|
|
" let outputDiv = document.currentScript.previousElementSibling;\n",
|
|
" if (outputDiv.id !== \"altair-viz-8d10ab61b28f4f6cbb22061c07d924ea\") {\n",
|
|
" outputDiv = document.getElementById(\"altair-viz-8d10ab61b28f4f6cbb22061c07d924ea\");\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@5.20.1?noext\",\n",
|
|
" \"vega-embed\": \"https://cdn.jsdelivr.net/npm/vega-embed@6?noext\",\n",
|
|
" };\n",
|
|
"\n",
|
|
" function maybeLoadScript(lib, version) {\n",
|
|
" var key = `${lib.replace(\"-\", \"\")}_version`;\n",
|
|
" return (VEGA_DEBUG[key] == version) ?\n",
|
|
" Promise.resolve(paths[lib]) :\n",
|
|
" new Promise(function(resolve, reject) {\n",
|
|
" var s = document.createElement('script');\n",
|
|
" document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
|
|
" s.async = true;\n",
|
|
" s.onload = () => {\n",
|
|
" VEGA_DEBUG[key] = version;\n",
|
|
" return resolve(paths[lib]);\n",
|
|
" };\n",
|
|
" s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
|
|
" s.src = paths[lib];\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 {\n",
|
|
" maybeLoadScript(\"vega\", \"5\")\n",
|
|
" .then(() => maybeLoadScript(\"vega-lite\", \"5.20.1\"))\n",
|
|
" .then(() => maybeLoadScript(\"vega-embed\", \"6\"))\n",
|
|
" .catch(showError)\n",
|
|
" .then(() => displayChart(vegaEmbed));\n",
|
|
" }\n",
|
|
" })({\"config\": {\"view\": {\"continuousWidth\": 300, \"continuousHeight\": 300}}, \"layer\": [{\"mark\": {\"type\": \"line\"}, \"encoding\": {\"color\": {\"field\": \"state\", \"scale\": {\"scheme\": \"set2\"}, \"type\": \"nominal\"}, \"x\": {\"field\": \"session_start_year\", \"type\": \"nominal\"}, \"y\": {\"field\": \"num_bills\", \"type\": \"quantitative\"}}}, {\"mark\": {\"type\": \"point\"}, \"encoding\": {\"color\": {\"field\": \"state\", \"scale\": {\"scheme\": \"set2\"}, \"type\": \"nominal\"}, \"shape\": {\"field\": \"state\", \"type\": \"nominal\"}, \"x\": {\"field\": \"session_start_year\", \"title\": \"Session Year\", \"type\": \"nominal\"}, \"y\": {\"field\": \"num_bills\", \"title\": \"Bills Introduced\", \"type\": \"quantitative\"}}, \"title\": \"Midwest Bills by Session\"}], \"data\": {\"name\": \"data-7819b1facf2e5fc9998dcf4cad0b99f8\"}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.20.1.json\", \"datasets\": {\"data-7819b1facf2e5fc9998dcf4cad0b99f8\": [{\"state\": \"IL\", \"session_start_year\": 2017, \"num_bills\": 13616}, {\"state\": \"IL\", \"session_start_year\": 2019, \"num_bills\": 12760}, {\"state\": \"IL\", \"session_start_year\": 2021, \"num_bills\": 12847}, {\"state\": \"IL\", \"session_start_year\": 2023, \"num_bills\": 11951}, {\"state\": \"MI\", \"session_start_year\": 2017, \"num_bills\": 4818}, {\"state\": \"MI\", \"session_start_year\": 2019, \"num_bills\": 4450}, {\"state\": \"MI\", \"session_start_year\": 2021, \"num_bills\": 4520}, {\"state\": \"MI\", \"session_start_year\": 2023, \"num_bills\": 3424}, {\"state\": \"WI\", \"session_start_year\": 2017, \"num_bills\": 1820}, {\"state\": \"WI\", \"session_start_year\": 2019, \"num_bills\": 2264}, {\"state\": \"WI\", \"session_start_year\": 2021, \"num_bills\": 2618}, {\"state\": \"WI\", \"session_start_year\": 2023, \"num_bills\": 2656}]}}, {\"mode\": \"vega-lite\"});\n",
|
|
"</script>"
|
|
],
|
|
"text/plain": [
|
|
"alt.LayerChart(...)"
|
|
]
|
|
},
|
|
"execution_count": 54,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"\n",
|
|
"# one possible solution to the exercise\n",
|
|
"\n",
|
|
"color_scheme = alt.Scale(scheme=\"set2\")\n",
|
|
"chart.mark_line().encode(\n",
|
|
" alt.Y(\"num_bills\"),\n",
|
|
" alt.X(\"session_start_year:N\"),\n",
|
|
" alt.Color(\"state\", scale=color_scheme),\n",
|
|
") + chart.mark_point().encode(\n",
|
|
" alt.Y(\"num_bills\").title(\"Bills Introduced\"),\n",
|
|
" alt.X(\"session_start_year:N\").title(\"Session Year\"),\n",
|
|
" alt.Color(\"state\", scale=color_scheme),\n",
|
|
" alt.Shape(\"state\"),\n",
|
|
").properties(\n",
|
|
" title='Midwest Bills by Session',\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "b4a63b04-c8b0-4406-933e-973708c151f6",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "e6ca4883-fea8-49ac-ad7c-23168c69a118",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.10.15"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|