diff --git a/docs/images/github-template-action-enable.png b/docs/images/github-template-action-enable.png deleted file mode 100644 index 8951744..0000000 Binary files a/docs/images/github-template-action-enable.png and /dev/null differ diff --git a/docs/images/github-template-action.png b/docs/images/github-template-action.png deleted file mode 100644 index 2738d51..0000000 Binary files a/docs/images/github-template-action.png and /dev/null differ diff --git a/docs/images/github-template-create.png b/docs/images/github-template-create.png deleted file mode 100644 index a2782ed..0000000 Binary files a/docs/images/github-template-create.png and /dev/null differ diff --git a/docs/images/github-template-pages.png b/docs/images/github-template-pages.png deleted file mode 100644 index 619f8ab..0000000 Binary files a/docs/images/github-template-pages.png and /dev/null differ diff --git a/docs/images/github-template.png b/docs/images/github-template.png deleted file mode 100644 index 9503f66..0000000 Binary files a/docs/images/github-template.png and /dev/null differ diff --git a/docs/images/logo.png b/docs/images/logo.png deleted file mode 100644 index 9c46884..0000000 Binary files a/docs/images/logo.png and /dev/null differ diff --git a/notebooks/nasa-apod.ipynb b/notebooks/nasa-apod.ipynb deleted file mode 100644 index da53534..0000000 --- a/notebooks/nasa-apod.ipynb +++ /dev/null @@ -1,283 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "90700fdc-fcc7-4e54-8c9e-449879d8c66d", - "metadata": { - "tags": [] - }, - "source": [ - "# Securely Using API Keys\n", - "\n", - "> The following are (opinionated) best practices to store and use API keys in your source code. If you disagree, please consider [contributing](https://github.com/worldbank/template/issues/new/choose). " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "ac0ed1c0", - "metadata": {}, - "source": [ - "## Environment Variables\n", - "\n", - "An [environment variable](https://en.wikipedia.org/wiki/Environment_variable) is a dynamic-named value that can be used to store information on a computer. For instance, an environment variable can be used to store settings and/or privileged information (e.g. API keys) on your local computer or server.\n", - "\n", - "To set a environment variable to a new value, in **Unix-like** systems, you must pass a `name` and a `value` pair as shown below in the terminal.\n", - "\n", - "```shell\n", - "export SECRET_API_KEY = \n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "080bd097-f128-4759-946d-793368230804", - "metadata": { - "tags": [] - }, - "source": [ - "The `value` is acessible by the `name` without being exposed throughout the sytem. In particular, in [Python](https://python.org), the value can be retrieve as follows." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "8d023b4e-496b-440c-91a7-199bceb44d7d", - "metadata": { - "tags": [] - }, - "source": [ - "```python\n", - "secret_api_key = os.getenv(\"SECRET_API_KEY\")\n", - "```" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "54a99582-d509-4ab8-be42-ddb4921c0f45", - "metadata": { - "tags": [] - }, - "source": [ - "Alternatively, it is customary to use a `.env` file to organize and load environments variables as needed. Packages such as [dotenv](https://www.npmjs.com/package/dotenv) and [python-dotenv](https://pypi.org/project/python-dotenv/) will automatically load environments variables for you from the `.env` file.\n", - "\n", - "```shell\n", - "source .env\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "3c0cc26a-2a99-49b0-a406-d57f31fff8ee", - "metadata": {}, - "source": [ - "With [Python](https://python.org)," - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "960398ce-eadb-45e3-b160-53e6c9250dd0", - "metadata": { - "tags": [ - "remove_output" - ] - }, - "outputs": [], - "source": [ - "from dotenv import load_dotenv\n", - "\n", - "load_dotenv()" - ] - }, - { - "cell_type": "markdown", - "id": "bda573d0-c877-42e6-8ee5-3000b780b4b7", - "metadata": { - "tags": [] - }, - "source": [ - "With [Jupyter](https://jupyter.org)," - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "2e700464-b50d-4b06-b0aa-afaafa17e68e", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "%load_ext dotenv\n", - "%dotenv" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "660db869", - "metadata": {}, - "source": [ - "The template includes `.env.example` as an example; to use, simply rename it to `.env` and add your settings and secrets to it. Please note that `.env` **must** never be commited/versioned (for example, to GitHub) and **should** ignored on `.gitignore`. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "74484f7e", - "metadata": {}, - "source": [ - "```{tip}\n", - "While environments variables are a convenient way to minimize the security risk, it is important to emphasize secrets are still stored in plaintext in your computer. It is strongly recommended to use instead a secret manager, such as [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) or [1Password](https://developer.1password.com/docs/cli/secret-references).\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "14e89727", - "metadata": {}, - "source": [ - "## Astronomy Picture of the Day" - ] - }, - { - "cell_type": "markdown", - "id": "b4c0f3e8-7756-41bb-aa21-cc2eee5ff67f", - "metadata": {}, - "source": [ - "One of the most popular APIs is NASA's [Astronomy Picture of the Day](https://apod.nasa.gov/apod/astropix.html). Let's see in the following example how to use the NASA API with a secret API key." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "d797ef77-6ca4-4f9d-a1f8-abbfd9884b07", - "metadata": { - "tags": [ - "hide-cell" - ] - }, - "outputs": [], - "source": [ - "import os\n", - "\n", - "import httpx\n", - "from IPython.core.display import HTML\n", - "from IPython.display import Image" - ] - }, - { - "cell_type": "markdown", - "id": "ece37244", - "metadata": {}, - "source": [ - "First, you will have to [generate your API key](https://api.nasa.gov) and set up the environment variable `NASA_API_KEY` with its value. Now you are ready to use it in your code. For instance, in this example, we assign it to `api_key`. Please note that the value is never exposed and the notebook can be securely shared with anyone. " - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "7b914e66-7ae8-4d8b-9621-d6dc5ec49631", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "api_key = os.getenv(\"NASA_API_KEY\")" - ] - }, - { - "cell_type": "markdown", - "id": "10b5b12a", - "metadata": {}, - "source": [ - "Now, we are ready to make the request to the NASA API. According to the [documentation](https://github.com/nasa/apod-api#docs), the `api_key` is passed a parameter to the GET request. " - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "1990c3b9-f145-4c1f-bbb5-82f50801a011", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "async with httpx.AsyncClient() as client:\n", - " r = await client.get(\n", - " \"https://api.nasa.gov/planetary/apod\", params={\"api_key\": api_key}\n", - " )" - ] - }, - { - "cell_type": "markdown", - "id": "e952e343", - "metadata": {}, - "source": [ - "Voilà!" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "bd1cb597-0144-43e8-bed8-12145a831a0c", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "Image(url=r.json()[\"hdurl\"])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8c7cb67e-c7ba-4ed3-bee0-36d303c1517d", - "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.6" - }, - "vscode": { - "interpreter": { - "hash": "ce6d896885f4e28373aa2ff7c44f136ed5a497e2abd203a79a632f5859ed7bb5" - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/world-bank-api.ipynb b/notebooks/world-bank-api.ipynb deleted file mode 100644 index 4b103ac..0000000 --- a/notebooks/world-bank-api.ipynb +++ /dev/null @@ -1,708 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "90700fdc-fcc7-4e54-8c9e-449879d8c66d", - "metadata": { - "tags": [] - }, - "source": [ - "# Indicators Example\n", - "\n", - "> The following is an example of a [Jupyter notebook](https://jupyter.org) - a tutorial of how to retrieve data from the [World Bank Indicators API](https://datahelpdesk.worldbank.org/knowledgebase/articles/889392-about-the-indicators-api-documentation) - that illustrates how to use computational content with the [template](https://worldbank.github.io/template). " - ] - }, - { - "cell_type": "markdown", - "id": "e0d992a6-f656-45ce-a025-f824901e8797", - "metadata": {}, - "source": [ - "## Requirements" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "1811080b-c4c6-43cb-9e46-5cfa65d54abf", - "metadata": {}, - "outputs": [], - "source": [ - "import itertools\n", - "\n", - "import bokeh\n", - "import pandas\n", - "import requests\n", - "from bokeh.palettes import Spectral6\n", - "from bokeh.plotting import figure, output_notebook, show" - ] - }, - { - "cell_type": "markdown", - "id": "fb8d2738-535e-4957-b82a-987891955a7f", - "metadata": {}, - "source": [ - "## Retrieve Data\n", - "\n", - "In this example, we retrieve **Population, total** (`SP.POP.TOTL`) from the [World Bank Indicators](https://data.worldbank.org/indicator) for [BRICS](https://infobrics.org)." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "c955864a-1889-4f7f-a29e-108b0534846b", - "metadata": {}, - "outputs": [], - "source": [ - "url = \"https://api.worldbank.org/v2/country/chn;bra;ind;rus;zaf/indicator/SP.POP.TOTL?format=json&per_page=10000\"" - ] - }, - { - "cell_type": "markdown", - "id": "6b5aac7c-bf80-4daa-a4a4-eebe8edc97bb", - "metadata": {}, - "source": [ - "Let's use [requests](https://requests.readthedocs.io) to send a GET request," - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "8d699f28-853a-40a1-8ea9-8dd566962454", - "metadata": {}, - "outputs": [], - "source": [ - "r = requests.get(url)" - ] - }, - { - "cell_type": "markdown", - "id": "a21cf193-ec13-45b8-9726-bb960ac8586a", - "metadata": {}, - "source": [ - "Now, let's normalize and create `pandas.DataFrame` from the response," - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "3dc152b2-95ba-473a-a416-2c4d5bac7622", - "metadata": {}, - "outputs": [], - "source": [ - "# normalize\n", - "data = pandas.json_normalize(r.json()[-1])\n", - "\n", - "# create dataframe\n", - "df = pandas.DataFrame.from_dict(data)" - ] - }, - { - "cell_type": "markdown", - "id": "241904c0-35b9-4e43-a3f9-f97738ea9fd1", - "metadata": {}, - "source": [ - "```{tip}\n", - "Alternatively, the World Bank API supports downloading the data as an [archive](http://api.worldbank.org/v2/country/all/indicator/SP.POP.TOTL?date=2000&source=2&downloadformat=csv). \n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "bae3462b-f49c-4b8a-badb-8f580b4fc268", - "metadata": {}, - "source": [ - "Let's take a look at the dataframe, " - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "c0bbef2d-495c-4140-b8ac-45ee47772142", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
countryiso3codeBRACHNINDRUSZAF
date
196073.092515667.070445.954579119.89700016.520441
196175.330008660.330456.351876121.23600016.989464
196277.599218665.770467.024193122.59100017.503133
196379.915555682.335477.933619123.96000018.042215
196482.262794698.355489.059309125.34500018.603097
..................
2017208.5049601396.2151354.195680144.49673956.641209
2018210.1665921402.7601369.003306144.47785957.339635
2019211.7828781407.7451383.112050144.40626158.087055
2020213.1963041411.1001396.387127144.07313958.801927
2021214.3262231412.3601407.563842143.44928659.392255
\n", - "

62 rows × 5 columns

\n", - "
" - ], - "text/plain": [ - "countryiso3code BRA CHN IND RUS ZAF\n", - "date \n", - "1960 73.092515 667.070 445.954579 119.897000 16.520441\n", - "1961 75.330008 660.330 456.351876 121.236000 16.989464\n", - "1962 77.599218 665.770 467.024193 122.591000 17.503133\n", - "1963 79.915555 682.335 477.933619 123.960000 18.042215\n", - "1964 82.262794 698.355 489.059309 125.345000 18.603097\n", - "... ... ... ... ... ...\n", - "2017 208.504960 1396.215 1354.195680 144.496739 56.641209\n", - "2018 210.166592 1402.760 1369.003306 144.477859 57.339635\n", - "2019 211.782878 1407.745 1383.112050 144.406261 58.087055\n", - "2020 213.196304 1411.100 1396.387127 144.073139 58.801927\n", - "2021 214.326223 1412.360 1407.563842 143.449286 59.392255\n", - "\n", - "[62 rows x 5 columns]" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df = df.pivot_table(values=\"value\", index=\"date\", columns=\"countryiso3code\")\n", - "df = df / 1e6 # scaling\n", - "df" - ] - }, - { - "cell_type": "markdown", - "id": "27f26a03-6d7a-4c86-8a02-1ea341d7ac5b", - "metadata": {}, - "source": [ - "## Visualization" - ] - }, - { - "cell_type": "markdown", - "id": "38e8582b-2a51-4908-8356-76cb6158fdc3", - "metadata": {}, - "source": [ - "Let's now plot the data as a time series using [Bokeh](https://docs.bokeh.org)." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "78041d94-56a6-43ff-a307-8e8a3b377858", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - " \n", - " Loading BokehJS ...\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " const force = true;\n", - "\n", - " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - "const JS_MIME_TYPE = 'application/javascript';\n", - " const HTML_MIME_TYPE = 'text/html';\n", - " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", - " const CLASS_NAME = 'output_bokeh rendered_html';\n", - "\n", - " /**\n", - " * Render data to the DOM node\n", - " */\n", - " function render(props, node) {\n", - " const script = document.createElement(\"script\");\n", - " node.appendChild(script);\n", - " }\n", - "\n", - " /**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - " function handleClearOutput(event, handle) {\n", - " const cell = handle.cell;\n", - "\n", - " const id = cell.output_area._bokeh_element_id;\n", - " const server_id = cell.output_area._bokeh_server_id;\n", - " // Clean up Bokeh references\n", - " if (id != null && id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - "\n", - " if (server_id !== undefined) {\n", - " // Clean up Bokeh references\n", - " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", - " cell.notebook.kernel.execute(cmd_clean, {\n", - " iopub: {\n", - " output: function(msg) {\n", - " const id = msg.content.text.trim();\n", - " if (id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - " }\n", - " }\n", - " });\n", - " // Destroy server and session\n", - " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", - " cell.notebook.kernel.execute(cmd_destroy);\n", - " }\n", - " }\n", - "\n", - " /**\n", - " * Handle when a new output is added\n", - " */\n", - " function handleAddOutput(event, handle) {\n", - " const output_area = handle.output_area;\n", - " const output = handle.output;\n", - "\n", - " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", - " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - "\n", - " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - "\n", - " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", - " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", - " // store reference to embed id on output_area\n", - " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " }\n", - " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " const bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " const script_attrs = bk_div.children[0].attributes;\n", - " for (let i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - " }\n", - "\n", - " function register_renderer(events, OutputArea) {\n", - "\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " const toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[toinsert.length - 1]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " /* Handle when an output is cleared or removed */\n", - " events.on('clear_output.CodeCell', handleClearOutput);\n", - " events.on('delete.Cell', handleClearOutput);\n", - "\n", - " /* Handle when a new output is added */\n", - " events.on('output_added.OutputArea', handleAddOutput);\n", - "\n", - " /**\n", - " * Register the mime type and append_mime function with output_area\n", - " */\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " /* Is output safe? */\n", - " safe: true,\n", - " /* Index of renderer in `output_area.display_order` */\n", - " index: 0\n", - " });\n", - " }\n", - "\n", - " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", - " if (root.Jupyter !== undefined) {\n", - " const events = require('base/js/events');\n", - " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", - "\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " }\n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " const NB_LOAD_WARNING = {'data': {'text/html':\n", - " \"
\\n\"+\n", - " \"

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

\\n\"+\n", - " \"
    \\n\"+\n", - " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", - " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", - " \"
\\n\"+\n", - " \"\\n\"+\n", - " \"from bokeh.resources import INLINE\\n\"+\n", - " \"output_notebook(resources=INLINE)\\n\"+\n", - " \"\\n\"+\n", - " \"
\"}};\n", - "\n", - " function display_loaded() {\n", - " const el = document.getElementById(\"1002\");\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS is loading...\";\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(display_loaded, 100)\n", - " }\n", - " }\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls == null || js_urls.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - "\n", - " function on_error(url) {\n", - " console.error(\"failed to load \" + url);\n", - " }\n", - "\n", - " for (let i = 0; i < css_urls.length; i++) {\n", - " const url = css_urls[i];\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error.bind(null, url);\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " for (let i = 0; i < js_urls.length; i++) {\n", - " const url = js_urls[i];\n", - " const element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error.bind(null, url);\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " };\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n", - " const css_urls = [];\n", - "\n", - " const inline_js = [ function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - "function(Bokeh) {\n", - " }\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " if (root.Bokeh !== undefined || force === true) {\n", - " for (let i = 0; i < inline_js.length; i++) {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " }\n", - "if (force === true) {\n", - " display_loaded();\n", - " }} else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " } else if (force !== true) {\n", - " const cell = $(document.getElementById(\"1002\")).parents('.cell').data().cell;\n", - " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", - " }\n", - " }\n", - "\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", - " run_inline_js();\n", - " } else {\n", - " load_libs(css_urls, js_urls, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - "}(window));" - ], - "application/vnd.bokehjs_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

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

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(\"1002\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\nif (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(\"1002\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function embed_document(root) {\n", - " const docs_json = {\"76a88bd2-d1e2-4b96-a4aa-feed715948c8\":{\"defs\":[],\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"1014\"}],\"center\":[{\"id\":\"1017\"},{\"id\":\"1021\"},{\"id\":\"1052\"}],\"left\":[{\"id\":\"1018\"}],\"renderers\":[{\"id\":\"1040\"},{\"id\":\"1058\"},{\"id\":\"1077\"},{\"id\":\"1098\"},{\"id\":\"1121\"}],\"title\":{\"id\":\"1004\"},\"toolbar\":{\"id\":\"1029\"},\"width\":700,\"x_range\":{\"id\":\"1006\"},\"x_scale\":{\"id\":\"1010\"},\"y_range\":{\"id\":\"1008\"},\"y_scale\":{\"id\":\"1012\"}},\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"1006\",\"type\":\"DataRange1d\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#fc8d59\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1119\",\"type\":\"Line\"},{\"attributes\":{\"line_color\":\"#fc8d59\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1118\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1008\",\"type\":\"DataRange1d\"},{\"attributes\":{},\"id\":\"1091\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1114\",\"type\":\"Selection\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"Population, total (World Bank)\",\"text_font_size\":\"12pt\"},\"id\":\"1004\",\"type\":\"Title\"},{\"attributes\":{},\"id\":\"1044\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1022\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1027\",\"type\":\"HelpTool\"},{\"attributes\":{},\"id\":\"1012\",\"type\":\"LinearScale\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1028\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"axis\":{\"id\":\"1018\"},\"coordinates\":null,\"dimension\":1,\"group\":null,\"ticker\":null},\"id\":\"1021\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1019\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1138\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"label\":{\"value\":\"BRA\"},\"renderers\":[{\"id\":\"1040\"}]},\"id\":\"1053\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1023\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"data\":{\"x\":[\"1960\",\"1961\",\"1962\",\"1963\",\"1964\",\"1965\",\"1966\",\"1967\",\"1968\",\"1969\",\"1970\",\"1971\",\"1972\",\"1973\",\"1974\",\"1975\",\"1976\",\"1977\",\"1978\",\"1979\",\"1980\",\"1981\",\"1982\",\"1983\",\"1984\",\"1985\",\"1986\",\"1987\",\"1988\",\"1989\",\"1990\",\"1991\",\"1992\",\"1993\",\"1994\",\"1995\",\"1996\",\"1997\",\"1998\",\"1999\",\"2000\",\"2001\",\"2002\",\"2003\",\"2004\",\"2005\",\"2006\",\"2007\",\"2008\",\"2009\",\"2010\",\"2011\",\"2012\",\"2013\",\"2014\",\"2015\",\"2016\",\"2017\",\"2018\",\"2019\",\"2020\",\"2021\"],\"y\":{\"__ndarray__\":\"w/UoXI/YhEBxPQrXo6KEQFyPwvUozoRASOF6FK5ShUCkcD0K19KFQBSuR+F6WYZAMzMzMzP7hkBmZmZmZpSHQK5H4XoUNIhAMzMzMzPgiEDsUbgehZKJQKRwPQrXSIpACtejcD3wikDsUbgehY+LQM3MzMzMIoxAXI/C9SijjEAUrkfhehWNQHE9Cteje41AuB6F61HhjUDXo3A9CkiOQHsUrkfhqY5ArkfhehQPj0DXo3A9CoWPQBSuR+F6+o9AzczMzEwzkEBcj8L1KGyQQFyPwvUoq5BAcT0K1yPwkEDsUbgehTaRQJqZmZmZepFACtejcL28kUCF61G4HvuRQHsUrkfhM5JA9ihcj8JpkkCkcD0KV5+SQFK4HoVr05JAMzMzMzMGk0DNzMzMTDiTQArXo3C9Z5NAPQrXo/CSk0CuR+F6lLqTQGZmZmZm35NAmpmZmZkBlECamZmZmSGUQM3MzMxMQJRAexSuR+FelECuR+F6FHyUQNejcD2Kl5RAhetRuJ6ylEDXo3A9Cs2UQLgehevR5pRAcT0K1yMElUD2KFyPwiiVQClcj8L1TJVAPQrXo3BvlUA9CtejcI+VQFyPwvUor5VAj8L1KNzQlUDXo3A9CuuVQBSuR+H6/pVAZmZmZmYMlkA9CtejcBGWQA==\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[62]}},\"selected\":{\"id\":\"1070\"},\"selection_policy\":{\"id\":\"1069\"}},\"id\":\"1054\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"axis\":{\"id\":\"1014\"},\"coordinates\":null,\"group\":null,\"ticker\":null},\"id\":\"1017\",\"type\":\"Grid\"},{\"attributes\":{\"line_color\":\"#99d594\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1055\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1025\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"1139\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1010\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1015\",\"type\":\"BasicTicker\"},{\"attributes\":{\"overlay\":{\"id\":\"1028\"}},\"id\":\"1024\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"axis_label\":\"Year\",\"coordinates\":null,\"formatter\":{\"id\":\"1047\"},\"group\":null,\"major_label_policy\":{\"id\":\"1048\"},\"ticker\":{\"id\":\"1015\"}},\"id\":\"1014\",\"type\":\"LinearAxis\"},{\"attributes\":{\"source\":{\"id\":\"1054\"}},\"id\":\"1059\",\"type\":\"CDSView\"},{\"attributes\":{\"click_policy\":\"mute\",\"coordinates\":null,\"group\":null,\"items\":[{\"id\":\"1053\"},{\"id\":\"1072\"},{\"id\":\"1093\"},{\"id\":\"1116\"},{\"id\":\"1141\"}],\"location\":\"right\"},\"id\":\"1052\",\"type\":\"Legend\"},{\"attributes\":{\"tools\":[{\"id\":\"1022\"},{\"id\":\"1023\"},{\"id\":\"1024\"},{\"id\":\"1025\"},{\"id\":\"1026\"},{\"id\":\"1027\"}]},\"id\":\"1029\",\"type\":\"Toolbar\"},{\"attributes\":{\"axis_label\":\"Population, total (in millions)\",\"coordinates\":null,\"formatter\":{\"id\":\"1044\"},\"group\":null,\"major_label_policy\":{\"id\":\"1045\"},\"ticker\":{\"id\":\"1019\"}},\"id\":\"1018\",\"type\":\"LinearAxis\"},{\"attributes\":{\"line_color\":\"#3288bd\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1037\",\"type\":\"Line\"},{\"attributes\":{\"data\":{\"x\":[\"1960\",\"1961\",\"1962\",\"1963\",\"1964\",\"1965\",\"1966\",\"1967\",\"1968\",\"1969\",\"1970\",\"1971\",\"1972\",\"1973\",\"1974\",\"1975\",\"1976\",\"1977\",\"1978\",\"1979\",\"1980\",\"1981\",\"1982\",\"1983\",\"1984\",\"1985\",\"1986\",\"1987\",\"1988\",\"1989\",\"1990\",\"1991\",\"1992\",\"1993\",\"1994\",\"1995\",\"1996\",\"1997\",\"1998\",\"1999\",\"2000\",\"2001\",\"2002\",\"2003\",\"2004\",\"2005\",\"2006\",\"2007\",\"2008\",\"2009\",\"2010\",\"2011\",\"2012\",\"2013\",\"2014\",\"2015\",\"2016\",\"2017\",\"2018\",\"2019\",\"2020\",\"2021\"],\"y\":{\"__ndarray__\":\"LSeh9EXfe0D1g7pIoYV8QK38MhhjMH1Ayv55GvDefUC8df7t8pB+QNumeFzUQX9AQgddwuHvf0Aqj26E5U+AQMmutIx0q4BAQni0cYQKgUCeQxmqAmyBQBAHCVH+z4FAcy8wK7Q2gkACDwwg3KCCQITyPo7GDYNAiSe7mTF8g0DC3sSQnOuDQMZpiCp8XYRAatlaXyTShEAP7zmw/EmFQPqbUIigxoVA04OCUvRGhkBGfv0QW8mGQB41JsScTodAjIaMRynXh0AUd7zJ72GIQE5jey0I74hAyXa+n7p9iUAa/P1i1g2KQFZETfQZoIpAK/uuCJ4zi0B/pl63iMeLQGmKAKeXXIxAdzHNdM/yjEBol299GIqNQOwy/Kc7Io5AXwg57z+6jkAb9RCNrlKPQANd+wJ6649A8OAnDgBCkEAsZRniiI6QQNTRcTXi25BAfa1LjUApkUBF8wAWqXWRQE+Q2O4OwZFAH9rHCo4KkkCNDkjCflGSQFAYlGnElpJAnuv7cPDakkDUYBqGjx6TQLAgzVh0YpNAR1Z+GXymk0B8LH3o8umTQAzohTuHLJRArvTabPxslEBIMxZNd6uUQIyEtpyL6pRA7YFWYMgolUCG56ViA2SVQBE2PL1ynJVAmDEFa4zRlUByGMxfQf6VQA==\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[62]}},\"selected\":{\"id\":\"1091\"},\"selection_policy\":{\"id\":\"1090\"}},\"id\":\"1073\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1054\"},\"glyph\":{\"id\":\"1055\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1057\"},\"nonselection_glyph\":{\"id\":\"1056\"},\"view\":{\"id\":\"1059\"}},\"id\":\"1058\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#fc8d59\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1120\",\"type\":\"Line\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#99d594\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1057\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1026\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"1069\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"data\":{\"x\":[\"1960\",\"1961\",\"1962\",\"1963\",\"1964\",\"1965\",\"1966\",\"1967\",\"1968\",\"1969\",\"1970\",\"1971\",\"1972\",\"1973\",\"1974\",\"1975\",\"1976\",\"1977\",\"1978\",\"1979\",\"1980\",\"1981\",\"1982\",\"1983\",\"1984\",\"1985\",\"1986\",\"1987\",\"1988\",\"1989\",\"1990\",\"1991\",\"1992\",\"1993\",\"1994\",\"1995\",\"1996\",\"1997\",\"1998\",\"1999\",\"2000\",\"2001\",\"2002\",\"2003\",\"2004\",\"2005\",\"2006\",\"2007\",\"2008\",\"2009\",\"2010\",\"2011\",\"2012\",\"2013\",\"2014\",\"2015\",\"2016\",\"2017\",\"2018\",\"2019\",\"2020\",\"2021\"],\"y\":{\"__ndarray__\":\"7dgIxOtFUkDH2t/ZHtVSQCtLdJZZZlNAHaz/c5j6U0Bx5eyd0ZBUQJl+iXjrJ1VA16Gakqy+VUAdzCbAsFRWQDSBIhYx6lZAjKIHPgaAV0DpJjEIrBdYQE7U0twKsVhAeSKI83BMWUCVZB2OrupZQAiRDDm2ilpA4NbdPNUsW0AVi98UVtJbQPj9mxcnfFxARYMUPIUqXUDGGcOcoNxdQDtu+N10kl5AAvG6fsFKX0BDBBxCFQJgQO5Cc51GX2BAFNBE2HC8YEAz3IDPDxlhQPuWOV2WdGFAq+l6ouvOYUAlIvyLIChiQEuuYvEbgGJAe0ykNJvWYkDj/E0oxCpjQAvSjEXTfGNA+FPjpRvOY0CZ1NAGYB9kQNJWJZF9cGRAyv55GjDBZEDRr62ffhFlQADICRNGYWVAUfUrnY+vZUCOO6WD9ftlQJq0qbrHRmZAza/mAEGPZkD0wp0LI9RmQMnp6/kaF2dApb+XwoNZZ0BPzeUGQ5pnQJz4akfx2GdAb/HwnoMVaEB7ouvCj1BoQLlsdM5Pi2hARbx1/u3FaEBAwjBgSf9oQKCKG7cYN2lAaLPqc7VuaUAz/n3GBaZpQI7LuKmB22lAObnfoSgQakDP+L64VEVqQEHYKVYNeWpAXoJTH0imakB/hjdrcMpqQA==\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[62]}},\"selected\":{\"id\":\"1050\"},\"selection_policy\":{\"id\":\"1049\"}},\"id\":\"1036\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"label\":{\"value\":\"CHN\"},\"renderers\":[{\"id\":\"1058\"}]},\"id\":\"1072\",\"type\":\"LegendItem\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#99d594\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1056\",\"type\":\"Line\"},{\"attributes\":{\"line_color\":\"#e6f598\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1074\",\"type\":\"Line\"},{\"attributes\":{\"source\":{\"id\":\"1073\"}},\"id\":\"1078\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1050\",\"type\":\"Selection\"},{\"attributes\":{\"data\":{\"x\":[\"1960\",\"1961\",\"1962\",\"1963\",\"1964\",\"1965\",\"1966\",\"1967\",\"1968\",\"1969\",\"1970\",\"1971\",\"1972\",\"1973\",\"1974\",\"1975\",\"1976\",\"1977\",\"1978\",\"1979\",\"1980\",\"1981\",\"1982\",\"1983\",\"1984\",\"1985\",\"1986\",\"1987\",\"1988\",\"1989\",\"1990\",\"1991\",\"1992\",\"1993\",\"1994\",\"1995\",\"1996\",\"1997\",\"1998\",\"1999\",\"2000\",\"2001\",\"2002\",\"2003\",\"2004\",\"2005\",\"2006\",\"2007\",\"2008\",\"2009\",\"2010\",\"2011\",\"2012\",\"2013\",\"2014\",\"2015\",\"2016\",\"2017\",\"2018\",\"2019\",\"2020\",\"2021\"],\"y\":{\"__ndarray__\":\"xSCwcmj5XUDJdr6fGk9eQOf7qfHSpV5APQrXo3D9XkCuR+F6FFZfQEjhehSur19Ay6FFtvPdX0CDwMqhRQZgQARWDi2yHWBAaJHtfD81YECwcmiR7UxgQClcj8L1ZGBADAIrhxZ9YEDFILByaJVgQOf7qfHSrWBAZmZmZmbGYEBiEFg5tORgQDMzMzMzA2FAUrgeheshYUC+nxov3UBhQLgehetRYGFAJzEIrBx+YUB1kxgEVpphQEw3iUFgtWFApHA9CtfXYUD6fmq8dPthQPhT46WbHGJAkxgEVg49YkCBlUOLbFtiQFCNl24Sd2JAbjDUYQV/YkDrcd9qnYxiQMU56ug4kWJABmUaTa6OYkCsdHedDY1iQGJodXIGjGJAhUTaxh+FYkAV4SajSn1iQMPVARB3dWJA5/7qcd9mYkDhXwSNGVNiQD/kLVc/P2JAT+rL0s4pYkAaM4l6wRRiQOxP4nMnAmJAn1bRH5rwYUB9dVWgluFhQKhxb37D2WFAMnVXdsHXYUBI3jmUIdlhQPTfg9cu22FA304iwr/eYUBTPZl/dOZhQIkHlE058GFAidNJtjr6YUDVPh2PGQNiQPSnjer0CmJAuvQvSeUPYkAtI/WeSg9iQH2UERcADWJA/aGZJ1cCYkCfkQiNYO5hQA==\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[62]}},\"selected\":{\"id\":\"1114\"},\"selection_policy\":{\"id\":\"1113\"}},\"id\":\"1094\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1073\"},\"glyph\":{\"id\":\"1074\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1076\"},\"nonselection_glyph\":{\"id\":\"1075\"},\"view\":{\"id\":\"1078\"}},\"id\":\"1077\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1045\",\"type\":\"AllLabels\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#e6f598\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1076\",\"type\":\"Line\"},{\"attributes\":{\"label\":{\"value\":\"RUS\"},\"renderers\":[{\"id\":\"1098\"}]},\"id\":\"1116\",\"type\":\"LegendItem\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#3288bd\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1038\",\"type\":\"Line\"},{\"attributes\":{\"source\":{\"id\":\"1117\"}},\"id\":\"1122\",\"type\":\"CDSView\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1094\"},\"glyph\":{\"id\":\"1095\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1097\"},\"nonselection_glyph\":{\"id\":\"1096\"},\"view\":{\"id\":\"1099\"}},\"id\":\"1098\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#3288bd\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1039\",\"type\":\"Line\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#e6f598\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1075\",\"type\":\"Line\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#fee08b\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1097\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1048\",\"type\":\"AllLabels\"},{\"attributes\":{\"line_color\":\"#fee08b\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1095\",\"type\":\"Line\"},{\"attributes\":{\"label\":{\"value\":\"IND\"},\"renderers\":[{\"id\":\"1077\"}]},\"id\":\"1093\",\"type\":\"LegendItem\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1117\"},\"glyph\":{\"id\":\"1118\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1120\"},\"nonselection_glyph\":{\"id\":\"1119\"},\"view\":{\"id\":\"1122\"}},\"id\":\"1121\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1049\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1070\",\"type\":\"Selection\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1036\"},\"glyph\":{\"id\":\"1037\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1039\"},\"nonselection_glyph\":{\"id\":\"1038\"},\"view\":{\"id\":\"1041\"}},\"id\":\"1040\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1047\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#fee08b\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1096\",\"type\":\"Line\"},{\"attributes\":{\"source\":{\"id\":\"1036\"}},\"id\":\"1041\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1090\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"data\":{\"x\":[\"1960\",\"1961\",\"1962\",\"1963\",\"1964\",\"1965\",\"1966\",\"1967\",\"1968\",\"1969\",\"1970\",\"1971\",\"1972\",\"1973\",\"1974\",\"1975\",\"1976\",\"1977\",\"1978\",\"1979\",\"1980\",\"1981\",\"1982\",\"1983\",\"1984\",\"1985\",\"1986\",\"1987\",\"1988\",\"1989\",\"1990\",\"1991\",\"1992\",\"1993\",\"1994\",\"1995\",\"1996\",\"1997\",\"1998\",\"1999\",\"2000\",\"2001\",\"2002\",\"2003\",\"2004\",\"2005\",\"2006\",\"2007\",\"2008\",\"2009\",\"2010\",\"2011\",\"2012\",\"2013\",\"2014\",\"2015\",\"2016\",\"2017\",\"2018\",\"2019\",\"2020\",\"2021\"],\"y\":{\"__ndarray__\":\"X38SnzuFMEDBkUCDTf0wQNKJBFPNgDFAkGYsms4KMkDTUKOQZJoyQOcBLPLrLzNAR1Sobi7KM0AqOLwgImk0QM0jfzDwDDVApmJjXke0NUCr61BNSV42QOjAcoQMCDdA7gbRWtGyN0B7Szlf7GE4QMxEEVK3EzlAIXcRpijHOUDQRNjw9Ho6QIB/SpUoMztAIZOMnIXxO0Cp2m6Cb7I8QPAXsyWrdj1AN1MhHok7PkDb39kevQU/QLtIoSx83T9Adcdim1RiQEBdiNUfYeBAQI+oUN1ccEFAsirCTUYPQkA7N23GabJCQOKt82+XVUNAsfm4NlTwQ0CZf/RNmnREQF6iemtg4URAUAEwnkFDRUBW9fI7TaJFQO+NIQA4/kVAvvc3aK9URkAm5e5zfKRGQK5hhsYT7UZAfTz03a0uR0BweawZGWhHQHi3skRnnUdATuyhfazUR0Brm+JxUQ1IQISgo1UtR0hAvRx23zGCSEBPzlDc8b5IQPTeGAKA/0hAmdcRh2xISUD76xUW3JVJQMh4lEp45ElA5j+k3744SkCe6/twkJJKQJShKqbS70pAzuFa7WFdS0AWaHdIMfBLQL75DRMNNkxAUHPyIhNSTEDayeAoeatMQAX6RJ4kC01Aw2M/i6VmTUCjWG5pNbJNQA==\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[62]}},\"selected\":{\"id\":\"1139\"},\"selection_policy\":{\"id\":\"1138\"}},\"id\":\"1117\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"label\":{\"value\":\"ZAF\"},\"renderers\":[{\"id\":\"1121\"}]},\"id\":\"1141\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1113\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"1094\"}},\"id\":\"1099\",\"type\":\"CDSView\"}],\"root_ids\":[\"1003\"]},\"title\":\"Bokeh Application\",\"version\":\"2.4.3\"}};\n", - " const render_items = [{\"docid\":\"76a88bd2-d1e2-4b96-a4aa-feed715948c8\",\"root_ids\":[\"1003\"],\"roots\":{\"1003\":\"4d4ccb98-b0a7-4ec4-9327-87b553eb7e33\"}}];\n", - " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " } else {\n", - " let attempts = 0;\n", - " const timer = setInterval(function(root) {\n", - " if (root.Bokeh !== undefined) {\n", - " clearInterval(timer);\n", - " embed_document(root);\n", - " } else {\n", - " attempts++;\n", - " if (attempts > 100) {\n", - " clearInterval(timer);\n", - " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", - " }\n", - " }\n", - " }, 10, root)\n", - " }\n", - "})(window);" - ], - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "1003" - } - }, - "output_type": "display_data" - } - ], - "source": [ - "output_notebook()\n", - "\n", - "p = figure(title=\"Population, total (World Bank)\", width=700, height=600)\n", - "\n", - "# colors\n", - "colors = itertools.cycle(Spectral6)\n", - "\n", - "# plotting the line graph\n", - "for column, color in zip(df.columns, colors):\n", - " p.line(\n", - " df.index,\n", - " df[column],\n", - " legend_label=column,\n", - " color=color,\n", - " line_width=2,\n", - " )\n", - "\n", - "p.legend.location = \"right\"\n", - "p.legend.click_policy = \"mute\"\n", - "p.title.text_font_size = \"12pt\"\n", - "\n", - "p.xaxis.axis_label = \"Year\"\n", - "p.yaxis.axis_label = \"Population, total (in millions)\"\n", - "\n", - "show(p)" - ] - } - ], - "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.10" - }, - "vscode": { - "interpreter": { - "hash": "b6702b69e93007336b96338c5a331192f07cedff01d36d4dcfa0f842adb718ad" - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/world-bank-package.ipynb b/notebooks/world-bank-package.ipynb deleted file mode 100644 index cdfcb67..0000000 --- a/notebooks/world-bank-package.ipynb +++ /dev/null @@ -1,813 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "90700fdc-fcc7-4e54-8c9e-449879d8c66d", - "metadata": { - "tags": [] - }, - "source": [ - "# Package Example\n", - "\n", - "> The following is an example of on how to use and distribute the source code of your project as a [Python package](https://packaging.python.org) using the template." - ] - }, - { - "cell_type": "markdown", - "id": "14e89727", - "metadata": {}, - "source": [ - "## Usage" - ] - }, - { - "cell_type": "markdown", - "id": "b4c0f3e8-7756-41bb-aa21-cc2eee5ff67f", - "metadata": {}, - "source": [ - "Unlike the [previous example](https://worldbank.github.io/template/notebooks/world-bank-api.html), where the source code was contained on the Jupyter notebok itself, we (re)use a Python package - the [datalab](https://github.com/worldbank/template/tree/main/src/datalab) Python package - which will let us (re)use any attributes and methods in the following example.\n", - "\n", - "Let's start by importing `WorldBankIndicatorsAPI`, a Pyhton API wrapper class created to faciliate the usage of the [World Bank Indicators API](https://datahelpdesk.worldbank.org/knowledgebase/articles/889392-about-the-indicators-api-documentation)." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "d797ef77-6ca4-4f9d-a1f8-abbfd9884b07", - "metadata": {}, - "outputs": [], - "source": [ - "from datalab.indicators import WorldBankIndicatorsAPI" - ] - }, - { - "cell_type": "markdown", - "id": "17f380e4-3854-4af6-940c-7afe9723a59a", - "metadata": {}, - "source": [ - "Let's continue by creating the API object. " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f911a5c3-6994-45a6-a049-4b398f5890c0", - "metadata": {}, - "outputs": [], - "source": [ - "api = WorldBankIndicatorsAPI()" - ] - }, - { - "cell_type": "markdown", - "id": "7fa96741-f4cd-4504-a5f8-6467f9a2345e", - "metadata": {}, - "source": [ - "The `api` wrapper object is now ready to use! We will invoke its `query` method to retrieve data from the [World Bank Indicators API](https://datahelpdesk.worldbank.org/knowledgebase/articles/889392-about-the-indicators-api-documentation). To learn how to use it, such as information about method signature, valid parameters and return value, we read `help`. Since [PEP 257](https://peps.python.org/pep-0257), Python offers *doctrings*, which are an easy and standard to create code documentation and it is a good practice adopt it. Documentating the source code is crucial to create a maintainable reliable and reproducicle code base and project.\n", - "\n", - "Let's see the `query` method's *docstring* as shown below." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "fb6ca314-d161-40e1-a376-a3013a0711eb", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Help on method query in module datalab.indicators:\n", - "\n", - "query(indicator, country: list = 'all', params: dict = {}) method of datalab.indicators.WorldBankIndicatorsAPI instance\n", - " Retrieve a response, valid JSON response or error, from the World Bank Indicators API.\n", - " \n", - " See also:\n", - " https://datahelpdesk.worldbank.org/knowledgebase/articles/889392-about-the-indicators-api-documentation\n", - " \n", - " Parameters\n", - " ----------\n", - " indicator : str\n", - " World Bank API Indicator.\n", - " country : list, optional\n", - " List of countries. The country name is converted to ISO 3166-1 alpha-3 country code.\n", - " params : dict, optional\n", - " World Bank API Indicator Query Strings.\n", - " \n", - " Returns\n", - " -------\n", - " pandas.core.frame.DataFrame\n", - " Return a Pandas DataFrame obtained with response data from World Bank Indicators API.\n", - "\n" - ] - } - ], - "source": [ - "help(api.query)" - ] - }, - { - "cell_type": "markdown", - "id": "e82fc342-165d-42d6-b3dc-7534c215ca1f", - "metadata": {}, - "source": [ - "The `query` method allows us to select an **indicator** (e.g, [World Development Indicators](https://datatopics.worldbank.org/world-development-indicators)), a list of countries and [query parameters](https://datahelpdesk.worldbank.org/knowledgebase/articles/898581#query-strings). Note that contrary to the [previous example](https://worldbank.github.io/template/notebooks/world-bank-api.html), the method expets a list of country names and converts them to [ISO 3166-1 alpha-3](https://www.iso.org/iso-3166-country-codes.html) automatically." - ] - }, - { - "cell_type": "markdown", - "id": "23b0a1eb-73c1-42e7-8903-98e362ef86de", - "metadata": {}, - "source": [ - "Let's invoke the `query` method and retrieve the results for `SP.POP.TOTL` for the [BRICS](https://infobrics.org) (as before)." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "7fb7daea-c5cf-42ea-b746-a565dd9ac4e1", - "metadata": {}, - "outputs": [], - "source": [ - "df = api.query(\n", - " \"SP.POP.TOTL\", country=[\"Brazil\", \"China\", \"India\", \"Russia\", \"South Africa\"]\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "46662c1b-4c19-424b-8a61-f651cb486c5b", - "metadata": {}, - "source": [ - "**Voilà!** We just (re)used the [datalab](https://github.com/worldbank/template/tree/main/src/datalab) Python package in our example delegating the maintenance and logic, making the notebook easier to understand and reproduce. \n", - "\n", - "```{tip}\n", - "In addition, the `template` makes any Python package automatically [pip installable](https://packaging.python.org/en/latest/tutorials/installing-packages/) and acessible to *anyone* and from *anywhere*!\n", - "\n", - "To install from source:\n", - "\n", - "\tpip install git+https://github.com/worldbank/template.git\n", - "\n", - "To install from version:\n", - "\n", - "\tpip install git+https://github.com/worldbank/template.git@v0.1.0\n", - "\t\n", - "\n", - "When distributing a project release, it is strongly recommended to adhere to release management good practices. It is recommended to create checklists, adopt versioning (e.g, [semantic versioning](https://semver.org/) and to release on [Python Package Index](https://pypi.org/) (instead of GitHub).\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "80887da5-0474-48b3-8c71-fbe3dbd3a8e8", - "metadata": {}, - "source": [ - "```{tip}\n", - "The template will automatically find and install any local `src` packages as long as the `setup.cfg` file is up-to-date.\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "daa4319a-8936-4195-b1fc-aad9c008325b", - "metadata": {}, - "source": [ - "```{caution}\n", - "The `datalab` Python package shoudl be used for demonstration purposes only. For support, please see the [World Bank Indicators API Documentation](https://datahelpdesk.worldbank.org/knowledgebase/articles/889392-about-the-indicators-api-documentation).\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "e9f14239", - "metadata": {}, - "source": [ - "Finally, let's take a look at the retrieved data." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "b1d7cf70-bf0e-4c12-ae0d-fd26349291db", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "df = df.pivot_table(values=\"value\", index=\"date\", columns=\"country.value\")" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "699a0495-4f06-479c-b517-58336110547f", - "metadata": { - "tags": [ - "output_scroll" - ] - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
country.valueBrazilChinaIndiaRussian FederationSouth Africa
date
19607309251566707000044595457911989700016520441
19617533000866033000045635187612123600016989464
19627759921866577000046702419312259100017503133
19637991555568233500047793361912396000018042215
19648226279469835500048905930912534500018603097
..................
20172085049601396215000135419568014449673956641209
20182101665921402760000136900330614447785957339635
20192117828781407745000138311205014440626158087055
20202131963041411100000139638712714407313958801927
20212143262231412360000140756384214344928659392255
\n", - "

62 rows × 5 columns

\n", - "
" - ], - "text/plain": [ - "country.value Brazil China India Russian Federation \\\n", - "date \n", - "1960 73092515 667070000 445954579 119897000 \n", - "1961 75330008 660330000 456351876 121236000 \n", - "1962 77599218 665770000 467024193 122591000 \n", - "1963 79915555 682335000 477933619 123960000 \n", - "1964 82262794 698355000 489059309 125345000 \n", - "... ... ... ... ... \n", - "2017 208504960 1396215000 1354195680 144496739 \n", - "2018 210166592 1402760000 1369003306 144477859 \n", - "2019 211782878 1407745000 1383112050 144406261 \n", - "2020 213196304 1411100000 1396387127 144073139 \n", - "2021 214326223 1412360000 1407563842 143449286 \n", - "\n", - "country.value South Africa \n", - "date \n", - "1960 16520441 \n", - "1961 16989464 \n", - "1962 17503133 \n", - "1963 18042215 \n", - "1964 18603097 \n", - "... ... \n", - "2017 56641209 \n", - "2018 57339635 \n", - "2019 58087055 \n", - "2020 58801927 \n", - "2021 59392255 \n", - "\n", - "[62 rows x 5 columns]" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "markdown", - "id": "c5daa85a-004d-4e93-be84-72d064d0b83b", - "metadata": {}, - "source": [ - "## Visualization\n", - "\n", - "As before, let's now plot the data as a time series using [Bokeh](https://docs.bokeh.org)." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "5d6be794-9e37-4ee2-94df-b40dff3ace6a", - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - " \n", - " Loading BokehJS ...\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " const force = true;\n", - "\n", - " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - "const JS_MIME_TYPE = 'application/javascript';\n", - " const HTML_MIME_TYPE = 'text/html';\n", - " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", - " const CLASS_NAME = 'output_bokeh rendered_html';\n", - "\n", - " /**\n", - " * Render data to the DOM node\n", - " */\n", - " function render(props, node) {\n", - " const script = document.createElement(\"script\");\n", - " node.appendChild(script);\n", - " }\n", - "\n", - " /**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - " function handleClearOutput(event, handle) {\n", - " const cell = handle.cell;\n", - "\n", - " const id = cell.output_area._bokeh_element_id;\n", - " const server_id = cell.output_area._bokeh_server_id;\n", - " // Clean up Bokeh references\n", - " if (id != null && id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - "\n", - " if (server_id !== undefined) {\n", - " // Clean up Bokeh references\n", - " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", - " cell.notebook.kernel.execute(cmd_clean, {\n", - " iopub: {\n", - " output: function(msg) {\n", - " const id = msg.content.text.trim();\n", - " if (id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - " }\n", - " }\n", - " });\n", - " // Destroy server and session\n", - " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", - " cell.notebook.kernel.execute(cmd_destroy);\n", - " }\n", - " }\n", - "\n", - " /**\n", - " * Handle when a new output is added\n", - " */\n", - " function handleAddOutput(event, handle) {\n", - " const output_area = handle.output_area;\n", - " const output = handle.output;\n", - "\n", - " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", - " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - "\n", - " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - "\n", - " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", - " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", - " // store reference to embed id on output_area\n", - " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " }\n", - " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " const bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " const script_attrs = bk_div.children[0].attributes;\n", - " for (let i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - " }\n", - "\n", - " function register_renderer(events, OutputArea) {\n", - "\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " const toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[toinsert.length - 1]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " /* Handle when an output is cleared or removed */\n", - " events.on('clear_output.CodeCell', handleClearOutput);\n", - " events.on('delete.Cell', handleClearOutput);\n", - "\n", - " /* Handle when a new output is added */\n", - " events.on('output_added.OutputArea', handleAddOutput);\n", - "\n", - " /**\n", - " * Register the mime type and append_mime function with output_area\n", - " */\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " /* Is output safe? */\n", - " safe: true,\n", - " /* Index of renderer in `output_area.display_order` */\n", - " index: 0\n", - " });\n", - " }\n", - "\n", - " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", - " if (root.Jupyter !== undefined) {\n", - " const events = require('base/js/events');\n", - " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", - "\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " }\n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " const NB_LOAD_WARNING = {'data': {'text/html':\n", - " \"
\\n\"+\n", - " \"

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

\\n\"+\n", - " \"
    \\n\"+\n", - " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", - " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", - " \"
\\n\"+\n", - " \"\\n\"+\n", - " \"from bokeh.resources import INLINE\\n\"+\n", - " \"output_notebook(resources=INLINE)\\n\"+\n", - " \"\\n\"+\n", - " \"
\"}};\n", - "\n", - " function display_loaded() {\n", - " const el = document.getElementById(\"1002\");\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS is loading...\";\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(display_loaded, 100)\n", - " }\n", - " }\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls == null || js_urls.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - "\n", - " function on_error(url) {\n", - " console.error(\"failed to load \" + url);\n", - " }\n", - "\n", - " for (let i = 0; i < css_urls.length; i++) {\n", - " const url = css_urls[i];\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error.bind(null, url);\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " for (let i = 0; i < js_urls.length; i++) {\n", - " const url = js_urls[i];\n", - " const element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error.bind(null, url);\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " };\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n", - " const css_urls = [];\n", - "\n", - " const inline_js = [ function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - "function(Bokeh) {\n", - " }\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " if (root.Bokeh !== undefined || force === true) {\n", - " for (let i = 0; i < inline_js.length; i++) {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " }\n", - "if (force === true) {\n", - " display_loaded();\n", - " }} else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " } else if (force !== true) {\n", - " const cell = $(document.getElementById(\"1002\")).parents('.cell').data().cell;\n", - " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", - " }\n", - " }\n", - "\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", - " run_inline_js();\n", - " } else {\n", - " load_libs(css_urls, js_urls, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - "}(window));" - ], - "application/vnd.bokehjs_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

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

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(\"1002\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\nif (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(\"1002\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function embed_document(root) {\n", - " const docs_json = {\"27a5602b-a100-49a8-be71-4c1a30cbf69c\":{\"defs\":[],\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"1014\"}],\"center\":[{\"id\":\"1017\"},{\"id\":\"1021\"},{\"id\":\"1052\"}],\"left\":[{\"id\":\"1018\"}],\"renderers\":[{\"id\":\"1040\"},{\"id\":\"1058\"},{\"id\":\"1077\"},{\"id\":\"1098\"},{\"id\":\"1121\"}],\"title\":{\"id\":\"1004\"},\"toolbar\":{\"id\":\"1029\"},\"width\":700,\"x_range\":{\"id\":\"1006\"},\"x_scale\":{\"id\":\"1010\"},\"y_range\":{\"id\":\"1008\"},\"y_scale\":{\"id\":\"1012\"}},\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#fc8d59\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1119\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1113\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"Population, total (World Bank)\",\"text_font_size\":\"12pt\"},\"id\":\"1004\",\"type\":\"Title\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#fee08b\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1097\",\"type\":\"Line\"},{\"attributes\":{\"axis\":{\"id\":\"1014\"},\"coordinates\":null,\"group\":null,\"ticker\":null},\"id\":\"1017\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1114\",\"type\":\"Selection\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1094\"},\"glyph\":{\"id\":\"1095\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1097\"},\"nonselection_glyph\":{\"id\":\"1096\"},\"view\":{\"id\":\"1099\"}},\"id\":\"1098\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#99d594\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1056\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1138\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"label\":{\"value\":\"Russian Federation\"},\"renderers\":[{\"id\":\"1098\"}]},\"id\":\"1116\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1139\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1027\",\"type\":\"HelpTool\"},{\"attributes\":{},\"id\":\"1070\",\"type\":\"Selection\"},{\"attributes\":{\"label\":{\"value\":\"Brazil\"},\"renderers\":[{\"id\":\"1040\"}]},\"id\":\"1053\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1069\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#99d594\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1057\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1090\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"axis\":{\"id\":\"1018\"},\"coordinates\":null,\"dimension\":1,\"group\":null,\"ticker\":null},\"id\":\"1021\",\"type\":\"Grid\"},{\"attributes\":{\"label\":{\"value\":\"South Africa\"},\"renderers\":[{\"id\":\"1121\"}]},\"id\":\"1141\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1019\",\"type\":\"BasicTicker\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#e6f598\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1075\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1023\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"tools\":[{\"id\":\"1022\"},{\"id\":\"1023\"},{\"id\":\"1024\"},{\"id\":\"1025\"},{\"id\":\"1026\"},{\"id\":\"1027\"}]},\"id\":\"1029\",\"type\":\"Toolbar\"},{\"attributes\":{\"line_color\":\"#99d594\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1055\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1022\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1045\",\"type\":\"AllLabels\"},{\"attributes\":{\"overlay\":{\"id\":\"1028\"}},\"id\":\"1024\",\"type\":\"BoxZoomTool\"},{\"attributes\":{},\"id\":\"1025\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"1026\",\"type\":\"ResetTool\"},{\"attributes\":{\"label\":{\"value\":\"India\"},\"renderers\":[{\"id\":\"1077\"}]},\"id\":\"1093\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1047\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"data\":{\"x\":[\"1960\",\"1961\",\"1962\",\"1963\",\"1964\",\"1965\",\"1966\",\"1967\",\"1968\",\"1969\",\"1970\",\"1971\",\"1972\",\"1973\",\"1974\",\"1975\",\"1976\",\"1977\",\"1978\",\"1979\",\"1980\",\"1981\",\"1982\",\"1983\",\"1984\",\"1985\",\"1986\",\"1987\",\"1988\",\"1989\",\"1990\",\"1991\",\"1992\",\"1993\",\"1994\",\"1995\",\"1996\",\"1997\",\"1998\",\"1999\",\"2000\",\"2001\",\"2002\",\"2003\",\"2004\",\"2005\",\"2006\",\"2007\",\"2008\",\"2009\",\"2010\",\"2011\",\"2012\",\"2013\",\"2014\",\"2015\",\"2016\",\"2017\",\"2018\",\"2019\",\"2020\",\"2021\"],\"y\":[119897000,121236000,122591000,123960000,125345000,126745000,127468000,128196000,128928000,129664000,130404000,131155000,131909000,132669000,133432000,134200000,135147000,136100000,137060000,138027000,139010000,139941000,140823000,141668000,142745000,143858000,144894000,145908000,146857000,147721000,147969407,148394216,148538197,148458777,148407912,148375787,148160129,147915361,147670784,147214776,146596869,145976482,145306497,144648618,144067316,143518814,143049637,142805114,142742366,142785349,142849468,142960908,143201721,143506995,143819667,144096870,144342397,144496739,144477859,144406261,144073139,143449286]},\"selected\":{\"id\":\"1114\"},\"selection_policy\":{\"id\":\"1113\"}},\"id\":\"1094\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1049\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"1073\"}},\"id\":\"1078\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1050\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1091\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1048\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1044\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#e6f598\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1076\",\"type\":\"Line\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1028\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"source\":{\"id\":\"1054\"}},\"id\":\"1059\",\"type\":\"CDSView\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#fee08b\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1096\",\"type\":\"Line\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1073\"},\"glyph\":{\"id\":\"1074\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1076\"},\"nonselection_glyph\":{\"id\":\"1075\"},\"view\":{\"id\":\"1078\"}},\"id\":\"1077\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data\":{\"x\":[\"1960\",\"1961\",\"1962\",\"1963\",\"1964\",\"1965\",\"1966\",\"1967\",\"1968\",\"1969\",\"1970\",\"1971\",\"1972\",\"1973\",\"1974\",\"1975\",\"1976\",\"1977\",\"1978\",\"1979\",\"1980\",\"1981\",\"1982\",\"1983\",\"1984\",\"1985\",\"1986\",\"1987\",\"1988\",\"1989\",\"1990\",\"1991\",\"1992\",\"1993\",\"1994\",\"1995\",\"1996\",\"1997\",\"1998\",\"1999\",\"2000\",\"2001\",\"2002\",\"2003\",\"2004\",\"2005\",\"2006\",\"2007\",\"2008\",\"2009\",\"2010\",\"2011\",\"2012\",\"2013\",\"2014\",\"2015\",\"2016\",\"2017\",\"2018\",\"2019\",\"2020\",\"2021\"],\"y\":[16520441,16989464,17503133,18042215,18603097,19187194,19789771,20410677,21050540,21704214,22368306,23031441,23698507,24382513,25077016,25777964,26480300,27199838,27943445,28697014,29463549,30232561,31022417,31865176,32768207,33752964,34877834,36119333,37393853,38668684,39877570,40910959,41760755,42525440,43267982,43986084,44661603,45285048,45852166,46364681,46813266,47229714,47661514,48104048,48556071,49017147,49491756,49996094,50565812,51170779,51784921,52443325,53145033,53873616,54729551,55876504,56422274,56641209,57339635,58087055,58801927,59392255]},\"selected\":{\"id\":\"1139\"},\"selection_policy\":{\"id\":\"1138\"}},\"id\":\"1117\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"source\":{\"id\":\"1094\"}},\"id\":\"1099\",\"type\":\"CDSView\"},{\"attributes\":{\"line_color\":\"#fc8d59\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1118\",\"type\":\"Line\"},{\"attributes\":{\"data\":{\"x\":[\"1960\",\"1961\",\"1962\",\"1963\",\"1964\",\"1965\",\"1966\",\"1967\",\"1968\",\"1969\",\"1970\",\"1971\",\"1972\",\"1973\",\"1974\",\"1975\",\"1976\",\"1977\",\"1978\",\"1979\",\"1980\",\"1981\",\"1982\",\"1983\",\"1984\",\"1985\",\"1986\",\"1987\",\"1988\",\"1989\",\"1990\",\"1991\",\"1992\",\"1993\",\"1994\",\"1995\",\"1996\",\"1997\",\"1998\",\"1999\",\"2000\",\"2001\",\"2002\",\"2003\",\"2004\",\"2005\",\"2006\",\"2007\",\"2008\",\"2009\",\"2010\",\"2011\",\"2012\",\"2013\",\"2014\",\"2015\",\"2016\",\"2017\",\"2018\",\"2019\",\"2020\",\"2021\"],\"y\":[73092515,75330008,77599218,79915555,82262794,84623747,86979283,89323288,91659246,94000381,96369875,98766288,101194394,103666904,106167372,108700515,111286504,113939886,116664382,119447303,122288383,125168060,128065095,130977370,133888775,136783180,139643355,142466264,145253973,148003411,150706446,153336445,155900790,158440875,160980472,163515328,166037122,168546707,171039804,173486281,175873720,178211881,180476685,182629278,184722043,186797334,188820682,190779453,192672317,194517549,196353492,198185302,199977707,201721767,203459650,205188205,206859578,208504960,210166592,211782878,213196304,214326223]},\"selected\":{\"id\":\"1050\"},\"selection_policy\":{\"id\":\"1049\"}},\"id\":\"1036\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"line_color\":\"#e6f598\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1074\",\"type\":\"Line\"},{\"attributes\":{\"line_color\":\"#fee08b\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1095\",\"type\":\"Line\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#fc8d59\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1120\",\"type\":\"Line\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1054\"},\"glyph\":{\"id\":\"1055\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1057\"},\"nonselection_glyph\":{\"id\":\"1056\"},\"view\":{\"id\":\"1059\"}},\"id\":\"1058\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data\":{\"x\":[\"1960\",\"1961\",\"1962\",\"1963\",\"1964\",\"1965\",\"1966\",\"1967\",\"1968\",\"1969\",\"1970\",\"1971\",\"1972\",\"1973\",\"1974\",\"1975\",\"1976\",\"1977\",\"1978\",\"1979\",\"1980\",\"1981\",\"1982\",\"1983\",\"1984\",\"1985\",\"1986\",\"1987\",\"1988\",\"1989\",\"1990\",\"1991\",\"1992\",\"1993\",\"1994\",\"1995\",\"1996\",\"1997\",\"1998\",\"1999\",\"2000\",\"2001\",\"2002\",\"2003\",\"2004\",\"2005\",\"2006\",\"2007\",\"2008\",\"2009\",\"2010\",\"2011\",\"2012\",\"2013\",\"2014\",\"2015\",\"2016\",\"2017\",\"2018\",\"2019\",\"2020\",\"2021\"],\"y\":[445954579,456351876,467024193,477933619,489059309,500114346,510992617,521987069,533431909,545314670,557501301,569999178,582837973,596107483,609721951,623524219,637451448,651685628,666267760,681248383,696828385,712869298,729169466,745826546,762895156,780242084,797878993,815716125,833729681,852012673,870452165,888941756,907574049,926351297,945261958,964279129,983281218,1002335230,1021434576,1040500054,1059633675,1078970907,1098313039,1117415123,1136264583,1154638713,1172373788,1189691809,1206734806,1223640160,1240613620,1257621191,1274487215,1291132063,1307246509,1322866505,1338636340,1354195680,1369003306,1383112050,1396387127,1407563842]},\"selected\":{\"id\":\"1091\"},\"selection_policy\":{\"id\":\"1090\"}},\"id\":\"1073\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1008\",\"type\":\"DataRange1d\"},{\"attributes\":{\"source\":{\"id\":\"1036\"}},\"id\":\"1041\",\"type\":\"CDSView\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#3288bd\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1038\",\"type\":\"Line\"},{\"attributes\":{\"axis_label\":\"Population, total (in millions)\",\"coordinates\":null,\"formatter\":{\"id\":\"1044\"},\"group\":null,\"major_label_policy\":{\"id\":\"1045\"},\"ticker\":{\"id\":\"1019\"}},\"id\":\"1018\",\"type\":\"LinearAxis\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#3288bd\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1039\",\"type\":\"Line\"},{\"attributes\":{\"source\":{\"id\":\"1117\"}},\"id\":\"1122\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1010\",\"type\":\"LinearScale\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1036\"},\"glyph\":{\"id\":\"1037\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1039\"},\"nonselection_glyph\":{\"id\":\"1038\"},\"view\":{\"id\":\"1041\"}},\"id\":\"1040\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1117\"},\"glyph\":{\"id\":\"1118\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1120\"},\"nonselection_glyph\":{\"id\":\"1119\"},\"view\":{\"id\":\"1122\"}},\"id\":\"1121\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"click_policy\":\"mute\",\"coordinates\":null,\"group\":null,\"items\":[{\"id\":\"1053\"},{\"id\":\"1072\"},{\"id\":\"1093\"},{\"id\":\"1116\"},{\"id\":\"1141\"}],\"location\":\"right\"},\"id\":\"1052\",\"type\":\"Legend\"},{\"attributes\":{\"axis_label\":\"Year\",\"coordinates\":null,\"formatter\":{\"id\":\"1047\"},\"group\":null,\"major_label_policy\":{\"id\":\"1048\"},\"ticker\":{\"id\":\"1015\"}},\"id\":\"1014\",\"type\":\"LinearAxis\"},{\"attributes\":{\"data\":{\"x\":[\"1960\",\"1961\",\"1962\",\"1963\",\"1964\",\"1965\",\"1966\",\"1967\",\"1968\",\"1969\",\"1970\",\"1971\",\"1972\",\"1973\",\"1974\",\"1975\",\"1976\",\"1977\",\"1978\",\"1979\",\"1980\",\"1981\",\"1982\",\"1983\",\"1984\",\"1985\",\"1986\",\"1987\",\"1988\",\"1989\",\"1990\",\"1991\",\"1992\",\"1993\",\"1994\",\"1995\",\"1996\",\"1997\",\"1998\",\"1999\",\"2000\",\"2001\",\"2002\",\"2003\",\"2004\",\"2005\",\"2006\",\"2007\",\"2008\",\"2009\",\"2010\",\"2011\",\"2012\",\"2013\",\"2014\",\"2015\",\"2016\",\"2017\",\"2018\",\"2019\",\"2020\",\"2021\"],\"y\":[667070000,660330000,665770000,682335000,698355000,715185000,735400000,754550000,774510000,796025000,818315000,841105000,862030000,881940000,900350000,916395000,930685000,943455000,956165000,969005000,981235000,993885000,1008630000,1023310000,1036825000,1051040000,1066790000,1084035000,1101630000,1118650000,1135185000,1150780000,1164970000,1178440000,1191835000,1204855000,1217550000,1230075000,1241935000,1252735000,1262645000,1271850000,1280400000,1288400000,1296075000,1303720000,1311020000,1317885000,1324655000,1331260000,1337705000,1345035000,1354190000,1363240000,1371860000,1379860000,1387790000,1396215000,1402760000,1407745000,1411100000,1412360000]},\"selected\":{\"id\":\"1070\"},\"selection_policy\":{\"id\":\"1069\"}},\"id\":\"1054\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"line_color\":\"#3288bd\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1037\",\"type\":\"Line\"},{\"attributes\":{\"label\":{\"value\":\"China\"},\"renderers\":[{\"id\":\"1058\"}]},\"id\":\"1072\",\"type\":\"LegendItem\"},{\"attributes\":{},\"id\":\"1012\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1006\",\"type\":\"DataRange1d\"},{\"attributes\":{},\"id\":\"1015\",\"type\":\"BasicTicker\"}],\"root_ids\":[\"1003\"]},\"title\":\"Bokeh Application\",\"version\":\"2.4.3\"}};\n", - " const render_items = [{\"docid\":\"27a5602b-a100-49a8-be71-4c1a30cbf69c\",\"root_ids\":[\"1003\"],\"roots\":{\"1003\":\"756bcecf-5d05-4b33-b3f9-817acf206cf6\"}}];\n", - " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " } else {\n", - " let attempts = 0;\n", - " const timer = setInterval(function(root) {\n", - " if (root.Bokeh !== undefined) {\n", - " clearInterval(timer);\n", - " embed_document(root);\n", - " } else {\n", - " attempts++;\n", - " if (attempts > 100) {\n", - " clearInterval(timer);\n", - " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", - " }\n", - " }\n", - " }, 10, root)\n", - " }\n", - "})(window);" - ], - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "1003" - } - }, - "output_type": "display_data" - } - ], - "source": [ - "import itertools\n", - "\n", - "import bokeh\n", - "from bokeh.palettes import Spectral6\n", - "from bokeh.plotting import figure, output_notebook, show\n", - "\n", - "output_notebook()\n", - "\n", - "# instantiating the figure object\n", - "p = figure(title=\"Population, total (World Bank)\", width=700, height=600)\n", - "\n", - "# colors\n", - "colors = itertools.cycle(Spectral6)\n", - "\n", - "# plotting the line graph\n", - "for column, color in zip(df.columns, colors):\n", - " p.line(\n", - " df.index,\n", - " df[column],\n", - " legend_label=column,\n", - " color=color,\n", - " line_width=2,\n", - " )\n", - "\n", - "p.legend.location = \"right\"\n", - "p.legend.click_policy = \"mute\"\n", - "p.title.text_font_size = \"12pt\"\n", - "\n", - "p.xaxis.axis_label = \"Year\"\n", - "p.yaxis.axis_label = \"Population, total (in millions)\"\n", - "\n", - "show(p)" - ] - } - ], - "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.10" - }, - "vscode": { - "interpreter": { - "hash": "b6702b69e93007336b96338c5a331192f07cedff01d36d4dcfa0f842adb718ad" - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/static/.DS_Store b/static/.DS_Store deleted file mode 100644 index 80dc61d..0000000 Binary files a/static/.DS_Store and /dev/null differ