diff --git a/package-lock.json b/package-lock.json index fbf82aed52..d7d9b46630 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15319,9 +15319,9 @@ } }, "node_modules/postcss": { - "version": "8.4.24", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", - "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "funding": [ { "type": "opencollective", diff --git a/src/notebooks/550-intro-table-with-pandas.ipynb b/src/notebooks/550-intro-table-with-pandas.ipynb new file mode 100644 index 0000000000..c80802406b --- /dev/null +++ b/src/notebooks/550-intro-table-with-pandas.ipynb @@ -0,0 +1,328 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Libraries\n", + "\n", + "First, you need to install the following librairies:\n", + "- [matplotlib](https://python-graph-gallery.com/matplotlib/) is used for plot creating the charts\n", + "- [pandas](https://python-graph-gallery.com/pandas/) is used to put the data into a dataframe and custom the table\n", + "- `numpy` is used to generate some data" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import matplotlib as mpl\n", + "\n", + "# data generation\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dataset\n", + "\n", + "When creating **nice output tables**, we first need to have the dataframe with the values we want. \n", + "\n", + "In this post, we'll use *fake weather data* from different cities. We'll take a look at different simple features of [pandas](https://python-graph-gallery.com/pandas/) to make this table more **aesthetically appealing**." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "sample_size = 6\n", + "\n", + "new_york = np.random.uniform(20,60,sample_size)\n", + "paris = np.random.uniform(20,40,sample_size)\n", + "london = np.random.uniform(5,30,sample_size)\n", + "\n", + "df = pd.DataFrame({'new_york': new_york,\n", + " 'paris': paris,\n", + " 'london': london},\n", + " \n", + " # generate date values in the index of the dataframe\n", + " index=pd.date_range(start=\"2020-01-01\", periods=sample_size).strftime(\"%d-%m-%Y\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Default output\n", + "\n", + "The default result **isn't very pretty**, but it's from this base that we'll build something more pleasing to the eye." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [] + }, + "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", + "
new_yorkparislondon
01-01-202056.12850726.7486105.122318
02-01-202048.73440228.09282213.278814
03-01-202030.81302024.75003224.622958
04-01-202044.40417239.8443098.658434
05-01-202025.29252125.40008522.398493
06-01-202035.90307826.66614813.565218
\n", + "
" + ], + "text/plain": [ + " new_york paris london\n", + "01-01-2020 56.128507 26.748610 5.122318\n", + "02-01-2020 48.734402 28.092822 13.278814\n", + "03-01-2020 30.813020 24.750032 24.622958\n", + "04-01-2020 44.404172 39.844309 8.658434\n", + "05-01-2020 25.292521 25.400085 22.398493\n", + "06-01-2020 35.903078 26.666148 13.565218" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Change colors\n", + "\n", + "A clean way to apply modifications to [Pandas](https://python-graph-gallery.com) tables is to create a function that performs the **modifications**, then apply this function to our data frame.\n", + "\n", + "- We use a colormap named *\"Reds\"*, that will put the **background color** of each cell depending on the value in the cell.\n", + "\n", + "Once the function is defined, we use the `style()` and `pipe()` from [Pandas](https://python-graph-gallery.com) to **apply this function** to the dataframe. " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'ColormapRegistry' object has no attribute 'get_cmap'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/IPython/core/formatters.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, obj)\u001b[0m\n\u001b[1;32m 343\u001b[0m \u001b[0mmethod\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_real_method\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprint_method\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 344\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmethod\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 345\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 346\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 347\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style.py\u001b[0m in \u001b[0;36m_repr_html_\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 406\u001b[0m \"\"\"\n\u001b[1;32m 407\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mget_option\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"styler.render.repr\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"html\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 408\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto_html\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 409\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 410\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style.py\u001b[0m in \u001b[0;36mto_html\u001b[0;34m(self, buf, table_uuid, table_attributes, sparse_index, sparse_columns, bold_headers, caption, max_rows, max_columns, encoding, doctype_html, exclude_styles, **kwargs)\u001b[0m\n\u001b[1;32m 1346\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1347\u001b[0m \u001b[0;31m# Build HTML string..\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1348\u001b[0;31m html = obj._render_html(\n\u001b[0m\u001b[1;32m 1349\u001b[0m \u001b[0msparse_index\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msparse_index\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1350\u001b[0m \u001b[0msparse_columns\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msparse_columns\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style_render.py\u001b[0m in \u001b[0;36m_render_html\u001b[0;34m(self, sparse_index, sparse_columns, max_rows, max_cols, **kwargs)\u001b[0m\n\u001b[1;32m 202\u001b[0m \u001b[0mGenerates\u001b[0m \u001b[0ma\u001b[0m \u001b[0mdict\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mnecessary\u001b[0m \u001b[0mkwargs\u001b[0m \u001b[0mpassed\u001b[0m \u001b[0mto\u001b[0m \u001b[0mjinja2\u001b[0m \u001b[0mtemplate\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 203\u001b[0m \"\"\"\n\u001b[0;32m--> 204\u001b[0;31m \u001b[0md\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_render\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msparse_index\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msparse_columns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax_rows\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax_cols\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\" \"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 205\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 206\u001b[0m return self.template_html.render(\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style_render.py\u001b[0m in \u001b[0;36m_render\u001b[0;34m(self, sparse_index, sparse_columns, max_rows, max_cols, blank)\u001b[0m\n\u001b[1;32m 159\u001b[0m \u001b[0mstylers\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0muse\u001b[0m \u001b[0mwithin\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m`\u001b[0m\u001b[0m_translate_latex\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 160\u001b[0m \"\"\"\n\u001b[0;32m--> 161\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_compute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 162\u001b[0m \u001b[0mdxs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 163\u001b[0m \u001b[0mctx_len\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style_render.py\u001b[0m in \u001b[0;36m_compute\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 254\u001b[0m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 255\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_todo\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 256\u001b[0;31m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 257\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 258\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style.py\u001b[0m in \u001b[0;36m_apply\u001b[0;34m(self, func, axis, subset, **kwargs)\u001b[0m\n\u001b[1;32m 1710\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mDataFrame\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1711\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0maxis\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1712\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1713\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mDataFrame\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1714\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndarray\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style.py\u001b[0m in \u001b[0;36m_background_gradient\u001b[0;34m(data, cmap, low, high, text_color_threshold, vmin, vmax, gmap, text_only)\u001b[0m\n\u001b[1;32m 3828\u001b[0m )\n\u001b[1;32m 3829\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3830\u001b[0;31m \u001b[0mrgbas\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_matplotlib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolormaps\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_cmap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcmap\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnorm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgmap\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3831\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3832\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mrelative_luminance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrgba\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mAttributeError\u001b[0m: 'ColormapRegistry' object has no attribute 'get_cmap'" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def custom_table(styler):\n", + " styler.background_gradient(cmap=\"Reds\", axis=None)\n", + " return styler\n", + "\n", + "df.style.pipe(custom_table)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, for example, it's much easier to see that temperatures in New York are **higher** compared to London." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Add aggregate metrics\n", + "\n", + "To make our table more meaningful, we can then add **aggregation measures**. To do this, we use pandas' `agg()` and `concat()` functions.\n", + "\n", + "We also add a line to our function to **round off the values** in our table, using the `format()` function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'ColormapRegistry' object has no attribute 'get_cmap'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/IPython/core/formatters.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, obj)\u001b[0m\n\u001b[1;32m 343\u001b[0m \u001b[0mmethod\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_real_method\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprint_method\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 344\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmethod\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 345\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 346\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 347\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style.py\u001b[0m in \u001b[0;36m_repr_html_\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 406\u001b[0m \"\"\"\n\u001b[1;32m 407\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mget_option\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"styler.render.repr\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"html\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 408\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto_html\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 409\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 410\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style.py\u001b[0m in \u001b[0;36mto_html\u001b[0;34m(self, buf, table_uuid, table_attributes, sparse_index, sparse_columns, bold_headers, caption, max_rows, max_columns, encoding, doctype_html, exclude_styles, **kwargs)\u001b[0m\n\u001b[1;32m 1346\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1347\u001b[0m \u001b[0;31m# Build HTML string..\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1348\u001b[0;31m html = obj._render_html(\n\u001b[0m\u001b[1;32m 1349\u001b[0m \u001b[0msparse_index\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msparse_index\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1350\u001b[0m \u001b[0msparse_columns\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msparse_columns\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style_render.py\u001b[0m in \u001b[0;36m_render_html\u001b[0;34m(self, sparse_index, sparse_columns, max_rows, max_cols, **kwargs)\u001b[0m\n\u001b[1;32m 202\u001b[0m \u001b[0mGenerates\u001b[0m \u001b[0ma\u001b[0m \u001b[0mdict\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mnecessary\u001b[0m \u001b[0mkwargs\u001b[0m \u001b[0mpassed\u001b[0m \u001b[0mto\u001b[0m \u001b[0mjinja2\u001b[0m \u001b[0mtemplate\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 203\u001b[0m \"\"\"\n\u001b[0;32m--> 204\u001b[0;31m \u001b[0md\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_render\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msparse_index\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msparse_columns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax_rows\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax_cols\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\" \"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 205\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 206\u001b[0m return self.template_html.render(\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style_render.py\u001b[0m in \u001b[0;36m_render\u001b[0;34m(self, sparse_index, sparse_columns, max_rows, max_cols, blank)\u001b[0m\n\u001b[1;32m 159\u001b[0m \u001b[0mstylers\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0muse\u001b[0m \u001b[0mwithin\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m`\u001b[0m\u001b[0m_translate_latex\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 160\u001b[0m \"\"\"\n\u001b[0;32m--> 161\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_compute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 162\u001b[0m \u001b[0mdxs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 163\u001b[0m \u001b[0mctx_len\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style_render.py\u001b[0m in \u001b[0;36m_compute\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 254\u001b[0m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 255\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_todo\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 256\u001b[0;31m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 257\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 258\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style.py\u001b[0m in \u001b[0;36m_apply\u001b[0;34m(self, func, axis, subset, **kwargs)\u001b[0m\n\u001b[1;32m 1710\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mDataFrame\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1711\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0maxis\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1712\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1713\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mDataFrame\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1714\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndarray\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/pandas/io/formats/style.py\u001b[0m in \u001b[0;36m_background_gradient\u001b[0;34m(data, cmap, low, high, text_color_threshold, vmin, vmax, gmap, text_only)\u001b[0m\n\u001b[1;32m 3828\u001b[0m )\n\u001b[1;32m 3829\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3830\u001b[0;31m \u001b[0mrgbas\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_matplotlib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolormaps\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_cmap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcmap\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnorm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgmap\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3831\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3832\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mrelative_luminance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrgba\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mAttributeError\u001b[0m: 'ColormapRegistry' object has no attribute 'get_cmap'" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def custom_table(styler):\n", + " styler.background_gradient(cmap=\"Blues\", axis=None)\n", + " styler.format(precision=2)\n", + " return styler\n", + "\n", + "agg_metrics = df.agg([\"sum\", \"mean\", \"max\"])\n", + "pd.concat([df, agg_metrics]).style.pipe(custom_table)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Going further\n", + "\n", + "This post explains how to create a simple custom table with [pandas](https://python-graph-gallery.com/pandas/).\n", + "\n", + "For more examples of **how to create or customize** your tables, see the [table section](https://python-graph-gallery.com/table/). You may also be interested in how to [add HTML and CCS to your table](https://python-graph-gallery.com/5xx-pandas-table-with-html-and-css/)." + ] + } + ], + "metadata": { + "chartType": "colors", + "description": "Creating elegant tables with the Pandas library in Python is a useful way to organize and display structured data. Pandas tables allow you to present information in a neat and organized format, making it easy to analyze and understand various datasets.
You can use Pandas to create tables that display data such as numerical values, text, and categorical information. These tables can be customized and styled to enhance their visual appeal, making them a versatile tool for data presentation and analysis.", + "family": "general", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "keywords": "table, pandas, customization, styler", + "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.9.13" + }, + "seoDescription": "How to custom a table with pandas", + "slug": "550-intro-table-with-pandas", + "title": "Introduction to table with Pandas" + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/src/notebooks/551-student-t-test-visualization.ipynb b/src/notebooks/551-student-t-test-visualization.ipynb new file mode 100644 index 0000000000..de570d32ee --- /dev/null +++ b/src/notebooks/551-student-t-test-visualization.ipynb @@ -0,0 +1,312 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Libraries\n", + "\n", + "First, you need to install the following librairies:\n", + "- [matplotlib](https://python-graph-gallery.com/matplotlib/) is used for plot creating the charts\n", + "- [pandas](https://python-graph-gallery.com/pandas/) is used to put the data into a dataframe\n", + "- `numpy` is used to generate some data\n", + "\n", + "The **Student t-test** will be done using `scipy`: install it using the `pip install scipy` command" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import scipy.stats as stats" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dataset\n", + "\n", + "When creating **nice output tables**, we first need to have the dataframe with the values we want. \n", + "\n", + "In this post, we'll use *fake weather data* from different cities. We'll take a look at different simple features of [pandas](https://python-graph-gallery.com/pandas/) to make this table more **aesthetically appealing**." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "sample_size = 100\n", + "\n", + "groupA = np.random.normal(10, 10, sample_size)\n", + "groupB = np.random.normal(40, 10, sample_size)\n", + "\n", + "df = pd.DataFrame({'value': np.concatenate([groupA, groupB]),\n", + " 'category': ['GroupA']*sample_size + ['GroupB']*sample_size})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Get statistical values\n", + "\n", + "First, we'll start by retrive the values we want to add on the plot: the **p value** and the **t statistic**. For this, we need to use the `ttest_rel()` function from `scipy`.\n", + "\n", + "Also, we retrieve the **mean** of each group.\n", + "\n", + "*Important: This post does not cover any statistical/math details*" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T-statistic: -21.422755428886422\n", + "P-value: 5.923713845065175e-39\n", + "Mean groupA: 10.795220725982492\n", + "Mean groupB: 39.594683650277446\n" + ] + } + ], + "source": [ + "# groups\n", + "groupA = df[df['category']=='GroupA']['value']\n", + "groupB = df[df['category']=='GroupB']['value']\n", + "\n", + "# Perform a paired t-test\n", + "t_statistic, p_value = stats.ttest_rel(groupA, groupB)\n", + "\n", + "# Get means\n", + "mean_groupA = groupA.mean()\n", + "mean_groupB = groupB.mean()\n", + "\n", + "# Print the results\n", + "print(\"T-statistic:\", t_statistic)\n", + "print(\"P-value:\", p_value)\n", + "print(\"Mean groupA:\", mean_groupA)\n", + "print(\"Mean groupB:\", mean_groupB)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's **round them** in order to make the chart **more readable** at the end" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "t_statistic = round(t_statistic,2)\n", + "p_value = round(p_value,5) # more decimal since it's a lower value in general\n", + "mean_groupA = round(mean_groupA,2)\n", + "mean_groupB = round(mean_groupB,2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Histogram with statistical elements\n", + "\n", + "Now let's use the stats we got above and add them to the plot of [histograms](https://python-graph-gallery.com/histogram/) of each group using the `text()` function from [matplotlib](https://python-graph-gallery.com/matplotlib/)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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MWMGCxcubHYpK6VevXqxySab0LNnz7qnMbglSQ0zY8YM1lhjDQYOHMiSdztVZvLSSy8xY8YMBg3q8OZ5S3FX+Qq0YMECxo8fz+WXX77C5x0RDBkypPMRV6CDDz6YjTfemN69ezN06FBuueWW1mE/+clP2GKLLYgIVl999U7nlZmMGjWKiGC//Yq7nr788svsu+++bLjhhvTp04eddtqJBx54oGHtkdT1Fi5cyHrrrWdotyMiWG+99ZZ7b4TBvQItWLCAs846qyHB3QwPP/wwJ510EmeffTZPPvkkhxxyCPPnzweKf8YDDjiAddddt655XXLJJdx///1L9Hvttdd47rnnOOOMM/jqV7/Kvffey6GHHrrC2yGpuQztjr2rdZOZK/1j+PDhWQUDBgxIoPUxbty4pcYZMWJErrfeevnmm29mZuahhx6aPXr0yFmzZuWXvvSlXH/99XO11VbLQYMG5UUXXdQ6HZDbbLNNZmaOHTs2gbz//vszM7Nv3745YMCAzMxctGhRnn766bnRRhvlWmutlYceemjOnj07MzN/8pOfJJDf+9736mrPokWLWp8ffPDBCeSjjz66VJv79u27zPnMnDkz11577fz+97+fQH7yk5/MzMw333wz33rrrdbxtt9++wRy/vz5ddUnaeX3t7/9rdklZGbmCy+8kIcffngOGjQot99++xw5cmRed911DV/u7Nmzs0ePHkt8nrfV3joCJmcHmegx7hXo29/+NkceeSSDBw/mW9/6FkOGDOHVV1/lzTeL+9OvscYajBkzhlNPPZU77riDXXbZhd/+9rfsvffebLDBBgwePJizzz6bRYsWcdVVV3HiiScyevRoBgwYUHcN3/nOdzj33HM5/vjj+eAHP8g555zDCSecwLXXXrvM6RYtWsTcuXMB6NmzJ2uttRarrbYaAK+++ir33nsv/fv358Mf/vByr5eTTjqJPfbYg4MOOogvf/nLrf179Hjn7ffMM8/w2GOPMXz4cPr06bPcy5BUDWfFWSt0fuNyXKfjZCYHHnggY8eO5aqrrgKKz5wbb7xxifEWL168xOfSinDNNdcwcuRIJk6cyPHHH79C5mlwr0B77703ABtssAGHHXYYAKNGjeLOO+8EiuPChx12GKeffjrXXnstc+fOZf78+YwZU9zP/qmnnuKCCy5gwYIFrfOcOnXqcgX3TTfdBMCPfvSj1n4tx6bHjh3LmDFjWHXVVZeabuLEiXzuc58DYLfddmPSpEkAzJs3jwMOOIAXX3yR3/3ud61hXq/bb7+dm2++mVtvvZVnnikuBLRgwQJmzpzJRhttBMALL7zAvvvuywc+8AEmTJiwXPOXpM7ccccdrLbaanzxi19s7TdgwABOPvlkLr/8cn7zm9+wcOFC5s+fz7XXXssxxxzDU089RZ8+fbj44osZOnQo48ePZ/XVV+crX/kKAEOGDGn9vB09ejQf/ehHeeihh/jIRz7CT3/609YNkIkTJ3LuuedyxBFH8Nxzz7Hxxhu/5/YY3CtQe8cqzj33XP75z38CsM0227Dhhhuyxx57cMMNN/DKK6+w+uqr86lPfYrHHnuM7373uwwbNoxx48bx61//mssuu6zdkxZagnfx4sUsWrSI119/vXVYZtKjRw9uuumm1vHefvvt1r+LFy8mIpYK70984hPceuutAKyzzjoAzJ07l3322YfJkydz3XXXMWrUqLrWwxtvvMHbb79Nr169ePbZZ1m4cCG77LJL6/A//OEPHHXUUdx2223MnDmT3XffndmzZ3PLLbewzTbb1LUMSarXo48+yvbbb9/h8HvuuYcpU6aw7rrrcvLJJ7Pddttxww03cMcdd3DUUUfx8MMPL3P+jz/+OD/+8Y/ZeeedOeaYY/jBD37AV77yFZ599lleeOEFdtxxRz7zmc/w85//fIm9ju+WJ6etQGuuuSarrLIKTz75JFdeeSXPPPMMw4cPZ88992TPPfekf//+AIwZM4Y5c+Zw7bXXcvDBB9OnTx+yvC/666+/zqxZs7jttts6XE7LDVeuuOIKzjjjjNZgBth///1ZvHgxEyZMYPr06fzud79r3fq+4oor6N27N+edd95S8+zfv39rncOHDwdgr7324o9//COHH344r732GldffTWzZ88G4MEHH+TSSy9l3rx5LF68mEsvvZS77roLKPY89O7dmxdffJGPf/zjXHPNNVxzzTX84Ac/AGD48OGMGzeOefPmsdtuu/H444/zhS98gSeffJKrr7669QQ4SWqEE088kW233ZYddtgBKD7rWk60vfvuu/nsZz8LwO67785LL73Eq6++usz5bbrppuy8885A8fl+9913A3D11Vfzmc98BoDDDjuMiRMnrpD63eJegXr27Mm///u/c8EFFzBmzBiuuOKK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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Get group names and define colors\n", + "group_name = df['category'].unique()\n", + "colors = ['purple', 'orange']\n", + "\n", + "# Init plots\n", + "fig, ax = plt.subplots(figsize=(8,6))\n", + "\n", + "# Create the histograms\n", + "for i, group in enumerate(group_name):\n", + " \n", + " # Filter on the group\n", + " subgroup = df[df['category']==group]['value']\n", + " \n", + " # Add histogram of the subgroup, with the right color\n", + " ax.hist(subgroup, bins=5, color=colors[i])\n", + "\n", + "# Add a legend\n", + "ax.legend(group_name)\n", + "\n", + "# Add the p value and the t\n", + "p_value_text = f'p-value: {p_value}'\n", + "ax.text(-12, 40, p_value_text, weight='bold')\n", + "t_value_text = f't-value: {t_statistic}'\n", + "ax.text(-12, 37, t_value_text, weight='bold')\n", + "\n", + "# Add a title and axis label\n", + "ax.set_title('Student t-test between GroupA and GroupB')\n", + "ax.set_xlabel('Value')\n", + "ax.set_ylabel('Frequency')\n", + "\n", + "# Show the plot\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Boxplot with statistical elements\n", + "\n", + "Now let's use the stats we got above and add them to the plot of [boxplots](https://python-graph-gallery.com/boxplot/) of each group using the `text()` function from [matplotlib](https://python-graph-gallery.com/matplotlib/).\n", + "\n", + "For this graph, we'll also add the **average of each group** next to its associated [boxplot](https://python-graph-gallery.com/boxplot/). \n", + "\n", + "*Warning: the positions of the texts need to be changed compared to the histogram plot.*" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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X0bOAO47RlP/8Ps/F+/5zMTbfjjn9gD34z2/G/G26Yajlg/7+ssx/9/+a3sv3us52f/iJwFguQ+hiIgEl5nNwTtre3Rx9yXozGwI0Mg516u4+yInR3vQIiIiAaSAFhERCSANcYuIiASQ9qBFREQCSAEtIiISQKfiaikFVqNGDRcXF1fc3RARETllvv766+3OuaN/ZCZYAR0XF0dqampxd0NEROSUMbOwPxOrIW4REZEAUkCLiIgEkAJaREQkgAJ1DFpEREqOQ4cOsWHDBjIzM4u7KyVChQoViI2NpWzZsgUqr4AWEZGTsmHDBs444wzi4uLIfeVNOZpzjh07drBhwwbq18/3gm+5aIhbREROSmZmJmeffbbCuQDMjLPPPvuERhsU0CIictIUzgV3ottKAS0iIiXWli1buO2222jQoAFt2rThkksuYcqUKae8H1lZWdSoUYMnn3wyYnXqGLSIiETGe+dA5pbI1VehFnTbnO9s5xw33ngjycnJvP322wCsXbuWadOm5SmblZVFdHTRRd4nn3xC48aNmTRpEs8991xERha0By0iIpERyXAuQH2fffYZ5cqVo1+/fqFp9erV48EHHwRgzJgx3HLLLVx//fVcc8017Ny5kxtvvJGEhAQuvvhili5dCsCQIUN46aWXQnW0aNGC9PR00tPTadKkCcnJySQkJNC9e3f2798fti8pKSk8/PDD1K1bl6+++qqwaw4ooEVEpIRavnw5rVu3PmaZ+fPnM3bsWD777DOeeeYZWrVqxdKlS3nuuee44447jtvGd999R9++fVm6dClnnnkmo0aNylPm119/ZdasWXTp0oWePXuSkpJy0uuUkwJaREROCw888AAtW7akbdu2oWlXX3011atXB2DevHn07t0bgI4dO7Jjxw727NlzzDrPO+88LrvsMgB69erFvHnz8pSZPn06HTp0oFKlStx8881MmTKFw4cPF3p9FNAiIgFnZoW+nY6aN2/O4sWLQ49fffVVZs2axbZt20LTKleuHLrvnMtTh5kRHR3NkSNHQtNy/ivU0dsu3LZMSUnh008/JS4ujjZt2rBjxw5mz559ciuVQ0QC2szOMrPJZrbKzFaa2SVmVt3MZprZD/7fapFoS0SktHHOHfNW0DKnm44dO5KZmclrr70WmpbfMWKAK6+8kvHjxwMwZ84catSowZlnnklcXFwo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smXL+PXXXwGYOXMmderUKbb+TJ06la5du7JkyRIaNmyYa94999xDtWrV+OGHH1iyZAkzZsxg586deeo4fPhwkfZx5cqVHDlyhLlz55KRkXHc8tWrV+evf/0rjz/+eK7phw8f5oEHHuCjjz5ixYoVpKSksGLFijzLv/rqqzRr1oxvvvmGOXPm8Nhjj3Hw4MGIrY9IaaOAlhLjuuuu44MPPgAgJSUl155hRkYGd911F23btqVVq1a8//77AKSnp3PFFVfQunVrWrduzZdffgnAnDlzaN++Pd27d6dJkybcfvvtOOfytJmWlsbFF19MQkICN910E7t27eLDDz/klVdeYfTo0XTo0CFX+Z9++omFCxfyxz/+kago7+0VExPDE088EWq3Q4cO3HbbbcTHx5OZmcmdd95JfHw8rVq1Yvbs2QCMGTOG/v37h+rt0qULc+bMAaBKlSo89thjtG7dmk6dOrFt27aw2+vtt9+md+/eXHPNNUybNu2427dmzZq0bduWsmXL5pq+cOFCGjVqRIMGDShXrhw9evQIbd+czIxffvkF5xz79u2jevXqREdHH7ddEQlPAS0lRo8ePZgwYQKZmZksXbqUiy66KDRv2LBhdOzYkUWLFjF79mwGDBhARkYGNWvWZObMmSxevJiJEyfy0EMPhZZZsmQJr7zyCitWrGD16tV88cUXedq84447eOGFF1i6dCnx8fEMHTqUzp07069fPx599NFQoGZbvnw5LVu2DIVzOAsXLmTYsGGsWLGCV199FYBvv/2WlJQUkpOTyczMPOZ2yMjIoHXr1ixevJh27doxdOjQsOUmTpzIrbfeSs+ePUlJSQlNHzx4cIECO9vGjRs577zzQo9jY2PZuHFjnnL9+/dn5cqVnHvuucTHx/OXv/zlmNtBRI5N7x4pMRISEkhPTyclJYXOnTvnmvfJJ58wfPhwEhMTad++PZmZmaxbt45Dhw5x7733Eh8fzy233JJraPbCCy8kNjaWqKgoEhMTSU9Pz1Xnnj172L17N+3atQMgOTmZuXPnnlCfhw0bRmJiIueee26uduvXrw/AvHnzQsfWmzRpQr169fj++++PWWdUVBS33norAL169WLevHl5yixatIiYmBjq1atHp06dWLx4Mbt27QLg2Wef5YYbbijwOoQbWTCzPNM+/vhjEhMT2bRpE2lpafTv35+9e/cWuB0RyU0BLSXKDTfcwOOPP57nxCfnHO+++y5paWmkpaWxbt06mjZtyogRI6hVqxbffPMNqampuY6Jli9fPnS/TJkyZGVlFbp/2cdgjxw5AsCgQYNIS0vLFVSVK1fO1e9woqOjQ3UAx9yrDheWKSkprFq1iri4OBo2bMjevXt59913T3h9wNtjXr9+fejxhg0bcn3hyPbWW2/RrVs3zIxGjRpRv359Vq1adVJtiogCWkqYu+66i8GDBxMfH59r+rXXXsvIkSNDgbdkyRLA2wuuXbs2UVFRjBs37oROzKpatSrVqlXjP//5DwDjxo0L7U3np1GjRiQlJfH000+H2srMzMw3iK+88krGjx8PwPfff8+6deto3LgxcXFxpKWlceTIEdavX8/ChQtDyxw5coTJkycD3nHmyy+/PFedR44c4Z133mHp0qWkp6eTnp7O+++/n2uY+0S0bduWH374gTVr1nDw4EEmTJgQdg+8bt26zJo1C4AtW7bw3Xff0aBBg5NqU0QgImdwmNk/gC7AVudcC39adWAiEAekA791zu2KRHtSesXGxvLwww/nmf6HP/yBRx55hISEBJxzxMXFMX36dO6//35uvvlm3nnnHTp06JBr77Ugxo4dS79+/di/fz8NGjQo0L8OjR49mgEDBtCoUSOqV69OxYoVeeGFF8KWvf/+++nXrx/x8fFER0czZswYypcvz2WXXUb9+vWJj4+nRYsWtG7dOrRM5cqVWb58OW3atKFq1apMnDgxV51z586lTp06uc5yv/LKK1mxYgU///wzr732GklJSXlCdvPmzSQlJbF3716ioqJCx+fPPPNM/va3v3Httddy+PBh7rrrLpo3bw7A66+/DkC/fv34wx/+QJ8+fYiPj8c5xwsvvECNGjUKtqFFJA/L75v9CVVidiWwD/hnjoD+E7DTOTfczAYC1ZxzTxyrnqSkJJeamlro/siJMzPc+OLuBdjt+Q/7iqdKlSrs27evuLshIhFiZl8755KOnh6RPWjn3FwziztqclegvX9/LDAHOGZAS/Gy24u7ByIikq0o/0mxlnPuZwDn3M9mVjNcITPrC/QF7xiWFJ+g7EHLsWnvWaR0KPaTxJxzbzjnkpxzSTExMcXdHRERkUAoyoDeYma1Afy/W4uwLRERkdNKUQb0NCDZv58M5P1tQBEREQkrIgFtZinAfKCxmW0w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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Group our dataset with our 'Group' variable\n", + "grouped = df.groupby('category')['value']\n", + "\n", + "# Init a figure and axes\n", + "fig, ax = plt.subplots(figsize=(8, 6))\n", + "\n", + "# Create the plot with different colors for each group\n", + "boxplot = ax.boxplot(x=[group.values for name, group in grouped],\n", + " labels=grouped.groups.keys(),\n", + " patch_artist=True,\n", + " medianprops={'color': 'black'}\n", + " ) \n", + "\n", + "# Define colors for each group\n", + "colors = ['orange', 'purple']\n", + "\n", + "# Assign colors to each box in the boxplot\n", + "for box, color in zip(boxplot['boxes'], colors):\n", + " box.set_facecolor(color)\n", + " \n", + "# Add the p value and the t\n", + "p_value_text = f'p-value: {p_value}'\n", + "ax.text(0.7, 50, p_value_text, weight='bold')\n", + "t_value_text = f't-value: {t_statistic}'\n", + "ax.text(0.7, 45, t_value_text, weight='bold')\n", + "\n", + "# Add the mean for each group\n", + "ax.text(1.1, mean_groupA, f'Mean of Group A: {mean_groupA}')\n", + "ax.text(1.4, mean_groupB, f'Mean of Group B: {mean_groupB}')\n", + "\n", + "# Add a title and axis label\n", + "ax.set_title('Student t-test between GroupA and GroupB')\n", + "\n", + "# Add a legend\n", + "legend_labels = ['Group A', 'Group B']\n", + "legend_handles = [plt.Rectangle((0,0),1,1, color=color) for color in colors]\n", + "ax.legend(legend_handles, legend_labels)\n", + "\n", + "# Display it\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Going further\n", + "\n", + "This post explains how to represent the **results of a student t-test** in a [histogram](https://python-graph-gallery.com/histogram/) and a [boxplot](https://python-graph-gallery.com/boxplot/).\n", + "\n", + "For more examples of **charts with statistics**, see the [statistics section](https://python-graph-gallery.com/statistics/). You may also be interested in how to [create a mirror histogram chart](https://python-graph-gallery.com/density-mirror/)." + ] + } + ], + "metadata": { + "chartType": "statistics", + "description": "The Student t-test is used to compare the means of 2 normally distributed variables. With matplotlib, you can easily create a plot with 2 different histograms or boxplots on the same plot, in order to show difference between the variables.
However, it's possible to add, using annotation methods from matplotlib, the results of the Student t-test directly in our chart. This will make the chart much more informative and relevant when comparing distributions between groups or variables. ", + "family": "general", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "keywords": "statistics, student, test, matplotlib, histogram, boxplot, annotation, chart, plot", + "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.5" + }, + "seoDescription": "How to represent the results of a Student t-test with matplotlib", + "slug": "551-student-t-test-visualization", + "title": "Visualization of Student t-test" + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/src/notebooks/552-table-combined-with-plot.ipynb b/src/notebooks/552-table-combined-with-plot.ipynb new file mode 100644 index 0000000000..f797dd6462 --- /dev/null +++ b/src/notebooks/552-table-combined-with-plot.ipynb @@ -0,0 +1,241 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Libraries\n", + "\n", + "First, you need to install the following librairies:\n", + "- [matplotlib](https://python-graph-gallery.com/matplotlib/) is used for plot creating the charts\n", + "- [pandas](https://python-graph-gallery.com/pandas/) is used to put the data into a dataframe and custom the table\n", + "- `numpy` for data generation" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dataset\n", + "\n", + "Our dataset consists of values on weather such as Freeze or Hail. We store our data in a **pandas dataframe**.\n", + "\n", + "The \"rows\" column:\n", + "- for each value of x in the tuple, it creates a **string like \"100 year\"**, \"50 year\", \"20 year\", and so on." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "data = {'Freeze': [ 66386, 174296, 75131, 577908, 32015],\n", + " 'Wind': [ 58230, 381139, 78045, 99308, 160454],\n", + " 'Flood': [ 89135, 80552, 152558, 497981, 603535],\n", + " 'Quake': [ 78415, 81858, 150656, 193263, 69638],\n", + " 'Hail': [139361, 331509, 343164, 781380, 52269],\n", + " 'rows': ['%d year' % x for x in (100, 50, 20, 10, 5)]}\n", + "df = pd.DataFrame(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create the barplot\n", + "\n", + "The following code creates a [stacked barplot](https://python-graph-gallery.com/barplot/), with a **gradient color** for subgroups in each bar. \n", + "\n", + "- `index` specifies the **positions** of the bars on the x-axis\n", + "- `bar_width` determines the **width** of the bars\n", + "- `y_offset` is used to **keep track of the vertical position** of each category's bars on the chart\n", + "\n", + "Then, we loop through the data and creates the stacked bar chart:\n", + "\n", + "- For each row of data, it adds a set of bars to the chart\n", + "- Each bar represents a category's loss, and they are **stacked on top of each other**\n", + "- **Color of the bar** is defined with our `colors` variabme\n", + "- The **heights of the bars** are determined by the values in the data" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAGxCAYAAACDV6ltAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAxKElEQVR4nO3de1RVdeL//9cRBAHhJCoHSSQs0xK1kkTMQsNrXjIzK/uQlmXlpUj9NDn2beyipo2XGj865jhqN/UzlXZTkm5eBklT+ZiNmSYpjiCpCGoMCO7fH43nNyfEoDjsg+/nY62zlmfv99m8DqcWr/Xe772Pw7IsSwAAAAarZ3cAAAAAu1GIAACA8ShEAADAeBQiAABgPAoRAAAwHoUIAAAYj0IEAACMRyECAADGoxABAADjUYgAQy1dulQOh0Nffvml3VEuaMSIEWrYsKHXf063bt3kcDjkcDhUr149hYaG6oorrtAdd9yht956S2fPnq3wmssuu0wjRozwerbKZGRkaMqUKTpx4oRtGYCLhb/dAQDAV7Rs2VJvvPGGJOn06dPKzs7W6tWrdccdd+jGG2/U+++/L6fT6R6/atUqhYWF2RVXGRkZeuaZZzRixAhdcskltuUALgYUIgD4t6CgIHXu3Nlj2wMPPKAlS5bo/vvv16hRo7Ry5Ur3vmuvvba2I9aKH3/8UcHBwXbHAGoVp8wAXNCmTZuUnJys0NBQBQcHq0uXLvrwww89xvz444+aOHGiYmNj1aBBA4WHhys+Pl7Lly93j9m/f7/uuusuRUVFKTAwUC6XS8nJycrKyqpSjq+//lrJyckKCQlR06ZNNXbsWP3444/u/cnJyWrTpo1+/n3VlmXpiiuuUL9+/X717+C+++7TLbfcor/97W86cOCAe/vPT5mdPXtWzz//vFq3bq2goCBdcsklat++vV566SX3mH379um+++5Tq1atFBwcrEsvvVQDBgzQV1995fEzf+lYU6ZM0X//939LkmJjY92n+z7//HP3MVauXKnExESFhISoYcOG6t27t3bs2OHxc86dkvzqq6/Uq1cvhYaGKjk5+Vf/roC6ihkiAJVav369evbsqfbt22vx4sUKDAzU/PnzNWDAAC1fvlx33nmnJGn8+PF67bXX9Pzzz+vaa6/V6dOntWvXLh07dsx9rFtuuUXl5eWaOXOmWrRooaNHjyojI6NK61/OnDmjW265RQ899JCefPJJZWRk6Pnnn9eBAwf0/vvvS5Iee+wx3Xrrrfrkk0/Uo0cP92vXrl2r7777Ti+//PJv+l0MHDhQa9as0caNGxUTE3PeMTNnztSUKVP01FNP6aabbtKZM2f0zTffeLzHw4cPq3HjxnrhhRfUtGlTHT9+XMuWLVNCQoJ27Nih1q1bV+lYDzzwgI4fP64//elPeuedd9SsWTNJ0tVXXy1JmjZtmp566indd999euqpp1RaWqoXX3xRN954o7Zs2eIeJ0mlpaUaOHCg+/dbVlb2m35XQJ1kATDSkiVLLEnW1q1bKx3TuXNnKyIiwjp58qR7W1lZmRUXF2c1b97cOnv2rGVZlhUXF2cNGjSo0uMcPXrUkmTNnTu32jmHDx9uSbJeeuklj+1Tp061JFmbNm2yLMuyysvLrZYtW1q33nqrx7i+fftal19+uTtrZZKSkqy2bdtWun/t2rWWJGvGjBnubTExMdbw4cPdz/v3729dc801VXxnPykrK7NKS0utVq1aWY8//ni1jvXiiy9akqzs7GyP7QcPHrT8/f2tcePGeWw/efKkFRkZaQ0dOtS97dzv969//Wu1cgMXG06ZATiv06dP64svvtCQIUM8rvLy8/NTSkqKDh06pD179kiSOnXqpLVr1+rJJ5/U559/ruLiYo9jhYeH6/LLL9eLL76o2bNna8eOHee9autC7rnnHo/nw4YNkyR99tlnkqR69epp7Nix+uCDD3Tw4EFJ0nfffae0tDSNHj1aDoejer+An7F+dirufDp16qT/+7//0+jRo/XRRx+pqKiowpiysjJNmzZNV199tQICAuTv76+AgADt3btXu3fvrtaxKvPRRx+prKxM9957r8rKytyPBg0aKCkpyeO02jm33357lY8PXIwoRADOq6CgQJZluU/F/KeoqChJcp8Se/nll/W73/1Oq1evVvfu3RUeHq5BgwZp7969kiSHw6FPPvlEvXv31syZM3XdddepadOmevTRR3Xy5MlfzOLv76/GjRt7bIuMjPTIIEn333+/goKC9Oc//1mS9D//8z8KCgrS/fff/yt+A57OrR06997PZ9KkSfrjH/+ozMxM9e3bV40bN1ZycrLHrQ3Gjx+v//f//p8GDRqk999/X1988YW2bt2qDh06eBTJqhyrMkeOHJEkXX/99apfv77HY+XKlTp69KjH+ODgYFuvlgN8AYUIwHk1atRI9erVU25uboV9hw8fliQ1adJEkhQSEqJnnnlG33zzjfLy8rRgwQJlZmZqwIAB7tfExMRo8eLFysvL0549e/T4449r/vz57oXBF1JWVuZRfCQpLy9PkjyKktPp1PDhw/WXv/xFx48f15IlSzRs2LAauST9vffek8Ph0E033VTpGH9/f40fP17bt2/X8ePHtXz5cuXk5Kh3797uBeCvv/667r33Xk2bNk29e/dWp06dFB8fX6GkVOVYlTn3ubz11lvaunVrhccXX3zhMf63zp4BFwMKEYDzCgkJUUJCgt555x2PmYuzZ8/q9ddfV/PmzXXllVdWeJ3L5dKIESN09913a8+ePef9433llVfqqaeeUrt27bR9+/Yq5Tl3f6Bz3nzzTUk/3VDxPz366KM6evSohgwZohMnTmjs2LFVOv6FLFmyRGvXrtXdd9+tFi1aVOk1l1xyiYYMGaIxY8bo+PHj+v777yX9VD4CAwM9xn744Yf65z//We1jnTvOz09R9u7dW/7+/vruu+8UHx9/3gcAT1xlBhju008/df+B/U+33HKLpk+frp49e6p79+6aOHGiAgICNH/+fO3atUvLly93zywkJCSof//+at++vRo1aqTdu3frtddeU2JiooKDg7Vz506NHTtWd9xxh1q1aqWAgAB9+umn2rlzp5588slfzBgQEKBZs2bp1KlTuv76691XmfXt21ddu3b1GHvllVeqT58+Wrt2rbp27aoOHTpU+XdRXFyszMxM97/379+v1atX64MPPlBSUpL7VFxlBgwYoLi4OMXHx6tp06Y6cOCA5s6dq5iYGLVq1UqS1L9/fy1dulRt2rRR+/bttW3bNr344otq3rx5tY/Vrl07SdJLL72k4cOHq379+mrdurUuu+wyPfvss5o8ebL279+vPn36qFGjRjpy5Ii2bNnintED8B/sXtUNwB7nrjKr7HHuyqWNGzdaN998sxUSEmIFBQVZnTt3tt5//32PYz355JNWfHy81ahRIyswMNBq2bKl9fjjj1tHjx61LMuyjhw5Yo0YMcJq06aNFRISYjVs2NBq3769NWfOHKusrOyCOYcPH26FhIRYO3futLp162YFBQVZ4eHh1iOPPGKdOnXqvK9ZunSpJclasWJFlX8fSUlJHu8/JCTEatmypTVk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UJI0atQo9e/fnyvMAACAJJsL0Zdffqnu3bu7n59bszN8+HAtWLBAX331lV599VWdOHFCzZo1U/fu3bVy5UqFhoa6XzNnzhz5+/tr6NChKi4uVnJyspYuXSo/Pz/3mDfeeEOPPvqo+2q0gQMHXvDeRwAAwCwOy7Isu0PUBUVFRXI6nSosLGQ9EYCL3qz5m+2OUGsmjE60OwK8qKp/v+vUGiIAAABvoBABAADj/eZCVFRUpNWrV2v37t01kQcAAKDWVbsQDR061L0gubi4WPHx8Ro6dKjat2+vt99+u8YDAgAAeFu1C9GGDRt04403SpJWrVoly7J04sQJvfzyy3r++edrPCAAAIC3VbsQFRYWKjw8XJKUlpam22+/XcHBwerXr5/7DtIAAAB1SbULUXR0tDZv3qzTp08rLS3NfW+fgoICNWjQoMYDAgAAeFu1b8yYmpqqe+65Rw0bNlRMTIy6desm6adTae3atavpfAAAAF5X7UI0evRoderUSTk5OerZs6fq1ftpkqlly5asIQIAAHXSr/rqjvj4eMXHx3ts69evX40EAgAAqG1VLkTPPvusx/Onn366xsMAAADYocqFKDs72/1vh8PhlTAAAAB2qHIhWrJkiTdzAAAA2IbvMgMAAMar1qLqrVu3au7cucrIyFBeXp4cDodcLpe6dOmixx9/vMJCawBA3RTeuondEYBaVeVCtHr1ag0dOlTJycl67LHH5HK5ZFmW8vPztW7dOt1www363//9X916663ezAsAAFDjHJZlWVUZGBcXp//6r//Sk08+ed79M2bM0Kuvvqqvv/66RgP6iqKiIjmdThUWFiosLMzuOADgVUs+MeermO5LbmV3BHhRVf9+V3kN0b59+zR48OBK9w8aNEjfffdd9VICAAD4gCoXossvv1yrV6+udP+7776rli1b1kQmAACAWlWtGzPeddddWr9+vXr16iWXyyWHw6G8vDylp6dr3bp1WrFihTezAgAAeEWVC9Htt9+uDRs26KWXXtLs2bOVl5cnSYqMjFRiYqLWr1+vxMRErwUFAADwlmpddp+YmEjpAQAAF51f9eWu5eXlOnr0qBwOhxo3biw/P7+azgUAAFBrqnWn6lWrVumGG25QcHCwoqKi1KxZMwUHB+uGG2644IJrAAAAX1blQrRw4ULdddddat++vVauXKlNmzZp48aNWrlypdq3b6+77rpLixYt8mZWAAAAr6jyKbMXX3xR8+fP18iRIyvsGzRokK6//npNnTpVDz74YI0GBAAA8LYqzxD985//VNeuXSvd36VLFx0+fLhGQgEAANSmKheitm3b6pVXXql0/6JFi9S2bdsaCQUAAFCbqnzKbNasWerXr5/S0tLOe2PGAwcOaM2aNd7MCgAA4BVVLkRJSUnatWuXFixYoMzMTI8bM/bv318PP/ywLrvsMm/lBAAA8Jpq3Yfosssu04wZM7yVBQAAwBa/6saMBw4cUF5enhwOh1wul2JiYmo6FwAAQK2p1o0Z58yZo+joaLVs2VKJiYnq3LmzWrZsqejoaM2dO9dLEQEAALyryjNEzz33nP74xz/q97//vXr37i2XyyXLspSfn6+PPvpIU6ZM0alTp/TUU095My8AAECNq3IheuWVV7Rs2TINGjTIY3tUVJSuueYaXXnllRo7diyFCAAA1DlVPmV27NgxtW7dutL9V155pQoKCmokFAAAQG2qciHq1KmTpk6dqrKysgr7ysrKNG3aNHXq1KlGwwEAANSGKp8y+9Of/qRevXopIiJCSUlJHjdm3LBhgwIDA5Wenu7NrAAAAF5R5Rmidu3a6dtvv9XUqVMVFham7Oxs7d+/X2FhYZo6daq++eYbvroDAADUSdW6D1FoaKgeeeQRPfLII97KAwAAUOuqdR+iCzlz5owOHjxYU4cDAACoNTVWiP7xj38oNja2pg4HAABQa2qsEAEAANRVVV5DdN11111wf3Fx8W8OAwAAYIcqF6J//OMfuuuuuyo9LZabm6tvv/22xoIBAADUlioXori4OCUkJFR6hVlWVpYWLVpUY8EAAABqS5ULUdeuXbVnz55K94eGhuqmm26qkVAAAHvFuhraHQGoVQ7Lsiy7Q9QFRUVFcjqdKiwsVFhYmN1xAMCrPt+Va3eEWtMtrpndEeBFVf37zVVmAADAeL+5EB07dkyfffaZjhw5UhN5AAAAal21CtHChQu1cOFC9/OsrCxdccUVSk5OVsuWLfXRRx/VeEAAAABvq1YhWrRokZo0aeJ+/oc//EEDBw5UUVGRJkyYoMmTJ9d4QAAAAG+rUiHasGGD1q9fr/3796uwsND9/LPPPlNiYqK2b9+ujh07avfu3dqwYYM2bNjg7dwAAAA1pkqX3WdnZ0uSzp49q9zcXPn5+Wnv3r3y8/NTcHCwsrOzVVZWpvLycn3//feyLItL8AEAQJ1RpUI0fPhwST+dMsvJydH999+vTz75RD169NC9994rSfr2228VFRXlfg4AAFBXVPnGjJL03HPPadCgQe61RJ9++ql73/Lly3XzzTfXeEAAAABvq1Yh6t69uw4ePKh9+/apdevWatjw/7+T6cCBA9WsGTe3AgAAdU+1CpEkOZ1OdezYscL2a6+9tkYCAQAA1DbuVA0AAIxHIQIAAMajEAEAAONRiAAAgPGqvaj6nNLSUuXn5+vs2bMe21u0aPGbQwEAANSmaheivXv36v7771dGRobHdsuy5HA4VF5eXmPhAAAAakO1C9GIESPk7++vDz74QM2aNZPD4fBGLgAAgFpT7UKUlZWlbdu2qU2bNt7IAwAAUOuqXYiuvvpqHT161BtZAFvNmr/Z7gi1ZsLoRLsjAIBPqfZVZjNmzNATTzyhzz//XMeOHVNRUZHHAwAAoK6p9gxRjx49JEnJycke21lUDQAA6qpqF6LPPvvMGzkAAABsU+1ClJSU5I0cAAAAtqnSGqKdO3e6b8C4c+fOCz6qY8OGDRowYICioqLkcDi0evVqj/2WZWnKlCmKiopSUFCQunXrpq+//tpjTElJicaNG6cmTZooJCREAwcO1KFDhzzGFBQUKCUlRU6nU06nUykpKTpx4kS1sgIAgItXlQrRNddc476y7JprrtG1116ra665psLj2muvrdYPP336tDp06KB58+add//MmTM1e/ZszZs3T1u3blVkZKR69uypkydPusekpqZq1apVWrFihTZt2qRTp06pf//+HmuZhg0bpqysLKWlpSktLU1ZWVlKSUmpVlYAAHDxqtIps+zsbDVt2tT975rSt29f9e3b97z7LMvS3LlzNXnyZA0ePFiStGzZMrlcLr355pt66KGHVFhYqMWLF+u1115zL/Z+/fXXFR0drY8//li9e/fW7t27lZaWpszMTCUkJEiSFi1apMTERO3Zs0etW7eusfcDAADqpioVopiYmPP+25uys7OVl5enXr16ubcFBgYqKSlJGRkZeuihh7Rt2zadOXPGY0xUVJTi4uKUkZGh3r17a/PmzXI6ne4yJEmdO3eW0+lURkZGpYWopKREJSUl7ufcUgAAgIuXz37bfV5eniTJ5XJ5bHe5XO59eXl5CggIUKNGjS44JiIi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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "values = np.arange(0, 2500, 500)\n", + "value_increment = 1000\n", + "\n", + "# Get some pastel shades for the colors\n", + "colors = plt.cm.BuPu(np.linspace(0, 0.5, len(df)))\n", + "n_rows = len(df)\n", + "\n", + "index = np.arange(len(df.columns)-1) + 0.3\n", + "bar_width = 0.6\n", + "\n", + "# Initialize the vertical-offset for the stacked bar chart.\n", + "y_offset = np.zeros(len(df.columns)-1)\n", + "\n", + "# Plot bars and create text labels for the table\n", + "cell_text = []\n", + "for row in range(n_rows):\n", + " plt.bar(index, df.iloc[:, row], bar_width, bottom=y_offset, color=colors[row])\n", + " y_offset = y_offset + df.iloc[:, row]\n", + "\n", + "# Add labels and title\n", + "plt.ylabel(f\"Loss in ${value_increment}'s\")\n", + "plt.yticks(values * value_increment, ['%d' % val for val in values])\n", + "plt.title('Loss by Disaster')\n", + "\n", + "# Display the chart\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Add table on the chart\n", + "\n", + "Using the same code as before, we add the following elements:\n", + "\n", + "- It adjusts the layout with `plt.subplots_adjust(left=0.1, bottom=0.1)` to make room for the table at the bottom of the chart\n", + "- It **adds a table** at the bottom of the chart using `plt.table()`. This table includes the **text labels**, **row labels** (from the 'rows' column in the DataFrame), and column labels (from the DataFrame's columns)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "values = np.arange(0, 2500, 500)\n", + "value_increment = 1000\n", + "\n", + "# Get some pastel shades for the colors\n", + "colors = plt.cm.BuPu(np.linspace(0, 0.5, len(df)))\n", + "n_rows = len(df)\n", + "\n", + "index = np.arange(len(df.columns)-1) + 0.3\n", + "bar_width = 0.6\n", + "\n", + "# Initialize the vertical-offset for the stacked bar chart.\n", + "y_offset = np.zeros(len(df.columns)-1)\n", + "\n", + "# Plot bars and create text labels for the table\n", + "cell_text = []\n", + "for row in range(n_rows):\n", + " plt.bar(index, df.iloc[:, row], bar_width, bottom=y_offset, color=colors[row])\n", + " y_offset = y_offset + df.iloc[:, row]\n", + " cell_text.append(['%1.1f' % (x / 1000.0) for x in y_offset])\n", + "\n", + "# Reverse colors and text labels to display the last value at the top.\n", + "colors = colors[::-1]\n", + "cell_text.reverse()\n", + "\n", + "# Add a table at the bottom of the axes\n", + "the_table = plt.table(cellText=cell_text,\n", + " rowLabels=df['rows'],\n", + " rowColours=colors,\n", + " colLabels=df.columns,\n", + " loc='bottom')\n", + "\n", + "# Adjust layout to make room for the table:\n", + "plt.subplots_adjust(left=0.1, bottom=0.1)\n", + "\n", + "# Add label and title\n", + "plt.ylabel(f\"Loss in ${value_increment}'s\")\n", + "plt.yticks(values * value_increment, ['%d' % val for val in values])\n", + "plt.xticks([])\n", + "plt.title('Loss by Disaster')\n", + "\n", + "# Dislay the chart\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Going further\n", + "\n", + "This post explains how to create a bar chart with a table underneath using [matplotlib](https://python-graph-gallery.com/matplotlib/).\n", + "\n", + "For more examples of **how to create or customize** your bar plots, see the [barplot section](https://python-graph-gallery.com/barplot/). You may also be interested in how to [create a grouped barplot](https://python-graph-gallery.com/grouped-barplot/)." + ] + } + ], + "metadata": { + "chartType": "barplot", + "description": "Description: Creating chart with a table is a useful way to add more context to a chart. Matplotlib allows you to present information in a table underneath a barplpot very easily.
In this post we'll how to leverage Matplotlib code to create a stacked bar plot with the values in a table below the plot.", + "family": "ranking", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "keywords": "barplot, table, staked, matplotlib", + "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.9.13" + }, + "seoDescription": "How to create a barplot with a table underneath", + "slug": "552-table-combined-with-plot", + "title": "Barplot with table underneath" + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/src/notebooks/553-intro-candle-stick-plotly.ipynb b/src/notebooks/553-intro-candle-stick-plotly.ipynb new file mode 100644 index 0000000000..8a201f664a --- /dev/null +++ b/src/notebooks/553-intro-candle-stick-plotly.ipynb @@ -0,0 +1,2588 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Libraries\n", + "\n", + "First, we need to install the **plotly**:\n", + "\n", + "`pip install plotly`\n", + "\n", + "In this post, we'll use the `object oriented` API from plotly: you can find more info of why [here](https://python-graph-gallery.com/plotly/).\n", + "\n", + "And since we'll load **data from yahoo finance**, we need the `yfinance` library:\n", + "\n", + "`pip install yfinance`" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import plotly.graph_objects as go\n", + "import yfinance as yf" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dataset\n", + "\n", + "[Candlestick charts](https://python-graph-gallery.com/candlestick/) are mainly used to represent **financial data**, especially stock prices.\n", + "\n", + "In this post, we'll load Apple's share price data, directly from our **Python** code via the `yfinance` library. All we need to do is define the desired **start** and **end** data (`yyyy-mm-dd` format), and the **ticker** or symbol associated with this company (in this case `\"AAPL\"`).\n", + "\n", + "Our dataset must have the **characteristics** needed to produce our graph easily:\n", + "- be a pandas dataframe\n", + "- a date index\n", + "- an Open column\n", + "- a High column\n", + "- a Low column\n", + "- a Close column\n", + "\n", + "The **tickers** can be found on easily on [yahoo finance](https://finance.yahoo.com)." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[*********************100%%**********************] 1 of 1 completed\n" + ] + } + ], + "source": [ + "# Define the stock symbol and date range\n", + "stock_symbol = \"GOOGL\" # Example: Google\n", + "start_date = \"2021-01-01\"\n", + "end_date = \"2021-03-30\"\n", + "\n", + "# Load historical data\n", + "stock_data = yf.download(stock_symbol,\n", + " start=start_date, end=end_date)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Simple candlestick\n", + "\n", + "Once we've opened our dataset, we'll now **create the graph**.\n", + "\n", + "We have to **specify which column to use** for opening, closing etc. In our case, it's pretty intuitive:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "close": [ + 86.30650329589844, + 87.00250244140625, + 86.14399719238281, + 88.71700286865234, + 89.8915023803711, + 87.81449890136719, + 86.87149810791016, + 87.36250305175781, + 86.5459976196289, + 86.38099670410156, + 89.22350311279297, + 94.00350189208984, + 94.2074966430664, + 94.62799835205078, + 94.71399688720703, + 95.39749908447266, + 90.9469985961914, + 92.66000366210938, + 91.36799621582031, + 94.65350341796875, + 95.95600128173828, + 102.94400024414062, + 102.68150329589844, + 104.44149780273438, + 104.22599792480469, + 103.76950073242188, + 104.3239974975586, + 104.4375, + 104.75150299072266, + 105.53500366210938, + 105.93099975585938, + 105.29049682617188, + 104.44049835205078, + 102.71299743652344, + 103.00599670410156, + 104.19049835205078, + 100.79750061035156, + 101.09549713134766, + 103.48300170898438, + 103.2239990234375, + 100.57050323486328, + 101.69650268554688, + 104.85350036621094, + 100.375, + 102.01799774169922, + 101.80950164794922, + 105.0270004272461, + 102.5, + 102.72200012207031, + 104.19450378417969, + 104.11100006103516, + 101.06700134277344, + 101.3479995727539, + 101.53450012207031, + 102.06649780273438, + 101.62650299072266, + 101.62300109863281, + 101.23650360107422, + 102.28949737548828 + ], + "high": [ + 88.12449645996094, + 87.34149932861328, + 87.19850158691406, + 88.89099884033203, + 89.96800231933594, + 89.21900177001953, + 88.3949966430664, + 87.81950378417969, + 88.37750244140625, + 87.38099670410156, + 90.19200134277344, + 94.98600006103516, + 96.60399627685547, + 95.21949768066406, + 96.09100341796875, + 95.7874984741211, + 94.02349853515625, + 94.39949798583984, + 92.37699890136719, + 95.7770004272461, + 97.46849822998047, + 105.33100128173828, + 103.46499633789062, + 104.7969970703125, + 105.75, + 104.92549896240234, + 104.94400024414062, + 104.69999694824219, + 104.9749984741211, + 107.25700378417969, + 106.12200164794922, + 106.09950256347656, + 105.92900085449219, + 104.0165023803711, + 103.625, + 104.41600036621094, + 104.1500015258789, + 102.82599639892578, + 103.8115005493164, + 104.73699951171875, + 103.79949951171875, + 103.72949981689453, + 105.30999755859375, + 105.68699645996094, + 103.19599914550781, + 103.06999969482422, + 105.5634994506836, + 103.88050079345703, + 102.74949645996094, + 105.68399810791016, + 104.94999694824219, + 103.4375, + 101.85199737548828, + 102.41699981689453, + 103.20549774169922, + 103.37999725341797, + 102.28199768066406, + 101.96949768066406, + 102.46050262451172 + ], + "low": [ + 85.35700225830078, + 85.84500122070312, + 84.80500030517578, + 86.33799743652344, + 88.06099700927734, + 87.60700225830078, + 85.81900024414062, + 86.36599731445312, + 86.30349731445312, + 85.58550262451172, + 86.6415023803711, + 90.97550201416016, + 93.97049713134766, + 93.82499694824219, + 92.95800018310547, + 93.80650329589844, + 89.86399841308594, + 91.55000305175781, + 90.0780029296875, + 92.22949981689453, + 95.31849670410156, + 100.67749786376953, + 101.75499725341797, + 102.5, + 103.1675033569336, + 103.5, + 102.61199951171875, + 103.44300079345703, + 103.67849731445312, + 104.5875015258789, + 104.4175033569336, + 104.66649627685547, + 104.17150115966797, + 102.4000015258789, + 99.5114974975586, + 101.37650299072266, + 100.32450103759766, + 100.05049896240234, + 101.72100067138672, + 102.83350372314453, + 99.69999694824219, + 100.27149963378906, + 101.38899993896484, + 100.2594985961914, + 101.77999877929688, + 100.96649932861328, + 102.82250213623047, + 101.62100219726562, + 101.3895034790039, + 102.9645004272461, + 102.20600128173828, + 100.95899963378906, + 100.14649963378906, + 100.69999694824219, + 101.4000015258789, + 101.44999694824219, + 99.80449676513672, + 100.19249725341797, + 100.27249908447266 + ], + "open": [ + 88, + 86.25450134277344, + 85.01300048828125, + 86.33799743652344, + 88.85800170898438, + 88.85099792480469, + 87.26799774169922, + 86.36599731445312, + 87.44349670410156, + 86.45099639892578, + 87.1500015258789, + 91.31849670410156, + 94.68250274658203, + 94.572998046875, + 95.63700103759766, + 94.29949951171875, + 93.74549865722656, + 91.55000305175781, + 91.70099639892578, + 92.22949981689453, + 95.65650177001953, + 103.28050231933594, + 103.03099822998047, + 102.97799682617188, + 105, + 103.73999786376953, + 104.15699768066406, + 104.55000305175781, + 103.9885025024414, + 104.5875015258789, + 104.6989974975586, + 105.25, + 105.3895034790039, + 102.68000030517578, + 100.69950103759766, + 101.50199890136719, + 102.79650115966797, + 101.49749755859375, + 102.4000015258789, + 103.24199676513672, + 102.59750366210938, + 100.74349975585938, + 103.05750274658203, + 104.2030029296875, + 102.48750305175781, + 103.06999969482422, + 102.91100311279297, + 103.82050323486328, + 102.2490005493164, + 103.29949951171875, + 103.42350006103516, + 102.40899658203125, + 101.48650360107422, + 101.38150024414062, + 101.99749755859375, + 102.58799743652344, + 101.45249938964844, + 101.5895004272461, + 101.10800170898438 + ], + "type": "candlestick", + "x": [ + "2021-01-04T00:00:00", + "2021-01-05T00:00:00", + "2021-01-06T00:00:00", + "2021-01-07T00:00:00", + "2021-01-08T00:00:00", + "2021-01-11T00:00:00", + "2021-01-12T00:00:00", + "2021-01-13T00:00:00", + "2021-01-14T00:00:00", + "2021-01-15T00:00:00", + "2021-01-19T00:00:00", + "2021-01-20T00:00:00", + "2021-01-21T00:00:00", + "2021-01-22T00:00:00", + "2021-01-25T00:00:00", + "2021-01-26T00:00:00", + "2021-01-27T00:00:00", + "2021-01-28T00:00:00", + "2021-01-29T00:00:00", + "2021-02-01T00:00:00", + "2021-02-02T00:00:00", + "2021-02-03T00:00:00", + "2021-02-04T00:00:00", + "2021-02-05T00:00:00", + "2021-02-08T00:00:00", + "2021-02-09T00:00:00", + "2021-02-10T00:00:00", + "2021-02-11T00:00:00", + "2021-02-12T00:00:00", + "2021-02-16T00:00:00", + "2021-02-17T00:00:00", + "2021-02-18T00:00:00", + "2021-02-19T00:00:00", + "2021-02-22T00:00:00", + "2021-02-23T00:00:00", + "2021-02-24T00:00:00", + "2021-02-25T00:00:00", + "2021-02-26T00:00:00", + "2021-03-01T00:00:00", + "2021-03-02T00:00:00", + "2021-03-03T00:00:00", + "2021-03-04T00:00:00", + "2021-03-05T00:00:00", + "2021-03-08T00:00:00", + "2021-03-09T00:00:00", + "2021-03-10T00:00:00", + "2021-03-11T00:00:00", + "2021-03-12T00:00:00", + "2021-03-15T00:00:00", + "2021-03-16T00:00:00", + "2021-03-17T00:00:00", + "2021-03-18T00:00:00", + "2021-03-19T00:00:00", + "2021-03-22T00:00:00", + "2021-03-23T00:00:00", + "2021-03-24T00:00:00", + "2021-03-25T00:00:00", + "2021-03-26T00:00:00", + "2021-03-29T00:00:00" + ] + } + ], + "layout": { + "autosize": false, + "height": 500, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "width": 700, + "xaxis": { + "rangeslider": { + "visible": false + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = go.Figure(data=[go.Candlestick(\n", + " x = stock_data.index, # date values\n", + " open = stock_data['Open'],\n", + " high = stock_data['High'],\n", + " low = stock_data['Low'],\n", + " close = stock_data['Close'])])\n", + "\n", + "# Mask a default range slider\n", + "fig.update_layout(xaxis_rangeslider_visible=False)\n", + "\n", + "# Set layout size\n", + "fig.update_layout(\n", + " autosize=False,\n", + " width=700,\n", + " height=500)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's save the graph in a HTML file and display it in this website using an `iframe`" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# save this file as a standalong html file:\n", + "fig.write_html(\"../../static/interactiveCharts/candlestick-plotly-basic.html\")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%html\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Candle chart with a range slider\n", + "\n", + "[Plotly](https://python-graph-gallery.com/plotly/) lets us easily **add a slider** below the graph, which defines the date range displayed on the graph. \n", + "\n", + "To do this, simply **remove** the line of code from the graph above that specified that the slider should be hidden. " + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "close": [ + 86.30650329589844, + 87.00250244140625, + 86.14399719238281, + 88.71700286865234, + 89.8915023803711, + 87.81449890136719, + 86.87149810791016, + 87.36250305175781, + 86.5459976196289, + 86.38099670410156, + 89.22350311279297, + 94.00350189208984, + 94.2074966430664, + 94.62799835205078, + 94.71399688720703, + 95.39749908447266, + 90.9469985961914, + 92.66000366210938, + 91.36799621582031, + 94.65350341796875, + 95.95600128173828, + 102.94400024414062, + 102.68150329589844, + 104.44149780273438, + 104.22599792480469, + 103.76950073242188, + 104.3239974975586, + 104.4375, + 104.75150299072266, + 105.53500366210938, + 105.93099975585938, + 105.29049682617188, + 104.44049835205078, + 102.71299743652344, + 103.00599670410156, + 104.19049835205078, + 100.79750061035156, + 101.09549713134766, + 103.48300170898438, + 103.2239990234375, + 100.57050323486328, + 101.69650268554688, + 104.85350036621094, + 100.375, + 102.01799774169922, + 101.80950164794922, + 105.0270004272461, + 102.5, + 102.72200012207031, + 104.19450378417969, + 104.11100006103516, + 101.06700134277344, + 101.3479995727539, + 101.53450012207031, + 102.06649780273438, + 101.62650299072266, + 101.62300109863281, + 101.23650360107422, + 102.28949737548828 + ], + "high": [ + 88.12449645996094, + 87.34149932861328, + 87.19850158691406, + 88.89099884033203, + 89.96800231933594, + 89.21900177001953, + 88.3949966430664, + 87.81950378417969, + 88.37750244140625, + 87.38099670410156, + 90.19200134277344, + 94.98600006103516, + 96.60399627685547, + 95.21949768066406, + 96.09100341796875, + 95.7874984741211, + 94.02349853515625, + 94.39949798583984, + 92.37699890136719, + 95.7770004272461, + 97.46849822998047, + 105.33100128173828, + 103.46499633789062, + 104.7969970703125, + 105.75, + 104.92549896240234, + 104.94400024414062, + 104.69999694824219, + 104.9749984741211, + 107.25700378417969, + 106.12200164794922, + 106.09950256347656, + 105.92900085449219, + 104.0165023803711, + 103.625, + 104.41600036621094, + 104.1500015258789, + 102.82599639892578, + 103.8115005493164, + 104.73699951171875, + 103.79949951171875, + 103.72949981689453, + 105.30999755859375, + 105.68699645996094, + 103.19599914550781, + 103.06999969482422, + 105.5634994506836, + 103.88050079345703, + 102.74949645996094, + 105.68399810791016, + 104.94999694824219, + 103.4375, + 101.85199737548828, + 102.41699981689453, + 103.20549774169922, + 103.37999725341797, + 102.28199768066406, + 101.96949768066406, + 102.46050262451172 + ], + "low": [ + 85.35700225830078, + 85.84500122070312, + 84.80500030517578, + 86.33799743652344, + 88.06099700927734, + 87.60700225830078, + 85.81900024414062, + 86.36599731445312, + 86.30349731445312, + 85.58550262451172, + 86.6415023803711, + 90.97550201416016, + 93.97049713134766, + 93.82499694824219, + 92.95800018310547, + 93.80650329589844, + 89.86399841308594, + 91.55000305175781, + 90.0780029296875, + 92.22949981689453, + 95.31849670410156, + 100.67749786376953, + 101.75499725341797, + 102.5, + 103.1675033569336, + 103.5, + 102.61199951171875, + 103.44300079345703, + 103.67849731445312, + 104.5875015258789, + 104.4175033569336, + 104.66649627685547, + 104.17150115966797, + 102.4000015258789, + 99.5114974975586, + 101.37650299072266, + 100.32450103759766, + 100.05049896240234, + 101.72100067138672, + 102.83350372314453, + 99.69999694824219, + 100.27149963378906, + 101.38899993896484, + 100.2594985961914, + 101.77999877929688, + 100.96649932861328, + 102.82250213623047, + 101.62100219726562, + 101.3895034790039, + 102.9645004272461, + 102.20600128173828, + 100.95899963378906, + 100.14649963378906, + 100.69999694824219, + 101.4000015258789, + 101.44999694824219, + 99.80449676513672, + 100.19249725341797, + 100.27249908447266 + ], + "open": [ + 88, + 86.25450134277344, + 85.01300048828125, + 86.33799743652344, + 88.85800170898438, + 88.85099792480469, + 87.26799774169922, + 86.36599731445312, + 87.44349670410156, + 86.45099639892578, + 87.1500015258789, + 91.31849670410156, + 94.68250274658203, + 94.572998046875, + 95.63700103759766, + 94.29949951171875, + 93.74549865722656, + 91.55000305175781, + 91.70099639892578, + 92.22949981689453, + 95.65650177001953, + 103.28050231933594, + 103.03099822998047, + 102.97799682617188, + 105, + 103.73999786376953, + 104.15699768066406, + 104.55000305175781, + 103.9885025024414, + 104.5875015258789, + 104.6989974975586, + 105.25, + 105.3895034790039, + 102.68000030517578, + 100.69950103759766, + 101.50199890136719, + 102.79650115966797, + 101.49749755859375, + 102.4000015258789, + 103.24199676513672, + 102.59750366210938, + 100.74349975585938, + 103.05750274658203, + 104.2030029296875, + 102.48750305175781, + 103.06999969482422, + 102.91100311279297, + 103.82050323486328, + 102.2490005493164, + 103.29949951171875, + 103.42350006103516, + 102.40899658203125, + 101.48650360107422, + 101.38150024414062, + 101.99749755859375, + 102.58799743652344, + 101.45249938964844, + 101.5895004272461, + 101.10800170898438 + ], + "type": "candlestick", + "x": [ + "2021-01-04T00:00:00", + "2021-01-05T00:00:00", + "2021-01-06T00:00:00", + "2021-01-07T00:00:00", + "2021-01-08T00:00:00", + "2021-01-11T00:00:00", + "2021-01-12T00:00:00", + "2021-01-13T00:00:00", + "2021-01-14T00:00:00", + "2021-01-15T00:00:00", + "2021-01-19T00:00:00", + "2021-01-20T00:00:00", + "2021-01-21T00:00:00", + "2021-01-22T00:00:00", + "2021-01-25T00:00:00", + "2021-01-26T00:00:00", + "2021-01-27T00:00:00", + "2021-01-28T00:00:00", + "2021-01-29T00:00:00", + "2021-02-01T00:00:00", + "2021-02-02T00:00:00", + "2021-02-03T00:00:00", + "2021-02-04T00:00:00", + "2021-02-05T00:00:00", + "2021-02-08T00:00:00", + "2021-02-09T00:00:00", + "2021-02-10T00:00:00", + "2021-02-11T00:00:00", + "2021-02-12T00:00:00", + "2021-02-16T00:00:00", + "2021-02-17T00:00:00", + "2021-02-18T00:00:00", + "2021-02-19T00:00:00", + "2021-02-22T00:00:00", + "2021-02-23T00:00:00", + "2021-02-24T00:00:00", + "2021-02-25T00:00:00", + "2021-02-26T00:00:00", + "2021-03-01T00:00:00", + "2021-03-02T00:00:00", + "2021-03-03T00:00:00", + "2021-03-04T00:00:00", + "2021-03-05T00:00:00", + "2021-03-08T00:00:00", + "2021-03-09T00:00:00", + "2021-03-10T00:00:00", + "2021-03-11T00:00:00", + "2021-03-12T00:00:00", + "2021-03-15T00:00:00", + "2021-03-16T00:00:00", + "2021-03-17T00:00:00", + "2021-03-18T00:00:00", + "2021-03-19T00:00:00", + "2021-03-22T00:00:00", + "2021-03-23T00:00:00", + "2021-03-24T00:00:00", + "2021-03-25T00:00:00", + "2021-03-26T00:00:00", + "2021-03-29T00:00:00" + ] + } + ], + "layout": { + "autosize": false, + "height": 500, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "width": 700 + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = go.Figure(data=[go.Candlestick(\n", + " x = stock_data.index, # date values\n", + " open = stock_data['Open'],\n", + " high = stock_data['High'],\n", + " low = stock_data['Low'],\n", + " close = stock_data['Close'])])\n", + "\n", + "# Set layout size\n", + "fig.update_layout(\n", + " autosize=False,\n", + " width=700,\n", + " height=500)\n", + "\n", + "# Display the plot\n", + "fig.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's save the graph in a HTML file and display it in this website using an `iframe`" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# save this file as a standalong html file:\n", + "fig.write_html(\"../../static/interactiveCharts/candlestick-plotly-basic-2.html\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%html\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Going further\n", + "\n", + "This post explains how to create a candlestick chart with [plotly](https://python-graph-gallery.com/plotly/).\n", + "\n", + "For more examples of **how to create or customize** your candlesticks plots, see the [candlestick section](https://python-graph-gallery.com/candlestick/). You may also be interested in how to [custom style of a plotly candlestick chart](https://python-graph-gallery.com/554-custom-candle-stick-plotly/)." + ] + } + ], + "metadata": { + "chartType": "candlestick", + "description": "A candlestick chart, created using the Plotly library in Python, is a graphical representation of financial data. It displays price movements over a specific time period, typically used in stock market analysis. Candlestick charts are composed of individual 'candlesticks', each representing the opening, closing, high, and low prices for a given time interval. These candlesticks are displayed on a two-dimensional coordinate system, with one axis representing time and the other axis representing price.

Plotly has a Candlestick() function that provides the capability to create candlestick charts easily. In this post, we'll create simple candlestick charts with this library. ", + "family": "evolution", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "keywords": "candlestick, plotly, finance, plot, chart", + "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.9.13" + }, + "seoDescription": "How to create a candlestick plot with plotly", + "slug": "553-intro-candle-stick-plotly", + "title": "Introduction to candlestick chart with plotly" + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/src/notebooks/554-custom-candle-stick-plotly.ipynb b/src/notebooks/554-custom-candle-stick-plotly.ipynb new file mode 100644 index 0000000000..e27fbcbc39 --- /dev/null +++ b/src/notebooks/554-custom-candle-stick-plotly.ipynb @@ -0,0 +1,2700 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Libraries\n", + "\n", + "First, we need to install the **plotly**:\n", + "\n", + "`pip install plotly`\n", + "\n", + "And since we'll load **data from yahoo finance**, we need the `yfinance` library:\n", + "\n", + "`pip install yfinance`" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import plotly.graph_objects as go\n", + "import yfinance as yf" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dataset\n", + "\n", + "[Candlestick charts](https://python-graph-gallery.com/candlestick/) are mainly used to represent **financial data**, especially stock prices.\n", + "\n", + "In this post, we'll load Apple's share price data, directly from our **Python** code via the `yfinance` library. All we need to do is define the desired **start** and **end** data (`yyyy-mm-dd` format), and the **ticker** or symbol associated with this company (in this case `\"AAPL\"`).\n", + "\n", + "Our dataset must have the **characteristics** needed to produce our graph easily:\n", + "- be a pandas dataframe\n", + "- a date index\n", + "- an Open column\n", + "- a High column\n", + "- a Low column\n", + "- a Close column\n", + "\n", + "The **tickers** can be found on easily on [yahoo finance](https://finance.yahoo.com)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[*********************100%%**********************] 1 of 1 completed\n" + ] + } + ], + "source": [ + "# Define the stock symbol and date range\n", + "stock_symbol = \"^FCHI\" # Example: CAC40 (largest French companies)\n", + "start_date = \"2022-01-01\"\n", + "end_date = \"2022-03-30\"\n", + "\n", + "# Load historical data\n", + "stock_data = yf.download(stock_symbol,\n", + " start=start_date, end=end_date)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Candlestick with custom colors\n", + "\n", + "Once we've opened our dataset, we'll now **create the graph**. We have to **specify which column to use** for opening, closing etc. \n", + "\n", + "In order to **change the colors**, we need to add the `increasing_line_color` and `decreasing_line_color` arguments with the desired colors." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "close": [ + 7217.22021484375, + 7317.41015625, + 7376.3701171875, + 7249.66015625, + 7219.47998046875, + 7115.77001953125, + 7183.3798828125, + 7237.18994140625, + 7201.14013671875, + 7143, + 7201.64013671875, + 7133.830078125, + 7172.97998046875, + 7194.16015625, + 7068.58984375, + 6787.7900390625, + 6837.9599609375, + 6981.9599609375, + 7023.7998046875, + 6965.8798828125, + 6999.2001953125, + 7099.490234375, + 7115.27001953125, + 7005.6298828125, + 6951.3798828125, + 7009.25, + 7028.41015625, + 7130.8798828125, + 7101.5498046875, + 7011.60009765625, + 6852.2001953125, + 6979.97021484375, + 6964.97998046875, + 6946.81982421875, + 6929.6298828125, + 6788.33984375, + 6787.60009765625, + 6780.669921875, + 6521.0498046875, + 6752.43017578125, + 6658.830078125, + 6396.490234375, + 6498.02001953125, + 6378.3701171875, + 6061.66015625, + 5982.27001953125, + 5962.9599609375, + 6387.830078125, + 6207.2001953125, + 6260.25, + 6369.93994140625, + 6355, + 6588.64013671875, + 6612.52001953125, + 6620.240234375, + 6582.330078125, + 6659.41015625, + 6581.43017578125, + 6555.77001953125, + 6553.68017578125, + 6589.10986328125, + 6792.16015625 + ], + "decreasing": { + "line": { + "color": "orange" + } + }, + "high": [ + 7245.66015625, + 7332.2099609375, + 7384.85986328125, + 7316.06005859375, + 7269.64990234375, + 7250.240234375, + 7227.7099609375, + 7249.8798828125, + 7227.35009765625, + 7171.39990234375, + 7213.7001953125, + 7175.4599609375, + 7211.240234375, + 7199.97021484375, + 7122.06005859375, + 7070.919921875, + 6890.5400390625, + 7024.14013671875, + 7053.4501953125, + 7053, + 7043.22021484375, + 7105.22998046875, + 7150.5400390625, + 7125.580078125, + 7066.43994140625, + 7025.58984375, + 7085.64013671875, + 7146.31005859375, + 7169.6298828125, + 7071.009765625, + 6875.31005859375, + 6983.14013671875, + 7031.93017578125, + 7017.06982421875, + 6995.6201171875, + 6986.830078125, + 6834.77001953125, + 6904.81005859375, + 6617.08984375, + 6762.77978515625, + 6684.5400390625, + 6662.25, + 6544.14990234375, + 6543.77001953125, + 6321.08984375, + 6115.22998046875, + 6169.60009765625, + 6387.830078125, + 6380.77001953125, + 6466.1201171875, + 6421.080078125, + 6383.75, + 6680, + 6635.31005859375, + 6620.240234375, + 6642.4599609375, + 6666.83984375, + 6684.7001953125, + 6636.580078125, + 6615.89990234375, + 6683.7001953125, + 6829.39990234375 + ], + "increasing": { + "line": { + "color": "purple" + } + }, + "low": [ + 7195.81982421875, + 7250.240234375, + 7313.52978515625, + 7240.8798828125, + 7178.18017578125, + 7105.5498046875, + 7160.43994140625, + 7183.3798828125, + 7166.93994140625, + 7119.009765625, + 7148.97998046875, + 7098.18994140625, + 7104.10986328125, + 7123.6201171875, + 7013.490234375, + 6754.240234375, + 6776.7998046875, + 6901.740234375, + 6873.60009765625, + 6846.22021484375, + 6937.10009765625, + 7035.91015625, + 7109.2998046875, + 6995.41015625, + 6914.77001953125, + 6929.7099609375, + 6994.14990234375, + 7086.33984375, + 7051.60009765625, + 6992.08984375, + 6757.330078125, + 6823.4501953125, + 6931.08984375, + 6905.68994140625, + 6895.08984375, + 6744.1298828125, + 6633.740234375, + 6768.3798828125, + 6432.89013671875, + 6521.56005859375, + 6516.16015625, + 6396.490234375, + 6312.2998046875, + 6361.60009765625, + 6061.66015625, + 5756.3798828125, + 5903.10009765625, + 6122.7998046875, + 6166.10986328125, + 6165.41015625, + 6271.81982421875, + 6206.0498046875, + 6481.7001953125, + 6530.7900390625, + 6499.58984375, + 6574.06982421875, + 6578.91015625, + 6559.31005859375, + 6541.31982421875, + 6538.7998046875, + 6572.009765625, + 6658.77978515625 + ], + "open": [ + 7197.39990234375, + 7273.56982421875, + 7320.47998046875, + 7264, + 7250.7900390625, + 7245.2099609375, + 7185.2099609375, + 7235.47021484375, + 7215.47998046875, + 7132.58984375, + 7167.52978515625, + 7172.43017578125, + 7104.10986328125, + 7190.02001953125, + 7088.43994140625, + 7014.83984375, + 6870.27001953125, + 6901.740234375, + 6879.64013671875, + 7043.43017578125, + 7039.7099609375, + 7052.2998046875, + 7117.4501953125, + 7115.2998046875, + 7049.7998046875, + 6987.169921875, + 7008.2001953125, + 7086.33984375, + 7141.68994140625, + 7025.5, + 6868.06982421875, + 6830.740234375, + 7009.68994140625, + 6999.1298828125, + 6951.830078125, + 6984.31005859375, + 6633.740234375, + 6801.66015625, + 6496.25, + 6571.9501953125, + 6620.47998046875, + 6646.16015625, + 6359.97998046875, + 6488.25, + 6308.33984375, + 5887.830078125, + 5906.6201171875, + 6131.27978515625, + 6376.56982421875, + 6233.1201171875, + 6298.9599609375, + 6294.72021484375, + 6484.330078125, + 6617.22998046875, + 6613.9501953125, + 6608.7900390625, + 6586.64990234375, + 6674.68017578125, + 6593.14990234375, + 6569.4501953125, + 6578.72021484375, + 6675.14990234375 + ], + "type": "candlestick", + "x": [ + "2022-01-03T00:00:00", + "2022-01-04T00:00:00", + "2022-01-05T00:00:00", + "2022-01-06T00:00:00", + "2022-01-07T00:00:00", + "2022-01-10T00:00:00", + "2022-01-11T00:00:00", + "2022-01-12T00:00:00", + "2022-01-13T00:00:00", + "2022-01-14T00:00:00", + "2022-01-17T00:00:00", + "2022-01-18T00:00:00", + "2022-01-19T00:00:00", + "2022-01-20T00:00:00", + "2022-01-21T00:00:00", + "2022-01-24T00:00:00", + "2022-01-25T00:00:00", + "2022-01-26T00:00:00", + "2022-01-27T00:00:00", + "2022-01-28T00:00:00", + "2022-01-31T00:00:00", + "2022-02-01T00:00:00", + "2022-02-02T00:00:00", + "2022-02-03T00:00:00", + "2022-02-04T00:00:00", + "2022-02-07T00:00:00", + "2022-02-08T00:00:00", + "2022-02-09T00:00:00", + "2022-02-10T00:00:00", + "2022-02-11T00:00:00", + "2022-02-14T00:00:00", + "2022-02-15T00:00:00", + "2022-02-16T00:00:00", + "2022-02-17T00:00:00", + "2022-02-18T00:00:00", + "2022-02-21T00:00:00", + "2022-02-22T00:00:00", + "2022-02-23T00:00:00", + "2022-02-24T00:00:00", + "2022-02-25T00:00:00", + "2022-02-28T00:00:00", + "2022-03-01T00:00:00", + "2022-03-02T00:00:00", + "2022-03-03T00:00:00", + "2022-03-04T00:00:00", + "2022-03-07T00:00:00", + "2022-03-08T00:00:00", + "2022-03-09T00:00:00", + "2022-03-10T00:00:00", + "2022-03-11T00:00:00", + "2022-03-14T00:00:00", + "2022-03-15T00:00:00", + "2022-03-16T00:00:00", + "2022-03-17T00:00:00", + "2022-03-18T00:00:00", + "2022-03-21T00:00:00", + "2022-03-22T00:00:00", + "2022-03-23T00:00:00", + "2022-03-24T00:00:00", + "2022-03-25T00:00:00", + "2022-03-28T00:00:00", + "2022-03-29T00:00:00" + ] + } + ], + "layout": { + "autosize": false, + "height": 500, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "width": 700, + "xaxis": { + "rangeslider": { + "visible": false + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = go.Figure(data=[go.Candlestick(\n", + " x = stock_data.index, # date values\n", + " open = stock_data['Open'],\n", + " high = stock_data['High'],\n", + " low = stock_data['Low'],\n", + " close = stock_data['Close'],\n", + " increasing_line_color = 'purple',\n", + " decreasing_line_color = 'orange')])\n", + "\n", + "# Mask a default range slider\n", + "fig.update_layout(xaxis_rangeslider_visible=False)\n", + "\n", + "# Set layout size\n", + "fig.update_layout(\n", + " autosize=False,\n", + " width=700,\n", + " height=500)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's save the graph in a HTML file and display it in this website using an `iframe`" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# save this file as a standalong html file:\n", + "fig.write_html(\"../../static/interactiveCharts/candlestick-plotly-custom.html\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%html\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Custom layout\n", + "\n", + "- **Title**: Added a title to the chart using `update_layout`\n", + "\n", + "- **Background Color**: Set the background color of the plot to white\n", + "\n", + "- **Grid Lines**: Added grid lines to both the `x` and `y` axes for easier reference\n", + "\n", + "- **Candlestick Border Customization**: Customized the color and width of the candlestick borders for increasing (`purple`) and decreasing (`orange`) periods\n", + "\n", + "- **Range Slider**: Enabled the range slider for zooming in and out on the `x-axis`. Customized its appearance by setting the thickness, background color, border color, and border width\n", + "\n", + "These customizations enhance the aesthetics and functionality of your candlestick chart, making it more **informative** and visually **appealing**." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "close": [ + 7217.22021484375, + 7317.41015625, + 7376.3701171875, + 7249.66015625, + 7219.47998046875, + 7115.77001953125, + 7183.3798828125, + 7237.18994140625, + 7201.14013671875, + 7143, + 7201.64013671875, + 7133.830078125, + 7172.97998046875, + 7194.16015625, + 7068.58984375, + 6787.7900390625, + 6837.9599609375, + 6981.9599609375, + 7023.7998046875, + 6965.8798828125, + 6999.2001953125, + 7099.490234375, + 7115.27001953125, + 7005.6298828125, + 6951.3798828125, + 7009.25, + 7028.41015625, + 7130.8798828125, + 7101.5498046875, + 7011.60009765625, + 6852.2001953125, + 6979.97021484375, + 6964.97998046875, + 6946.81982421875, + 6929.6298828125, + 6788.33984375, + 6787.60009765625, + 6780.669921875, + 6521.0498046875, + 6752.43017578125, + 6658.830078125, + 6396.490234375, + 6498.02001953125, + 6378.3701171875, + 6061.66015625, + 5982.27001953125, + 5962.9599609375, + 6387.830078125, + 6207.2001953125, + 6260.25, + 6369.93994140625, + 6355, + 6588.64013671875, + 6612.52001953125, + 6620.240234375, + 6582.330078125, + 6659.41015625, + 6581.43017578125, + 6555.77001953125, + 6553.68017578125, + 6589.10986328125, + 6792.16015625 + ], + "decreasing": { + "line": { + "color": "orange" + } + }, + "high": [ + 7245.66015625, + 7332.2099609375, + 7384.85986328125, + 7316.06005859375, + 7269.64990234375, + 7250.240234375, + 7227.7099609375, + 7249.8798828125, + 7227.35009765625, + 7171.39990234375, + 7213.7001953125, + 7175.4599609375, + 7211.240234375, + 7199.97021484375, + 7122.06005859375, + 7070.919921875, + 6890.5400390625, + 7024.14013671875, + 7053.4501953125, + 7053, + 7043.22021484375, + 7105.22998046875, + 7150.5400390625, + 7125.580078125, + 7066.43994140625, + 7025.58984375, + 7085.64013671875, + 7146.31005859375, + 7169.6298828125, + 7071.009765625, + 6875.31005859375, + 6983.14013671875, + 7031.93017578125, + 7017.06982421875, + 6995.6201171875, + 6986.830078125, + 6834.77001953125, + 6904.81005859375, + 6617.08984375, + 6762.77978515625, + 6684.5400390625, + 6662.25, + 6544.14990234375, + 6543.77001953125, + 6321.08984375, + 6115.22998046875, + 6169.60009765625, + 6387.830078125, + 6380.77001953125, + 6466.1201171875, + 6421.080078125, + 6383.75, + 6680, + 6635.31005859375, + 6620.240234375, + 6642.4599609375, + 6666.83984375, + 6684.7001953125, + 6636.580078125, + 6615.89990234375, + 6683.7001953125, + 6829.39990234375 + ], + "increasing": { + "line": { + "color": "purple" + } + }, + "low": [ + 7195.81982421875, + 7250.240234375, + 7313.52978515625, + 7240.8798828125, + 7178.18017578125, + 7105.5498046875, + 7160.43994140625, + 7183.3798828125, + 7166.93994140625, + 7119.009765625, + 7148.97998046875, + 7098.18994140625, + 7104.10986328125, + 7123.6201171875, + 7013.490234375, + 6754.240234375, + 6776.7998046875, + 6901.740234375, + 6873.60009765625, + 6846.22021484375, + 6937.10009765625, + 7035.91015625, + 7109.2998046875, + 6995.41015625, + 6914.77001953125, + 6929.7099609375, + 6994.14990234375, + 7086.33984375, + 7051.60009765625, + 6992.08984375, + 6757.330078125, + 6823.4501953125, + 6931.08984375, + 6905.68994140625, + 6895.08984375, + 6744.1298828125, + 6633.740234375, + 6768.3798828125, + 6432.89013671875, + 6521.56005859375, + 6516.16015625, + 6396.490234375, + 6312.2998046875, + 6361.60009765625, + 6061.66015625, + 5756.3798828125, + 5903.10009765625, + 6122.7998046875, + 6166.10986328125, + 6165.41015625, + 6271.81982421875, + 6206.0498046875, + 6481.7001953125, + 6530.7900390625, + 6499.58984375, + 6574.06982421875, + 6578.91015625, + 6559.31005859375, + 6541.31982421875, + 6538.7998046875, + 6572.009765625, + 6658.77978515625 + ], + "name": "Candlesticks", + "open": [ + 7197.39990234375, + 7273.56982421875, + 7320.47998046875, + 7264, + 7250.7900390625, + 7245.2099609375, + 7185.2099609375, + 7235.47021484375, + 7215.47998046875, + 7132.58984375, + 7167.52978515625, + 7172.43017578125, + 7104.10986328125, + 7190.02001953125, + 7088.43994140625, + 7014.83984375, + 6870.27001953125, + 6901.740234375, + 6879.64013671875, + 7043.43017578125, + 7039.7099609375, + 7052.2998046875, + 7117.4501953125, + 7115.2998046875, + 7049.7998046875, + 6987.169921875, + 7008.2001953125, + 7086.33984375, + 7141.68994140625, + 7025.5, + 6868.06982421875, + 6830.740234375, + 7009.68994140625, + 6999.1298828125, + 6951.830078125, + 6984.31005859375, + 6633.740234375, + 6801.66015625, + 6496.25, + 6571.9501953125, + 6620.47998046875, + 6646.16015625, + 6359.97998046875, + 6488.25, + 6308.33984375, + 5887.830078125, + 5906.6201171875, + 6131.27978515625, + 6376.56982421875, + 6233.1201171875, + 6298.9599609375, + 6294.72021484375, + 6484.330078125, + 6617.22998046875, + 6613.9501953125, + 6608.7900390625, + 6586.64990234375, + 6674.68017578125, + 6593.14990234375, + 6569.4501953125, + 6578.72021484375, + 6675.14990234375 + ], + "type": "candlestick", + "x": [ + "2022-01-03T00:00:00", + "2022-01-04T00:00:00", + "2022-01-05T00:00:00", + "2022-01-06T00:00:00", + "2022-01-07T00:00:00", + "2022-01-10T00:00:00", + "2022-01-11T00:00:00", + "2022-01-12T00:00:00", + "2022-01-13T00:00:00", + "2022-01-14T00:00:00", + "2022-01-17T00:00:00", + "2022-01-18T00:00:00", + "2022-01-19T00:00:00", + "2022-01-20T00:00:00", + "2022-01-21T00:00:00", + "2022-01-24T00:00:00", + "2022-01-25T00:00:00", + "2022-01-26T00:00:00", + "2022-01-27T00:00:00", + "2022-01-28T00:00:00", + "2022-01-31T00:00:00", + "2022-02-01T00:00:00", + "2022-02-02T00:00:00", + "2022-02-03T00:00:00", + "2022-02-04T00:00:00", + "2022-02-07T00:00:00", + "2022-02-08T00:00:00", + "2022-02-09T00:00:00", + "2022-02-10T00:00:00", + "2022-02-11T00:00:00", + "2022-02-14T00:00:00", + "2022-02-15T00:00:00", + "2022-02-16T00:00:00", + "2022-02-17T00:00:00", + "2022-02-18T00:00:00", + "2022-02-21T00:00:00", + "2022-02-22T00:00:00", + "2022-02-23T00:00:00", + "2022-02-24T00:00:00", + "2022-02-25T00:00:00", + "2022-02-28T00:00:00", + "2022-03-01T00:00:00", + "2022-03-02T00:00:00", + "2022-03-03T00:00:00", + "2022-03-04T00:00:00", + "2022-03-07T00:00:00", + "2022-03-08T00:00:00", + "2022-03-09T00:00:00", + "2022-03-10T00:00:00", + "2022-03-11T00:00:00", + "2022-03-14T00:00:00", + "2022-03-15T00:00:00", + "2022-03-16T00:00:00", + "2022-03-17T00:00:00", + "2022-03-18T00:00:00", + "2022-03-21T00:00:00", + "2022-03-22T00:00:00", + "2022-03-23T00:00:00", + "2022-03-24T00:00:00", + "2022-03-25T00:00:00", + "2022-03-28T00:00:00", + "2022-03-29T00:00:00" + ] + } + ], + "layout": { + "autosize": false, + "height": 500, + "plot_bgcolor": "white", + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "font": { + "family": "Arial", + "size": 24 + }, + "text": "Stock Price Candlestick Chart", + "x": 0.5 + }, + "width": 700, + "xaxis": { + "gridcolor": "lightgray", + "gridwidth": 1, + "rangeslider": { + "bordercolor": "black", + "borderwidth": 1, + "thickness": 0.05, + "visible": true + }, + "showgrid": true + }, + "yaxis": { + "gridcolor": "lightgray", + "gridwidth": 1, + "showgrid": true + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = go.Figure(data=[go.Candlestick(\n", + " x = stock_data.index, # date values\n", + " open = stock_data['Open'],\n", + " high = stock_data['High'],\n", + " low = stock_data['Low'],\n", + " close = stock_data['Close'],\n", + " increasing_line_color = 'purple',\n", + " decreasing_line_color = 'orange',\n", + " name='Candlesticks')])\n", + "\n", + "# Add a title\n", + "fig.update_layout(\n", + " title=\"Stock Price Candlestick Chart\",\n", + " title_x=0.5, # Center the title\n", + "\n", + " # Customize the font and size of the title\n", + " title_font=dict(size=24, family=\"Arial\"),\n", + "\n", + " # Set the background color of the plot\n", + " plot_bgcolor='white',\n", + "\n", + " # Customize the grid lines\n", + " xaxis=dict(showgrid=True, gridwidth=1, gridcolor='lightgray'),\n", + " yaxis=dict(showgrid=True, gridwidth=1, gridcolor='lightgray'),\n", + ")\n", + "\n", + "# Add a range slider and customize it\n", + "fig.update_layout(\n", + " xaxis_rangeslider_visible=True, # Show the range slider\n", + "\n", + " # Customize the range slider's appearance\n", + " xaxis_rangeslider=dict(\n", + " thickness=0.05, # Set the thickness of the slider\n", + " bordercolor='black', # Set the border color\n", + " borderwidth=1, # Set the border width\n", + " )\n", + ")\n", + "\n", + "# Set layout size\n", + "fig.update_layout(\n", + " autosize=False,\n", + " width=700, \n", + " height=500)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's save the graph in a HTML file and display it in this website using an `iframe`" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# save this file as a standalong html file:\n", + "fig.write_html(\"../../static/interactiveCharts/candlestick-plotly-custom-2.html\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%html\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Going further\n", + "\n", + "This post explains how to create a candlestick chart with [plotly](https://python-graph-gallery.com/plotly/).\n", + "\n", + "For more examples of **how to create or customize** your candlesticks plots, see the [candlestick section](https://python-graph-gallery.com/candlestick/). You may also be interested in how to [add moving averages to a plotly candlestick chart](https://python-graph-gallery.com/555-candle-stick-with-moving-average-plotly/)." + ] + } + ], + "metadata": { + "chartType": "candlestick", + "description": "A candlestick chart, created using the Plotly library in Python, is a graphical representation of financial data. It displays price movements over a specific time period, typically used in stock market analysis. Candlestick charts are composed of individual 'candlesticks', each representing the opening, closing, high, and low prices for a given time interval. These candlesticks are displayed on a two-dimensional coordinate system, with one axis representing time and the other axis representing price.

Plotly has a Candlestick() function that provides the capability to create candlestick charts easily. In this post, we'll see how to customize candlestick charts with this library. You might first want to take a look at this intro to candlestick with plotly", + "family": "evolution", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "keywords": "candlestick, plotly, finance, plot, chart, customize", + "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.9.13" + }, + "seoDescription": "How to customize a candlestick chart with plotly", + "slug": "554-custom-candle-stick-plotly", + "title": "Customize candlestick chart with plotly" + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/src/notebooks/555-candle-stick-with-moving-average-plotly.ipynb b/src/notebooks/555-candle-stick-with-moving-average-plotly.ipynb new file mode 100644 index 0000000000..a4d3a736a9 --- /dev/null +++ b/src/notebooks/555-candle-stick-with-moving-average-plotly.ipynb @@ -0,0 +1,4625 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Libraries\n", + "\n", + "First, we need to install the **plotly**:\n", + "\n", + "`pip install plotly`\n", + "\n", + "And since we'll load **data from yahoo finance**, we need the `yfinance` library:\n", + "\n", + "`pip install yfinance`\n", + "\n", + "We'll also need the `pandas` module to calculate the moving average." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import plotly.graph_objects as go\n", + "import yfinance as yf\n", + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dataset\n", + "\n", + "[Candlestick charts](https://python-graph-gallery.com/candlestick/) are mainly used to represent **financial data**, especially stock prices.\n", + "\n", + "In this post, we'll load Apple's share price data, directly from our **Python** code via the `yfinance` library. All we need to do is define the desired **start** and **end** data (`yyyy-mm-dd` format), and the **ticker** or symbol associated with this company (in this case `\"AAPL\"`).\n", + "\n", + "Our dataset must have the **characteristics** needed to produce our graph easily:\n", + "- be a pandas dataframe\n", + "- a date index\n", + "- an Open column\n", + "- a High column\n", + "- a Low column\n", + "- a Close column\n", + "\n", + "The **tickers** can be found on easily on [yahoo finance](https://finance.yahoo.com)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[*********************100%%**********************] 1 of 1 completed\n" + ] + } + ], + "source": [ + "# Define the stock symbol and date range\n", + "stock_symbol = \"^FCHI\" # Example: CAC40 (largest French companies)\n", + "start_date = \"2020-01-01\"\n", + "end_date = \"2020-03-30\"\n", + "\n", + "# Load historical data\n", + "stock_data = yf.download(stock_symbol,\n", + " start=start_date, end=end_date)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Once we have our dataset, we just need to **calculate the moving averages**. Thanks to the `rolling()` function from [pandas](https://python-graph-gallery.com/pandas/), it's actually pretty easy:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Moving average over a window of 3 and 8\n", + "stock_data['moving3'] = stock_data['Close'].rolling(3).mean()\n", + "stock_data['moving8'] = stock_data['Close'].rolling(8).mean()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Candlestick with one moving average\n", + "\n", + "Once we've opened our dataset, we'll now **create the graph**. We have to **specify which column to use** for opening, closing etc. \n", + "\n", + "To add the moving average, all we need to do is add an `Scatter` to the `data` argument, and specify the values on the **x-axis** (in this case, time) and those on the **y-axis** (the moving average calculated previously). " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "close": [ + 6041.5, + 6044.16015625, + 6013.58984375, + 6012.35009765625, + 6031, + 6042.5498046875, + 6037.10986328125, + 6036.14013671875, + 6040.89013671875, + 6032.60986328125, + 6039.02978515625, + 6100.72021484375, + 6078.5400390625, + 6045.990234375, + 6010.97998046875, + 5971.7900390625, + 6024.259765625, + 5863.02001953125, + 5925.81982421875, + 5954.89013671875, + 5871.77001953125, + 5806.33984375, + 5832.509765625, + 5935.0498046875, + 5985.39990234375, + 6038.18017578125, + 6029.75, + 6015.669921875, + 6054.759765625, + 6104.72998046875, + 6093.14013671875, + 6069.35009765625, + 6085.9501953125, + 6056.81982421875, + 6111.240234375, + 6062.2998046875, + 6029.72021484375, + 5791.8701171875, + 5679.68017578125, + 5684.5498046875, + 5495.60009765625, + 5309.89990234375, + 5333.52001953125, + 5393.169921875, + 5464.89013671875, + 5361.10009765625, + 5139.10986328125, + 4707.91015625, + 4636.60986328125, + 4610.25, + 4044.260009765625, + 4118.35986328125, + 3881.4599609375, + 3991.780029296875, + 3754.840087890625, + 3855.5, + 4048.800048828125, + 3914.31005859375, + 4242.7001953125, + 4432.2998046875, + 4543.580078125, + 4351.490234375 + ], + "high": [ + 6062.919921875, + 6044.16015625, + 6017.97021484375, + 6065.740234375, + 6031, + 6071.66015625, + 6057.830078125, + 6058.68994140625, + 6046.1201171875, + 6053.009765625, + 6058.97021484375, + 6109.81005859375, + 6094.08984375, + 6045.990234375, + 6069.259765625, + 6024.31982421875, + 6064.5498046875, + 5942.830078125, + 5933.72021484375, + 5969.72998046875, + 5904.080078125, + 5894.68994140625, + 5857.39990234375, + 5935.0498046875, + 6004.330078125, + 6050.93994140625, + 6044.97021484375, + 6018.31005859375, + 6060.97021484375, + 6104.72998046875, + 6098.259765625, + 6096.06982421875, + 6088.60009765625, + 6079.5, + 6111.41015625, + 6110.9501953125, + 6067.2900390625, + 5884.85986328125, + 5828.4599609375, + 5707.31005859375, + 5613.72021484375, + 5376.0498046875, + 5430.0498046875, + 5509.27978515625, + 5493.25, + 5494.16015625, + 5284.080078125, + 4863.33984375, + 4924.83984375, + 4766, + 4404.259765625, + 4438.509765625, + 3962.010009765625, + 4042.4599609375, + 3908.719970703125, + 3909.14990234375, + 4109.10986328125, + 4097.81982421875, + 4242.7001953125, + 4453.009765625, + 4543.580078125, + 4471.3701171875 + ], + "low": [ + 6011.2099609375, + 5994.58984375, + 5955.25, + 6000, + 5972.77001953125, + 6034.14990234375, + 6028.2900390625, + 6018.330078125, + 5980.0498046875, + 6011.27978515625, + 6021.02978515625, + 6066.2900390625, + 6071.169921875, + 5994.169921875, + 6005.77001953125, + 5961.8701171875, + 6016.77001953125, + 5851, + 5857.22998046875, + 5916.22998046875, + 5846.4501953125, + 5799.0400390625, + 5804.14013671875, + 5862.81982421875, + 5912.490234375, + 6008.5498046875, + 5999.9501953125, + 5993.91015625, + 6032.7900390625, + 6062.97021484375, + 6028.27978515625, + 6067.14013671875, + 6064.919921875, + 6039.93994140625, + 6072.66015625, + 6062.2998046875, + 5995.14013671875, + 5765.169921875, + 5670.7099609375, + 5526.14013671875, + 5421.31005859375, + 5229.56005859375, + 5197.56982421875, + 5371.66015625, + 5357.35009765625, + 5329.240234375, + 5117.56982421875, + 4691.2001953125, + 4615.16015625, + 4603.0498046875, + 4025.889892578125, + 4055.18994140625, + 3632.06005859375, + 3759, + 3726.449951171875, + 3691.080078125, + 3984.300048828125, + 3851.169921875, + 4038.06005859375, + 4221.31982421875, + 4296.06005859375, + 4288.66015625 + ], + "open": [ + 6016.60986328125, + 6007.9599609375, + 6001.2099609375, + 6033.22021484375, + 5986.81005859375, + 6066.75, + 6056.740234375, + 6040.91015625, + 6037.4501953125, + 6042.72021484375, + 6039.6201171875, + 6066.2900390625, + 6092.97021484375, + 6034.240234375, + 6053.85009765625, + 5992.47021484375, + 6019.60009765625, + 5924.06005859375, + 5886.81005859375, + 5921.97021484375, + 5886.02001953125, + 5891.7099609375, + 5822.0400390625, + 5863.35986328125, + 5919.06005859375, + 6045.0400390625, + 6027.5400390625, + 6008.47998046875, + 6047.9599609375, + 6064.25, + 6076.919921875, + 6096.06982421875, + 6079.52978515625, + 6042.3798828125, + 6086.10986328125, + 6105.169921875, + 6035.02978515625, + 5875.85986328125, + 5825.3701171875, + 5646.14013671875, + 5571.72021484375, + 5310.81982421875, + 5416.02001953125, + 5408.14990234375, + 5400.43017578125, + 5490.52001953125, + 5253.81982421875, + 4845.27001953125, + 4770.6201171875, + 4716.22021484375, + 4374.669921875, + 4234.3701171875, + 3886.820068359375, + 4041.330078125, + 3905.530029296875, + 3833.989990234375, + 4066.7900390625, + 3869.010009765625, + 4087.610107421875, + 4339.7099609375, + 4332.7900390625, + 4433.9501953125 + ], + "type": "candlestick", + "x": [ + "2020-01-02T00:00:00", + "2020-01-03T00:00:00", + "2020-01-06T00:00:00", + "2020-01-07T00:00:00", + "2020-01-08T00:00:00", + "2020-01-09T00:00:00", + "2020-01-10T00:00:00", + "2020-01-13T00:00:00", + "2020-01-14T00:00:00", + "2020-01-15T00:00:00", + "2020-01-16T00:00:00", + "2020-01-17T00:00:00", + "2020-01-20T00:00:00", + "2020-01-21T00:00:00", + "2020-01-22T00:00:00", + "2020-01-23T00:00:00", + "2020-01-24T00:00:00", + "2020-01-27T00:00:00", + "2020-01-28T00:00:00", + "2020-01-29T00:00:00", + "2020-01-30T00:00:00", + "2020-01-31T00:00:00", + "2020-02-03T00:00:00", + "2020-02-04T00:00:00", + "2020-02-05T00:00:00", + "2020-02-06T00:00:00", + "2020-02-07T00:00:00", + "2020-02-10T00:00:00", + "2020-02-11T00:00:00", + "2020-02-12T00:00:00", + "2020-02-13T00:00:00", + "2020-02-14T00:00:00", + "2020-02-17T00:00:00", + "2020-02-18T00:00:00", + "2020-02-19T00:00:00", + "2020-02-20T00:00:00", + "2020-02-21T00:00:00", + "2020-02-24T00:00:00", + "2020-02-25T00:00:00", + "2020-02-26T00:00:00", + "2020-02-27T00:00:00", + "2020-02-28T00:00:00", + "2020-03-02T00:00:00", + "2020-03-03T00:00:00", + "2020-03-04T00:00:00", + "2020-03-05T00:00:00", + "2020-03-06T00:00:00", + "2020-03-09T00:00:00", + "2020-03-10T00:00:00", + "2020-03-11T00:00:00", + "2020-03-12T00:00:00", + "2020-03-13T00:00:00", + "2020-03-16T00:00:00", + "2020-03-17T00:00:00", + "2020-03-18T00:00:00", + "2020-03-19T00:00:00", + "2020-03-20T00:00:00", + "2020-03-23T00:00:00", + "2020-03-24T00:00:00", + "2020-03-25T00:00:00", + "2020-03-26T00:00:00", + "2020-03-27T00:00:00" + ] + }, + { + "type": "scatter", + "x": [ + "2020-01-02T00:00:00", + "2020-01-03T00:00:00", + "2020-01-06T00:00:00", + "2020-01-07T00:00:00", + "2020-01-08T00:00:00", + "2020-01-09T00:00:00", + "2020-01-10T00:00:00", + "2020-01-13T00:00:00", + "2020-01-14T00:00:00", + "2020-01-15T00:00:00", + "2020-01-16T00:00:00", + "2020-01-17T00:00:00", + "2020-01-20T00:00:00", + "2020-01-21T00:00:00", + "2020-01-22T00:00:00", + "2020-01-23T00:00:00", + "2020-01-24T00:00:00", + "2020-01-27T00:00:00", + "2020-01-28T00:00:00", + "2020-01-29T00:00:00", + "2020-01-30T00:00:00", + "2020-01-31T00:00:00", + "2020-02-03T00:00:00", + "2020-02-04T00:00:00", + "2020-02-05T00:00:00", + "2020-02-06T00:00:00", + "2020-02-07T00:00:00", + "2020-02-10T00:00:00", + "2020-02-11T00:00:00", + "2020-02-12T00:00:00", + "2020-02-13T00:00:00", + "2020-02-14T00:00:00", + "2020-02-17T00:00:00", + "2020-02-18T00:00:00", + "2020-02-19T00:00:00", + "2020-02-20T00:00:00", + "2020-02-21T00:00:00", + "2020-02-24T00:00:00", + "2020-02-25T00:00:00", + "2020-02-26T00:00:00", + "2020-02-27T00:00:00", + "2020-02-28T00:00:00", + "2020-03-02T00:00:00", + "2020-03-03T00:00:00", + "2020-03-04T00:00:00", + "2020-03-05T00:00:00", + "2020-03-06T00:00:00", + "2020-03-09T00:00:00", + "2020-03-10T00:00:00", + "2020-03-11T00:00:00", + "2020-03-12T00:00:00", + "2020-03-13T00:00:00", + "2020-03-16T00:00:00", + "2020-03-17T00:00:00", + "2020-03-18T00:00:00", + "2020-03-19T00:00:00", + "2020-03-20T00:00:00", + "2020-03-23T00:00:00", + "2020-03-24T00:00:00", + "2020-03-25T00:00:00", + "2020-03-26T00:00:00", + "2020-03-27T00:00:00" + ], + "y": [ + null, + null, + 6033.083333333333, + 6023.36669921875, + 6018.97998046875, + 6028.63330078125, + 6036.886555989583, + 6038.599934895833, + 6038.046712239583, + 6036.546712239583, + 6037.509928385417, + 6057.453287760417, + 6072.763346354167, + 6075.08349609375, + 6045.170084635417, + 6009.586751302083, + 6002.34326171875, + 5953.023274739583, + 5937.699869791667, + 5914.57666015625, + 5917.493326822917, + 5877.666666666667, + 5836.873209635417, + 5857.966471354167, + 5917.653157552083, + 5986.2099609375, + 6017.776692708333, + 6027.86669921875, + 6033.393229166667, + 6058.386555989583, + 6084.2099609375, + 6089.073404947917, + 6082.8134765625, + 6070.706705729167, + 6084.670084635417, + 6076.78662109375, + 6067.75341796875, + 5961.296712239583, + 5833.7568359375, + 5718.700032552083, + 5619.943359375, + 5496.683268229167, + 5379.67333984375, + 5345.529947916667, + 5397.193359375, + 5406.38671875, + 5321.700032552083, + 5069.373372395833, + 4827.876627604167, + 4651.590006510417, + 4430.373291015625, + 4257.623291015625, + 4014.6932779947915, + 3997.199951171875, + 3876.0266927083335, + 3867.3733723958335, + 3886.3800455729165, + 3939.5367024739585, + 4068.6034342447915, + 4196.436686197917, + 4406.193359375, + 4442.456705729167 + ] + } + ], + "layout": { + "autosize": false, + "height": 500, + "showlegend": false, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "width": 700, + "xaxis": { + "rangeslider": { + "visible": false + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = go.Figure(data=[go.Candlestick(\n", + " \n", + " x = stock_data.index, # date values\n", + " open = stock_data['Open'],\n", + " high = stock_data['High'],\n", + " low = stock_data['Low'],\n", + " close = stock_data['Close']),\n", + " \n", + " # Add the moving average\n", + " go.Scatter(x=stock_data['moving3'].index,\n", + " y=stock_data['moving3'])\n", + " ])\n", + "\n", + "# Mask a default range slider\n", + "fig.update_layout(xaxis_rangeslider_visible=False)\n", + "\n", + "# Set layout size\n", + "fig.update_layout(\n", + " autosize=False,\n", + " width=700,\n", + " height=500,\n", + " showlegend=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's save the graph in a HTML file and display it in this website using an `iframe`" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# save this file as a standalong html file:\n", + "fig.write_html(\"../../static/interactiveCharts/candlestick-plotly-moving-average.html\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%html\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Multiple moving averages\n", + "\n", + "You can easily add **as many moving averages as you want** by adding arguments when creating the figure. In our case, we'll add the **8-day** moving average. " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "close": [ + 6041.5, + 6044.16015625, + 6013.58984375, + 6012.35009765625, + 6031, + 6042.5498046875, + 6037.10986328125, + 6036.14013671875, + 6040.89013671875, + 6032.60986328125, + 6039.02978515625, + 6100.72021484375, + 6078.5400390625, + 6045.990234375, + 6010.97998046875, + 5971.7900390625, + 6024.259765625, + 5863.02001953125, + 5925.81982421875, + 5954.89013671875, + 5871.77001953125, + 5806.33984375, + 5832.509765625, + 5935.0498046875, + 5985.39990234375, + 6038.18017578125, + 6029.75, + 6015.669921875, + 6054.759765625, + 6104.72998046875, + 6093.14013671875, + 6069.35009765625, + 6085.9501953125, + 6056.81982421875, + 6111.240234375, + 6062.2998046875, + 6029.72021484375, + 5791.8701171875, + 5679.68017578125, + 5684.5498046875, + 5495.60009765625, + 5309.89990234375, + 5333.52001953125, + 5393.169921875, + 5464.89013671875, + 5361.10009765625, + 5139.10986328125, + 4707.91015625, + 4636.60986328125, + 4610.25, + 4044.260009765625, + 4118.35986328125, + 3881.4599609375, + 3991.780029296875, + 3754.840087890625, + 3855.5, + 4048.800048828125, + 3914.31005859375, + 4242.7001953125, + 4432.2998046875, + 4543.580078125, + 4351.490234375 + ], + "high": [ + 6062.919921875, + 6044.16015625, + 6017.97021484375, + 6065.740234375, + 6031, + 6071.66015625, + 6057.830078125, + 6058.68994140625, + 6046.1201171875, + 6053.009765625, + 6058.97021484375, + 6109.81005859375, + 6094.08984375, + 6045.990234375, + 6069.259765625, + 6024.31982421875, + 6064.5498046875, + 5942.830078125, + 5933.72021484375, + 5969.72998046875, + 5904.080078125, + 5894.68994140625, + 5857.39990234375, + 5935.0498046875, + 6004.330078125, + 6050.93994140625, + 6044.97021484375, + 6018.31005859375, + 6060.97021484375, + 6104.72998046875, + 6098.259765625, + 6096.06982421875, + 6088.60009765625, + 6079.5, + 6111.41015625, + 6110.9501953125, + 6067.2900390625, + 5884.85986328125, + 5828.4599609375, + 5707.31005859375, + 5613.72021484375, + 5376.0498046875, + 5430.0498046875, + 5509.27978515625, + 5493.25, + 5494.16015625, + 5284.080078125, + 4863.33984375, + 4924.83984375, + 4766, + 4404.259765625, + 4438.509765625, + 3962.010009765625, + 4042.4599609375, + 3908.719970703125, + 3909.14990234375, + 4109.10986328125, + 4097.81982421875, + 4242.7001953125, + 4453.009765625, + 4543.580078125, + 4471.3701171875 + ], + "low": [ + 6011.2099609375, + 5994.58984375, + 5955.25, + 6000, + 5972.77001953125, + 6034.14990234375, + 6028.2900390625, + 6018.330078125, + 5980.0498046875, + 6011.27978515625, + 6021.02978515625, + 6066.2900390625, + 6071.169921875, + 5994.169921875, + 6005.77001953125, + 5961.8701171875, + 6016.77001953125, + 5851, + 5857.22998046875, + 5916.22998046875, + 5846.4501953125, + 5799.0400390625, + 5804.14013671875, + 5862.81982421875, + 5912.490234375, + 6008.5498046875, + 5999.9501953125, + 5993.91015625, + 6032.7900390625, + 6062.97021484375, + 6028.27978515625, + 6067.14013671875, + 6064.919921875, + 6039.93994140625, + 6072.66015625, + 6062.2998046875, + 5995.14013671875, + 5765.169921875, + 5670.7099609375, + 5526.14013671875, + 5421.31005859375, + 5229.56005859375, + 5197.56982421875, + 5371.66015625, + 5357.35009765625, + 5329.240234375, + 5117.56982421875, + 4691.2001953125, + 4615.16015625, + 4603.0498046875, + 4025.889892578125, + 4055.18994140625, + 3632.06005859375, + 3759, + 3726.449951171875, + 3691.080078125, + 3984.300048828125, + 3851.169921875, + 4038.06005859375, + 4221.31982421875, + 4296.06005859375, + 4288.66015625 + ], + "open": [ + 6016.60986328125, + 6007.9599609375, + 6001.2099609375, + 6033.22021484375, + 5986.81005859375, + 6066.75, + 6056.740234375, + 6040.91015625, + 6037.4501953125, + 6042.72021484375, + 6039.6201171875, + 6066.2900390625, + 6092.97021484375, + 6034.240234375, + 6053.85009765625, + 5992.47021484375, + 6019.60009765625, + 5924.06005859375, + 5886.81005859375, + 5921.97021484375, + 5886.02001953125, + 5891.7099609375, + 5822.0400390625, + 5863.35986328125, + 5919.06005859375, + 6045.0400390625, + 6027.5400390625, + 6008.47998046875, + 6047.9599609375, + 6064.25, + 6076.919921875, + 6096.06982421875, + 6079.52978515625, + 6042.3798828125, + 6086.10986328125, + 6105.169921875, + 6035.02978515625, + 5875.85986328125, + 5825.3701171875, + 5646.14013671875, + 5571.72021484375, + 5310.81982421875, + 5416.02001953125, + 5408.14990234375, + 5400.43017578125, + 5490.52001953125, + 5253.81982421875, + 4845.27001953125, + 4770.6201171875, + 4716.22021484375, + 4374.669921875, + 4234.3701171875, + 3886.820068359375, + 4041.330078125, + 3905.530029296875, + 3833.989990234375, + 4066.7900390625, + 3869.010009765625, + 4087.610107421875, + 4339.7099609375, + 4332.7900390625, + 4433.9501953125 + ], + "type": "candlestick", + "x": [ + "2020-01-02T00:00:00", + "2020-01-03T00:00:00", + "2020-01-06T00:00:00", + "2020-01-07T00:00:00", + "2020-01-08T00:00:00", + "2020-01-09T00:00:00", + "2020-01-10T00:00:00", + "2020-01-13T00:00:00", + "2020-01-14T00:00:00", + "2020-01-15T00:00:00", + "2020-01-16T00:00:00", + "2020-01-17T00:00:00", + "2020-01-20T00:00:00", + "2020-01-21T00:00:00", + "2020-01-22T00:00:00", + "2020-01-23T00:00:00", + "2020-01-24T00:00:00", + "2020-01-27T00:00:00", + "2020-01-28T00:00:00", + "2020-01-29T00:00:00", + "2020-01-30T00:00:00", + "2020-01-31T00:00:00", + "2020-02-03T00:00:00", + "2020-02-04T00:00:00", + "2020-02-05T00:00:00", + "2020-02-06T00:00:00", + "2020-02-07T00:00:00", + "2020-02-10T00:00:00", + "2020-02-11T00:00:00", + "2020-02-12T00:00:00", + "2020-02-13T00:00:00", + "2020-02-14T00:00:00", + "2020-02-17T00:00:00", + "2020-02-18T00:00:00", + "2020-02-19T00:00:00", + "2020-02-20T00:00:00", + "2020-02-21T00:00:00", + "2020-02-24T00:00:00", + "2020-02-25T00:00:00", + "2020-02-26T00:00:00", + "2020-02-27T00:00:00", + "2020-02-28T00:00:00", + "2020-03-02T00:00:00", + "2020-03-03T00:00:00", + "2020-03-04T00:00:00", + "2020-03-05T00:00:00", + "2020-03-06T00:00:00", + "2020-03-09T00:00:00", + "2020-03-10T00:00:00", + "2020-03-11T00:00:00", + "2020-03-12T00:00:00", + "2020-03-13T00:00:00", + "2020-03-16T00:00:00", + "2020-03-17T00:00:00", + "2020-03-18T00:00:00", + "2020-03-19T00:00:00", + "2020-03-20T00:00:00", + "2020-03-23T00:00:00", + "2020-03-24T00:00:00", + "2020-03-25T00:00:00", + "2020-03-26T00:00:00", + "2020-03-27T00:00:00" + ] + }, + { + "type": "scatter", + "x": [ + "2020-01-02T00:00:00", + "2020-01-03T00:00:00", + "2020-01-06T00:00:00", + "2020-01-07T00:00:00", + "2020-01-08T00:00:00", + "2020-01-09T00:00:00", + "2020-01-10T00:00:00", + "2020-01-13T00:00:00", + "2020-01-14T00:00:00", + "2020-01-15T00:00:00", + "2020-01-16T00:00:00", + "2020-01-17T00:00:00", + "2020-01-20T00:00:00", + "2020-01-21T00:00:00", + "2020-01-22T00:00:00", + "2020-01-23T00:00:00", + "2020-01-24T00:00:00", + "2020-01-27T00:00:00", + "2020-01-28T00:00:00", + "2020-01-29T00:00:00", + "2020-01-30T00:00:00", + "2020-01-31T00:00:00", + "2020-02-03T00:00:00", + "2020-02-04T00:00:00", + "2020-02-05T00:00:00", + "2020-02-06T00:00:00", + "2020-02-07T00:00:00", + "2020-02-10T00:00:00", + "2020-02-11T00:00:00", + "2020-02-12T00:00:00", + "2020-02-13T00:00:00", + "2020-02-14T00:00:00", + "2020-02-17T00:00:00", + "2020-02-18T00:00:00", + "2020-02-19T00:00:00", + "2020-02-20T00:00:00", + "2020-02-21T00:00:00", + "2020-02-24T00:00:00", + "2020-02-25T00:00:00", + "2020-02-26T00:00:00", + "2020-02-27T00:00:00", + "2020-02-28T00:00:00", + "2020-03-02T00:00:00", + "2020-03-03T00:00:00", + "2020-03-04T00:00:00", + "2020-03-05T00:00:00", + "2020-03-06T00:00:00", + "2020-03-09T00:00:00", + "2020-03-10T00:00:00", + "2020-03-11T00:00:00", + "2020-03-12T00:00:00", + "2020-03-13T00:00:00", + "2020-03-16T00:00:00", + "2020-03-17T00:00:00", + "2020-03-18T00:00:00", + "2020-03-19T00:00:00", + "2020-03-20T00:00:00", + "2020-03-23T00:00:00", + "2020-03-24T00:00:00", + "2020-03-25T00:00:00", + "2020-03-26T00:00:00", + "2020-03-27T00:00:00" + ], + "y": [ + null, + null, + 6033.083333333333, + 6023.36669921875, + 6018.97998046875, + 6028.63330078125, + 6036.886555989583, + 6038.599934895833, + 6038.046712239583, + 6036.546712239583, + 6037.509928385417, + 6057.453287760417, + 6072.763346354167, + 6075.08349609375, + 6045.170084635417, + 6009.586751302083, + 6002.34326171875, + 5953.023274739583, + 5937.699869791667, + 5914.57666015625, + 5917.493326822917, + 5877.666666666667, + 5836.873209635417, + 5857.966471354167, + 5917.653157552083, + 5986.2099609375, + 6017.776692708333, + 6027.86669921875, + 6033.393229166667, + 6058.386555989583, + 6084.2099609375, + 6089.073404947917, + 6082.8134765625, + 6070.706705729167, + 6084.670084635417, + 6076.78662109375, + 6067.75341796875, + 5961.296712239583, + 5833.7568359375, + 5718.700032552083, + 5619.943359375, + 5496.683268229167, + 5379.67333984375, + 5345.529947916667, + 5397.193359375, + 5406.38671875, + 5321.700032552083, + 5069.373372395833, + 4827.876627604167, + 4651.590006510417, + 4430.373291015625, + 4257.623291015625, + 4014.6932779947915, + 3997.199951171875, + 3876.0266927083335, + 3867.3733723958335, + 3886.3800455729165, + 3939.5367024739585, + 4068.6034342447915, + 4196.436686197917, + 4406.193359375, + 4442.456705729167 + ] + }, + { + "type": "scatter", + "x": [ + "2020-01-02T00:00:00", + "2020-01-03T00:00:00", + "2020-01-06T00:00:00", + "2020-01-07T00:00:00", + "2020-01-08T00:00:00", + "2020-01-09T00:00:00", + "2020-01-10T00:00:00", + "2020-01-13T00:00:00", + "2020-01-14T00:00:00", + "2020-01-15T00:00:00", + "2020-01-16T00:00:00", + "2020-01-17T00:00:00", + "2020-01-20T00:00:00", + "2020-01-21T00:00:00", + "2020-01-22T00:00:00", + "2020-01-23T00:00:00", + "2020-01-24T00:00:00", + "2020-01-27T00:00:00", + "2020-01-28T00:00:00", + "2020-01-29T00:00:00", + "2020-01-30T00:00:00", + "2020-01-31T00:00:00", + "2020-02-03T00:00:00", + "2020-02-04T00:00:00", + "2020-02-05T00:00:00", + "2020-02-06T00:00:00", + "2020-02-07T00:00:00", + "2020-02-10T00:00:00", + "2020-02-11T00:00:00", + "2020-02-12T00:00:00", + "2020-02-13T00:00:00", + "2020-02-14T00:00:00", + "2020-02-17T00:00:00", + "2020-02-18T00:00:00", + "2020-02-19T00:00:00", + "2020-02-20T00:00:00", + "2020-02-21T00:00:00", + "2020-02-24T00:00:00", + "2020-02-25T00:00:00", + "2020-02-26T00:00:00", + "2020-02-27T00:00:00", + "2020-02-28T00:00:00", + "2020-03-02T00:00:00", + "2020-03-03T00:00:00", + "2020-03-04T00:00:00", + "2020-03-05T00:00:00", + "2020-03-06T00:00:00", + "2020-03-09T00:00:00", + "2020-03-10T00:00:00", + "2020-03-11T00:00:00", + "2020-03-12T00:00:00", + "2020-03-13T00:00:00", + "2020-03-16T00:00:00", + "2020-03-17T00:00:00", + "2020-03-18T00:00:00", + "2020-03-19T00:00:00", + "2020-03-20T00:00:00", + "2020-03-23T00:00:00", + "2020-03-24T00:00:00", + "2020-03-25T00:00:00", + "2020-03-26T00:00:00", + "2020-03-27T00:00:00" + ], + "y": [ + null, + null, + null, + null, + null, + null, + null, + 6032.299987792969, + 6032.2237548828125, + 6030.779968261719, + 6033.9599609375, + 6045.0062255859375, + 6050.94873046875, + 6051.3787841796875, + 6048.112548828125, + 6040.068786621094, + 6037.989990234375, + 6016.791259765625, + 6002.6400146484375, + 5984.4112548828125, + 5958.565002441406, + 5928.608703613281, + 5906.2999267578125, + 5901.7073974609375, + 5896.849914550781, + 5918.744934082031, + 5931.7362060546875, + 5939.333679199219, + 5962.2073974609375, + 5999.506164550781, + 6032.0849609375, + 6048.872497558594, + 6061.4412841796875, + 6063.771240234375, + 6073.95751953125, + 6079.7862548828125, + 6076.656311035156, + 6037.548828125, + 5985.8663330078125, + 5937.766296386719, + 5863.9725341796875, + 5770.6075439453125, + 5673.392517089844, + 5589.751281738281, + 5519.147521972656, + 5465.30126953125, + 5397.72998046875, + 5275.6500244140625, + 5168.2762451171875, + 5080.820007324219, + 4919.662506103516, + 4760.311248779297, + 4562.382476806641, + 4391.217468261719, + 4218.183746337891, + 4111.632476806641, + 4038.15625, + 3951.1637573242188, + 3975.968780517578, + 4015.2112731933594, + 4097.976287841797, + 4142.9400634765625 + ] + } + ], + "layout": { + "autosize": false, + "height": 500, + "showlegend": false, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "width": 700, + "xaxis": { + "rangeslider": { + "visible": false + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = go.Figure(data=[go.Candlestick(\n", + " \n", + " x = stock_data.index, # date values\n", + " open = stock_data['Open'],\n", + " high = stock_data['High'],\n", + " low = stock_data['Low'],\n", + " close = stock_data['Close']),\n", + " \n", + " # Add the moving average\n", + " go.Scatter(x=stock_data['moving3'].index,\n", + " y=stock_data['moving3']),\n", + " go.Scatter(x=stock_data['moving8'].index,\n", + " y=stock_data['moving8'])\n", + " ])\n", + "\n", + "# Mask a default range slider\n", + "fig.update_layout(xaxis_rangeslider_visible=False)\n", + "\n", + "# Set layout size\n", + "fig.update_layout(\n", + " autosize=False,\n", + " width=700,\n", + " height=500,\n", + " showlegend=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's save the graph in a HTML file and display it in this website using an `iframe`" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# save this file as a standalong html file:\n", + "fig.write_html(\"../../static/interactiveCharts/candlestick-plotly-moving-average-2.html\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%html\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Custom style of the moving averages\n", + "\n", + "To make our graph **easier to read** and **more informative**, we can change the `colors` of the bars and moving averages.\n", + "\n", + "- **change color**: add a `line` argument (dictionnary) with the properties wanted (color, width and shape)\n", + "- **add legend**: add a `name` argument with the text we want" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "close": [ + 6041.5, + 6044.16015625, + 6013.58984375, + 6012.35009765625, + 6031, + 6042.5498046875, + 6037.10986328125, + 6036.14013671875, + 6040.89013671875, + 6032.60986328125, + 6039.02978515625, + 6100.72021484375, + 6078.5400390625, + 6045.990234375, + 6010.97998046875, + 5971.7900390625, + 6024.259765625, + 5863.02001953125, + 5925.81982421875, + 5954.89013671875, + 5871.77001953125, + 5806.33984375, + 5832.509765625, + 5935.0498046875, + 5985.39990234375, + 6038.18017578125, + 6029.75, + 6015.669921875, + 6054.759765625, + 6104.72998046875, + 6093.14013671875, + 6069.35009765625, + 6085.9501953125, + 6056.81982421875, + 6111.240234375, + 6062.2998046875, + 6029.72021484375, + 5791.8701171875, + 5679.68017578125, + 5684.5498046875, + 5495.60009765625, + 5309.89990234375, + 5333.52001953125, + 5393.169921875, + 5464.89013671875, + 5361.10009765625, + 5139.10986328125, + 4707.91015625, + 4636.60986328125, + 4610.25, + 4044.260009765625, + 4118.35986328125, + 3881.4599609375, + 3991.780029296875, + 3754.840087890625, + 3855.5, + 4048.800048828125, + 3914.31005859375, + 4242.7001953125, + 4432.2998046875, + 4543.580078125, + 4351.490234375 + ], + "decreasing": { + "line": { + "color": "orangered" + } + }, + "high": [ + 6062.919921875, + 6044.16015625, + 6017.97021484375, + 6065.740234375, + 6031, + 6071.66015625, + 6057.830078125, + 6058.68994140625, + 6046.1201171875, + 6053.009765625, + 6058.97021484375, + 6109.81005859375, + 6094.08984375, + 6045.990234375, + 6069.259765625, + 6024.31982421875, + 6064.5498046875, + 5942.830078125, + 5933.72021484375, + 5969.72998046875, + 5904.080078125, + 5894.68994140625, + 5857.39990234375, + 5935.0498046875, + 6004.330078125, + 6050.93994140625, + 6044.97021484375, + 6018.31005859375, + 6060.97021484375, + 6104.72998046875, + 6098.259765625, + 6096.06982421875, + 6088.60009765625, + 6079.5, + 6111.41015625, + 6110.9501953125, + 6067.2900390625, + 5884.85986328125, + 5828.4599609375, + 5707.31005859375, + 5613.72021484375, + 5376.0498046875, + 5430.0498046875, + 5509.27978515625, + 5493.25, + 5494.16015625, + 5284.080078125, + 4863.33984375, + 4924.83984375, + 4766, + 4404.259765625, + 4438.509765625, + 3962.010009765625, + 4042.4599609375, + 3908.719970703125, + 3909.14990234375, + 4109.10986328125, + 4097.81982421875, + 4242.7001953125, + 4453.009765625, + 4543.580078125, + 4471.3701171875 + ], + "increasing": { + "line": { + "color": "limegreen" + } + }, + "low": [ + 6011.2099609375, + 5994.58984375, + 5955.25, + 6000, + 5972.77001953125, + 6034.14990234375, + 6028.2900390625, + 6018.330078125, + 5980.0498046875, + 6011.27978515625, + 6021.02978515625, + 6066.2900390625, + 6071.169921875, + 5994.169921875, + 6005.77001953125, + 5961.8701171875, + 6016.77001953125, + 5851, + 5857.22998046875, + 5916.22998046875, + 5846.4501953125, + 5799.0400390625, + 5804.14013671875, + 5862.81982421875, + 5912.490234375, + 6008.5498046875, + 5999.9501953125, + 5993.91015625, + 6032.7900390625, + 6062.97021484375, + 6028.27978515625, + 6067.14013671875, + 6064.919921875, + 6039.93994140625, + 6072.66015625, + 6062.2998046875, + 5995.14013671875, + 5765.169921875, + 5670.7099609375, + 5526.14013671875, + 5421.31005859375, + 5229.56005859375, + 5197.56982421875, + 5371.66015625, + 5357.35009765625, + 5329.240234375, + 5117.56982421875, + 4691.2001953125, + 4615.16015625, + 4603.0498046875, + 4025.889892578125, + 4055.18994140625, + 3632.06005859375, + 3759, + 3726.449951171875, + 3691.080078125, + 3984.300048828125, + 3851.169921875, + 4038.06005859375, + 4221.31982421875, + 4296.06005859375, + 4288.66015625 + ], + "open": [ + 6016.60986328125, + 6007.9599609375, + 6001.2099609375, + 6033.22021484375, + 5986.81005859375, + 6066.75, + 6056.740234375, + 6040.91015625, + 6037.4501953125, + 6042.72021484375, + 6039.6201171875, + 6066.2900390625, + 6092.97021484375, + 6034.240234375, + 6053.85009765625, + 5992.47021484375, + 6019.60009765625, + 5924.06005859375, + 5886.81005859375, + 5921.97021484375, + 5886.02001953125, + 5891.7099609375, + 5822.0400390625, + 5863.35986328125, + 5919.06005859375, + 6045.0400390625, + 6027.5400390625, + 6008.47998046875, + 6047.9599609375, + 6064.25, + 6076.919921875, + 6096.06982421875, + 6079.52978515625, + 6042.3798828125, + 6086.10986328125, + 6105.169921875, + 6035.02978515625, + 5875.85986328125, + 5825.3701171875, + 5646.14013671875, + 5571.72021484375, + 5310.81982421875, + 5416.02001953125, + 5408.14990234375, + 5400.43017578125, + 5490.52001953125, + 5253.81982421875, + 4845.27001953125, + 4770.6201171875, + 4716.22021484375, + 4374.669921875, + 4234.3701171875, + 3886.820068359375, + 4041.330078125, + 3905.530029296875, + 3833.989990234375, + 4066.7900390625, + 3869.010009765625, + 4087.610107421875, + 4339.7099609375, + 4332.7900390625, + 4433.9501953125 + ], + "showlegend": false, + "type": "candlestick", + "x": [ + "2020-01-02T00:00:00", + "2020-01-03T00:00:00", + "2020-01-06T00:00:00", + "2020-01-07T00:00:00", + "2020-01-08T00:00:00", + "2020-01-09T00:00:00", + "2020-01-10T00:00:00", + "2020-01-13T00:00:00", + "2020-01-14T00:00:00", + "2020-01-15T00:00:00", + "2020-01-16T00:00:00", + "2020-01-17T00:00:00", + "2020-01-20T00:00:00", + "2020-01-21T00:00:00", + "2020-01-22T00:00:00", + "2020-01-23T00:00:00", + "2020-01-24T00:00:00", + "2020-01-27T00:00:00", + "2020-01-28T00:00:00", + "2020-01-29T00:00:00", + "2020-01-30T00:00:00", + "2020-01-31T00:00:00", + "2020-02-03T00:00:00", + "2020-02-04T00:00:00", + "2020-02-05T00:00:00", + "2020-02-06T00:00:00", + "2020-02-07T00:00:00", + "2020-02-10T00:00:00", + "2020-02-11T00:00:00", + "2020-02-12T00:00:00", + "2020-02-13T00:00:00", + "2020-02-14T00:00:00", + "2020-02-17T00:00:00", + "2020-02-18T00:00:00", + "2020-02-19T00:00:00", + "2020-02-20T00:00:00", + "2020-02-21T00:00:00", + "2020-02-24T00:00:00", + "2020-02-25T00:00:00", + "2020-02-26T00:00:00", + "2020-02-27T00:00:00", + "2020-02-28T00:00:00", + "2020-03-02T00:00:00", + "2020-03-03T00:00:00", + "2020-03-04T00:00:00", + "2020-03-05T00:00:00", + "2020-03-06T00:00:00", + "2020-03-09T00:00:00", + "2020-03-10T00:00:00", + "2020-03-11T00:00:00", + "2020-03-12T00:00:00", + "2020-03-13T00:00:00", + "2020-03-16T00:00:00", + "2020-03-17T00:00:00", + "2020-03-18T00:00:00", + "2020-03-19T00:00:00", + "2020-03-20T00:00:00", + "2020-03-23T00:00:00", + "2020-03-24T00:00:00", + "2020-03-25T00:00:00", + "2020-03-26T00:00:00", + "2020-03-27T00:00:00" + ] + }, + { + "line": { + "color": "gray", + "shape": "spline", + "width": 1 + }, + "name": "MA3", + "type": "scatter", + "x": [ + "2020-01-02T00:00:00", + "2020-01-03T00:00:00", + "2020-01-06T00:00:00", + "2020-01-07T00:00:00", + "2020-01-08T00:00:00", + "2020-01-09T00:00:00", + "2020-01-10T00:00:00", + "2020-01-13T00:00:00", + "2020-01-14T00:00:00", + "2020-01-15T00:00:00", + "2020-01-16T00:00:00", + "2020-01-17T00:00:00", + "2020-01-20T00:00:00", + "2020-01-21T00:00:00", + "2020-01-22T00:00:00", + "2020-01-23T00:00:00", + "2020-01-24T00:00:00", + "2020-01-27T00:00:00", + "2020-01-28T00:00:00", + "2020-01-29T00:00:00", + "2020-01-30T00:00:00", + "2020-01-31T00:00:00", + "2020-02-03T00:00:00", + "2020-02-04T00:00:00", + "2020-02-05T00:00:00", + "2020-02-06T00:00:00", + "2020-02-07T00:00:00", + "2020-02-10T00:00:00", + "2020-02-11T00:00:00", + "2020-02-12T00:00:00", + "2020-02-13T00:00:00", + "2020-02-14T00:00:00", + "2020-02-17T00:00:00", + "2020-02-18T00:00:00", + "2020-02-19T00:00:00", + "2020-02-20T00:00:00", + "2020-02-21T00:00:00", + "2020-02-24T00:00:00", + "2020-02-25T00:00:00", + "2020-02-26T00:00:00", + "2020-02-27T00:00:00", + "2020-02-28T00:00:00", + "2020-03-02T00:00:00", + "2020-03-03T00:00:00", + "2020-03-04T00:00:00", + "2020-03-05T00:00:00", + "2020-03-06T00:00:00", + "2020-03-09T00:00:00", + "2020-03-10T00:00:00", + "2020-03-11T00:00:00", + "2020-03-12T00:00:00", + "2020-03-13T00:00:00", + "2020-03-16T00:00:00", + "2020-03-17T00:00:00", + "2020-03-18T00:00:00", + "2020-03-19T00:00:00", + "2020-03-20T00:00:00", + "2020-03-23T00:00:00", + "2020-03-24T00:00:00", + "2020-03-25T00:00:00", + "2020-03-26T00:00:00", + "2020-03-27T00:00:00" + ], + "y": [ + null, + null, + 6033.083333333333, + 6023.36669921875, + 6018.97998046875, + 6028.63330078125, + 6036.886555989583, + 6038.599934895833, + 6038.046712239583, + 6036.546712239583, + 6037.509928385417, + 6057.453287760417, + 6072.763346354167, + 6075.08349609375, + 6045.170084635417, + 6009.586751302083, + 6002.34326171875, + 5953.023274739583, + 5937.699869791667, + 5914.57666015625, + 5917.493326822917, + 5877.666666666667, + 5836.873209635417, + 5857.966471354167, + 5917.653157552083, + 5986.2099609375, + 6017.776692708333, + 6027.86669921875, + 6033.393229166667, + 6058.386555989583, + 6084.2099609375, + 6089.073404947917, + 6082.8134765625, + 6070.706705729167, + 6084.670084635417, + 6076.78662109375, + 6067.75341796875, + 5961.296712239583, + 5833.7568359375, + 5718.700032552083, + 5619.943359375, + 5496.683268229167, + 5379.67333984375, + 5345.529947916667, + 5397.193359375, + 5406.38671875, + 5321.700032552083, + 5069.373372395833, + 4827.876627604167, + 4651.590006510417, + 4430.373291015625, + 4257.623291015625, + 4014.6932779947915, + 3997.199951171875, + 3876.0266927083335, + 3867.3733723958335, + 3886.3800455729165, + 3939.5367024739585, + 4068.6034342447915, + 4196.436686197917, + 4406.193359375, + 4442.456705729167 + ] + }, + { + "line": { + "color": "black", + "shape": "spline", + "width": 1 + }, + "name": "MA8", + "type": "scatter", + "x": [ + "2020-01-02T00:00:00", + "2020-01-03T00:00:00", + "2020-01-06T00:00:00", + "2020-01-07T00:00:00", + "2020-01-08T00:00:00", + "2020-01-09T00:00:00", + "2020-01-10T00:00:00", + "2020-01-13T00:00:00", + "2020-01-14T00:00:00", + "2020-01-15T00:00:00", + "2020-01-16T00:00:00", + "2020-01-17T00:00:00", + "2020-01-20T00:00:00", + "2020-01-21T00:00:00", + "2020-01-22T00:00:00", + "2020-01-23T00:00:00", + "2020-01-24T00:00:00", + "2020-01-27T00:00:00", + "2020-01-28T00:00:00", + "2020-01-29T00:00:00", + "2020-01-30T00:00:00", + "2020-01-31T00:00:00", + "2020-02-03T00:00:00", + "2020-02-04T00:00:00", + "2020-02-05T00:00:00", + "2020-02-06T00:00:00", + "2020-02-07T00:00:00", + "2020-02-10T00:00:00", + "2020-02-11T00:00:00", + "2020-02-12T00:00:00", + "2020-02-13T00:00:00", + "2020-02-14T00:00:00", + "2020-02-17T00:00:00", + "2020-02-18T00:00:00", + "2020-02-19T00:00:00", + "2020-02-20T00:00:00", + "2020-02-21T00:00:00", + "2020-02-24T00:00:00", + "2020-02-25T00:00:00", + "2020-02-26T00:00:00", + "2020-02-27T00:00:00", + "2020-02-28T00:00:00", + "2020-03-02T00:00:00", + "2020-03-03T00:00:00", + "2020-03-04T00:00:00", + "2020-03-05T00:00:00", + "2020-03-06T00:00:00", + "2020-03-09T00:00:00", + "2020-03-10T00:00:00", + "2020-03-11T00:00:00", + "2020-03-12T00:00:00", + "2020-03-13T00:00:00", + "2020-03-16T00:00:00", + "2020-03-17T00:00:00", + "2020-03-18T00:00:00", + "2020-03-19T00:00:00", + "2020-03-20T00:00:00", + "2020-03-23T00:00:00", + "2020-03-24T00:00:00", + "2020-03-25T00:00:00", + "2020-03-26T00:00:00", + "2020-03-27T00:00:00" + ], + "y": [ + null, + null, + null, + null, + null, + null, + null, + 6032.299987792969, + 6032.2237548828125, + 6030.779968261719, + 6033.9599609375, + 6045.0062255859375, + 6050.94873046875, + 6051.3787841796875, + 6048.112548828125, + 6040.068786621094, + 6037.989990234375, + 6016.791259765625, + 6002.6400146484375, + 5984.4112548828125, + 5958.565002441406, + 5928.608703613281, + 5906.2999267578125, + 5901.7073974609375, + 5896.849914550781, + 5918.744934082031, + 5931.7362060546875, + 5939.333679199219, + 5962.2073974609375, + 5999.506164550781, + 6032.0849609375, + 6048.872497558594, + 6061.4412841796875, + 6063.771240234375, + 6073.95751953125, + 6079.7862548828125, + 6076.656311035156, + 6037.548828125, + 5985.8663330078125, + 5937.766296386719, + 5863.9725341796875, + 5770.6075439453125, + 5673.392517089844, + 5589.751281738281, + 5519.147521972656, + 5465.30126953125, + 5397.72998046875, + 5275.6500244140625, + 5168.2762451171875, + 5080.820007324219, + 4919.662506103516, + 4760.311248779297, + 4562.382476806641, + 4391.217468261719, + 4218.183746337891, + 4111.632476806641, + 4038.15625, + 3951.1637573242188, + 3975.968780517578, + 4015.2112731933594, + 4097.976287841797, + 4142.9400634765625 + ] + } + ], + "layout": { + "autosize": false, + "height": 500, + "legend": { + "font": { + "size": 12 + }, + "x": 0.82, + "y": 0.98 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "width": 600, + "xaxis": { + "rangeslider": { + "visible": false + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = go.Figure(data=[go.Candlestick(\n", + " \n", + " x = stock_data.index, # date values\n", + " open = stock_data['Open'],\n", + " high = stock_data['High'],\n", + " low = stock_data['Low'],\n", + " close = stock_data['Close'],\n", + " \n", + " # color or bars\n", + " increasing_line_color = 'limegreen',\n", + " decreasing_line_color = 'orangered',\n", + " showlegend=False), \n", + " \n", + " # Add the moving average\n", + " go.Scatter(x=stock_data['moving3'].index,\n", + " y=stock_data['moving3'],\n", + " line=dict(color='gray',\n", + " width=1,\n", + " shape='spline'), # smooth the line\n", + " name='MA3'),\n", + " \n", + " go.Scatter(x=stock_data['moving8'].index,\n", + " y=stock_data['moving8'],\n", + " line=dict(color='black',\n", + " width=1,\n", + " shape='spline'), # smooth the line\n", + " name='MA8')\n", + " ])\n", + "\n", + "# Mask a default range slider\n", + "fig.update_layout(xaxis_rangeslider_visible=False)\n", + "\n", + "# Set layout size\n", + "fig.update_layout(\n", + " autosize=False,\n", + " width=600,\n", + " height=500,\n", + " legend=dict(\n", + " x=0.82, # Adjust the legend's x position\n", + " y=0.98, # Adjust the legend's y position\n", + " font=dict(size=12) # Customize font size\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's save the graph in a HTML file and display it in this website using an `iframe`" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# save this file as a standalong html file:\n", + "fig.write_html(\"../../static/interactiveCharts/candlestick-plotly-moving-average-3.html\")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%html\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Going further\n", + "\n", + "This post explains how to create a candlestick chart with [plotly](https://python-graph-gallery.com/plotly/).\n", + "\n", + "For more examples of **how to create or customize** your candlestick plots, see the [candlestick section](https://python-graph-gallery.com/candlestick/). You may also be interested in how to [custom style of a plotly candlestick chart](https://python-graph-gallery.com/554-custom-candle-stick-plotly/)." + ] + } + ], + "metadata": { + "chartType": "candlestick", + "description": "A candlestick chart, created using the Plotly library in Python, is a graphical representation of financial data. It displays price movements over a specific time period, typically used in stock market analysis. Candlestick charts are composed of individual 'candlesticks', each representing the opening, closing, high, and low prices for a given time interval. These candlesticks are displayed on a two-dimensional coordinate system, with one axis representing time and the other axis representing price.

Plotly has a Candlestick() function that provides the capability to create candlestick charts easily. In this post, we'll see how to add moving averages in candlestick charts with this library. You might first want to take a look at how to customize a candlestick chart (color, layout...) with plotly.", + "family": "evolution", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "keywords": "candlestick, plotly, moving, rolling, average, chart, finance", + "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.9.13" + }, + "seoDescription": "How to create a candlestick chart with moving averages with plotly", + "slug": "555-candle-stick-with-moving-average-plotly", + "title": "Candlestick chart with moving averages" + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/src/notebooks/558-waffle-bar-chart.ipynb b/src/notebooks/558-waffle-bar-chart.ipynb new file mode 100644 index 0000000000..b256f0eb91 --- /dev/null +++ b/src/notebooks/558-waffle-bar-chart.ipynb @@ -0,0 +1,291 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Libraries\n", + "\n", + "This post relies on the [PyWaffle library](https://github.com/gyli/PyWaffle), that is definitely the best way to create a waffle chart with Python.\n", + "\n", + "The very first thing to do is to install the library:\n", + "\n", + "`pip install pywaffle`\n", + "\n", + "Then, we just have to import the following libraries:\n", + "- [pandas](https://python-graph-gallery.com/pandas/) for creating a dataframe with our data\n", + "- [matplotlib](https://python-graph-gallery.com/matplotlib/) for customizing the chart\n", + "- `pywaffle` for the **waffle** figure" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import matplotlib.patches as mpatches # for the legend\n", + "from pywaffle import Waffle\n", + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dataset\n", + "\n", + "We create a simple dataset with the **number of cars produced**, broken down **by year and car type** (`car`, `truck` or `motorcycle`). Also, we define the index of this dataset using the `set_index()` function and specify that **each row** corresponds to a type of car." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "data = {\n", + " 2018: [3032, 2892, 804],\n", + " 2019: [4537, 3379, 1096],\n", + " 2020: [8932, 3879, 896],\n", + " 2021: [22147, 6678, 2156],\n", + " 2022: [32384, 13354, 5245]\n", + "}\n", + "\n", + "df = pd.DataFrame(data,\n", + " index=['car', 'truck', 'motorcycle'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Waffle bar chart\n", + "\n", + "Since there is **no pre-defined method** for waffle bar chart, we will create a *1 x n* figure, where n is the number of bar we want (**1 row and n cols**). In our case, it's one bar for each year (= 5).\n", + "\n", + "We will **iterate over each axe** and add the waffle chart of the corresponding year. The waffle chart is made with the `make_waffle()` function" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "number_of_bars = len(df.columns) # one bar per year\n", + "\n", + "# Init the whole figure and axes\n", + "fig, axs = plt.subplots(nrows=1,\n", + " ncols=number_of_bars,\n", + " figsize=(8,6),)\n", + "\n", + "# Iterate over each bar and create it\n", + "for i,ax in enumerate(axs):\n", + " \n", + " col_name = df.columns[i]\n", + " values = df[col_name] # values from the i-th column\n", + " \n", + " Waffle.make_waffle(\n", + " ax=ax, # pass axis to make_waffle \n", + " rows=20,\n", + " columns=5,\n", + " values=values,\n", + " )\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Stack vertically\n", + "\n", + "By default, the bars are **stacked horizontally** (from left to right). But in the context of a waffle bar chart, it might be **more relevant** to stack vertically.\n", + "\n", + "For this, we have to add `vertical=True` in the `make_waffle()` function:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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s3draGHdta6t1rqVLLsynxeX3VH0y1VERPTLlW7hbi1zX3dr3XE70/7vWjXW3Wo3Ip7kDOiGYRimvHC4+hJxszn8HU/76M4vynf32pm73bNfinTGWlh3tWursW6N/Y+IuLy9js327uBOv1zF+uRMt1L3eb8+uPEjc193a939dslujWughXW33I3468+AyQMgAAA/h+XUF879qcd+O3PXE8Ao226s6wlg7q4ngG1099ueAObulmxP3f/JTwDv//g14v7rQV9UREQsjuPoze/RnV/EcPUlHj7+VqY7akdE6u7i7Z9FOmPF9j+i+vez+LXVWLfG/kdE/OPf/4zt8HBwZ9kdxfsXr2J9chaXt9fx7vMn3YLdDy9fH9z4EftftjtuR0TRbo1roNT+R9Rbd6vdp7oHTP9pxlKH9P3X7085bjbluuN29m4NLay71rXVWreSUje97fDw7VPuZnunW7hby9zX3Vp33M60/7tWjXW32o14mnvAvH/tCACA4gyAAADJGAABAJIxAAIAJGMABABIxgAIAJCMARAAIBkDIABAMgZAAIBkDIAAAMkYAAEAkjEAAgAkYwAEAEjGAAgAkIwBEAAgGQMgAEAyBkAAgGQMgAAAyUwfABfHZd5xcRxx2j/++bQv1x23s3draGHdta6t1rqVLLsynxeX3VH0y1VERPTLlW7hbi1zX3dr3XE70/7vWjXW3Wo34mnuAd0wDMOUFw5XXyJuNoe/42kf3flF+e5eO3O3e/ZLkc5YC+uudm011q2x/xERl7fXsdneHdzpl6tYn5zpVuo+79cHN35k7uturbvfLtmtcQ20sO6WuyXbU/d/8gAIAMDPYTn1hXN/6rHfztz1BDDKthvregKYu+sJYBvd/bYngLm7JdvFnwDe//FrxP3Xg76oiIhYHMfRm9+jO7+I4epLPHz8rUx31I6I1N3F2z+LdMaK7X9E9e9n8WursW6N/Y+I+Me//xnb4eHgzrI7ivcvXsX65Cwub6/j3edPugW7H16+PrjxI/a/bHfcjoii3RrXQKn9j6i37la7T3UPmP4Th6UO6fuv359y3GzKdcft7N0aWlh3rWurtW4lpW562+Hh26fczfZOt3C3lrmvu7XuuJ1p/3etGututRvxNPeAef/aEQAAxRkAAQCSMQACACRjAAQASMYACACQjAEQACAZAyAAQDIGQACAZAyA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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "number_of_bars = len(df.columns) # one bar per year\n", + "\n", + "# Init the whole figure and axes\n", + "fig, axs = plt.subplots(nrows=1,\n", + " ncols=number_of_bars,\n", + " figsize=(8,6),)\n", + "\n", + "# Iterate over each bar and create it\n", + "for i,ax in enumerate(axs):\n", + " \n", + " col_name = df.columns[i]\n", + " values = df[col_name] # values from the i-th column\n", + " \n", + " Waffle.make_waffle(\n", + " ax=ax, # pass axis to make_waffle \n", + " rows=20,\n", + " columns=5,\n", + " values=values,\n", + " vertical=True,\n", + " )\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Custom colors and style\n", + "\n", + "The previous graphs lack the comments and legends needed for easy interpretation.\n", + "\n", + "To this end, we're going to add :\n", + "- a **legend**: it is created by **iterating** through a list of colors and generating graphical elements (`Patches`) with corresponding labels\n", + "- a **title** via the `subtitle()` function\n", + "- change the **colors** with the `colors` argument\n", + "- change the **shapes** with the `icons` argument" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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TEePHnXqNi1L8est/qP//PnzFBISYt++YMGCUsfec8899st79uxJRGXfb99//3268cYbKSAggKpXr04PPfQQnTp1qsx6jPzZIsTVShbpJWzevNnhgWfu3LkOl69cubLcHyhPPfVUhQurTp06lXrwKX75bbfdRtWqVSt1XHR0NJ05c8Z+TEULM6vVWmrRUfJr586d9v0r+sHzxhtvkI+PT7k5zZs3p5MnTzp921a0SP/1118dLn/kkUfKPK5Tp04O3xdfpI8fP77CvuvUqVNqcfn555+X2WNUVBR16NDB8EX6F198QaGhoeXWOG7cuFJzcXeRXlBQQAMHDqwwp1mzZnTixIly53TLLbeQl5dXpffJipRcpN91111l1tK3b1+yWq1ERLR161aHy/bu3euQWXwR36tXL6fqKCgooMTERPtx/v7+9Oabbzpcz8CBA+37X758mW699dYKb7/x48c7XMfFixcr3B8A3XrrrVRQUGA/puQMS97HnVmkT5gwocLr9PPzo2+//dbhmOKLtoYNG1Lt2rXLPPadd95xOG7r1q0Oi7qir4CAAOrRo4f9e2cX6SWf+LjnnnscLj958iR5e3vbL3/88cftl61evZqCgoIq/Df/22+/OeQV//d58803U1RUVKnjvLy8aO3atQ7HVfRY+fbbb5Ofn1+5dcyZM6fM273kIn3jxo0UExNTbk54eDj98MMPTt2uJZW3SCciGjVqlMNtUlx2drbDbbxixQoiKn2/7d69e5k1N2zYsNRjhdE/W4S4WskivQzNmjWzP1i0b9/e4bI+ffrYLyv+jM6HH37o8CBzxx130PPPP0+jRo1y+IFWfPFJRKUenJo2bUpPPfUU9erVy2H7iy++aD+mooVZyWcLo6Oj6bHHHqPnnnuOBg0aRMHBwU4t0jds2ODwC0NiYiI999xzNGHCBIcfIrfddpvTt2vxutx9Jh0AxcTE0OjRo+nZZ5+1/0B///33HfZp0aIFTZkyhYYPH+7wA75x48b2mV26dIlq1Khhv8zX15ceffRR+s9//kN169Z1yDNikX7kyBGHH3ZeXl50991307PPPkvJycnUtGlT+yJ94cKFpX7pGzlyJM2cOZNmzpxJH330UaW1PP/88w6XJSYm0tSpU+nee+912N6tW7dy5+TsfbIiJRfpXl5e9OCDD9LTTz9NTZs2dbjsvffesx9X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vDIyMnD77bejVatWDvsQEdatW6ftQ8uGDx+OqVOn4tKlS0hNTbX/wuzn51fp54EsWbIEDzzwgP0Jk6VLl9ov8/Pzs//lmdPPFiGqmizSy+Hv74/7778fb7zxBgDHBVKfPn0cnmEAgIkTJ9ofxDZs2IBWrVqhT58+iIyMRGZmJnbu3ImffvoJtWvXdliYGalatWqYOHGifSFz/PhxNGvWDAMHDkTNmjVx+PBhrF69Gt9//z3atGlTYdaECRPw2WefgYjw+++/o2XLlujfvz9q1qyJ8+fP45dffsH69etx6dIlDBkyREs/rpgwYQIefPBBALaF080334x+/frhxIkTDgvSxo0b46677gJg+4tH8V9qHnvsMWzduhWRkZFYsmQJ8vPzy7yusLAwNG7cGAcOHAAAvPDCC9i5cycsFgu+++67cmscO3Ys3nzzTfsz74MGDcLy5cvRpk0bZGVlITU1FV27dsWrr74KwPahOr6+vvY6nn76aezevRu+vr7o2rVrqQVTcdWqVcPjjz+OZ555BgCwadMmdOzYEbfffjv279/vsHjr1q2b289Iu2PKlCnYv38/6tWrh48//hhnz561X1bWB8aMGTPG/oxqTk4OANu/z+K/KBstKioKw4cPx1tvvQUAmDFjBrZt24akpCQEBATgzz//xObNm7Fz504MHToUd9xxBwDbL0e//vorANsvbNWqVUNQUBA++OADbX+6b9KkicP3d911F+68807s2bPH4VNUjZCQkIAWLVpg7969AGz3/SNHjqB+/fqlZumOYcOG2RfpxR9za9WqhZ49ezrsO2bMGMyfPx85OTk4d+4c2rRpg3vvvRdxcXHIzs7Gb7/9htTUVPz11184fPhwuX8tUjVx4kSsXr0aVqsVhYWF6NatGwYOHIgmTZrg1KlT+PrrrzF69Gj8+9//rjBn2LBh+N///oezZ8+ioKAAt9xyC+69915cf/31yM3NRVpaGlJTU3H69Gl8//33Wl4yFxERgQceeAALFiwAcOXlUX379i31M6+kb775Bj169EDnzp3x008/Yd26dfbLBg0ahKCgIAD8frYIUaWq4oXwXJR8p3nR1+eff17m/pMnT670jTAl30xV/LJFixY5XObOh+kYeZ70efPmVXgu26IvZxU/pqwP+XHmuJK3UXGVnSc9Nja21HnSP/vsM4c3CRd9hYaG0o033ljm7U9kOy9yWdfRsGFDh1PRuXue9CLFz4RQ/GvmzJlEVPl50kuebrHkV7NmzUp9EJA798mKlHzjaNeuXcus5a677rKfHaKkm266yWHfe++916nrdramst6Ue+nSpUrPk15yxiXPGFT0Vbt2bYezZ7jyRuTK5OXlOZwWsWRt5WVXNMvvv//e4bjiZx3asmULBQcHl7ouX19fhzfkuvrGUSLbOdPLOm/5hAkTytz/008/LbOWkl/F66/ocwxK3i+K88R50jds2FDhedLdvY+UvN6SvRVX8jMrAJT5wV0l77flff5B/fr1S51lzOifLUJcreSNoxW4+eabS700paxndIpMnz4dGzZswAMPPIAGDRrA398fvr6+qFOnDm6//XZMnz7d4dkFHby8vPDWW2/hm2++sT+r5Ofnh5CQEDRp0gT/+te/ULduXaeykpOTsXPnTvzrX/9C48aNERQUBB8fH9SsWRNdunTBM888g927d2vtxxWvvPIKvv32WwwYMACxsbHw9fVFSEgI2rRpg2eeeQZ79uwpNc++ffti7dq16Ny5MwIDAxEREYG7774bW7Zssf95tiwjRozAW2+9hWbNmsHPzw+1atXCY489hp9//rnCN8/16tULe/fuxcSJE9GqVSuEhITA19cXsbGxuOuuu+wvmyny1ltvYejQoahZs2ap18JXxtvbGytWrMDKlSvRq1cv1KhRAz4+PggPD0dCQgJmzpyJrVu3Vvhaax2++uorPPPMM2jQoAH8/PxQv359PPvss1i1alW5rwkeO3asw/c6X+pSJCgoCF9//TWWLVuGXr16oWbNmvDx8UFgYCAaNWqEe+65BwsXLsTs2bPtx/zzn//EihUr0Lp1a/j6+iI6Ohr33XcfNm/erO129vX1xXfffYdhw4YhOjoa/v7+aNmyJRYuXIjnnnvO8Otr3749NmzYgDvvvBMhISEICQlBjx49kJqaittuu00pu+gvmCWV93rzf/zjH/j1118xfvx43HDDDQgJCYG3tzeio6PRoUMHTJw4ERs2bCj1BlGjjRgxArt27cJjjz2Gpk2bIigoCP7+/oiLi8M999yDjh07OpWTlJSEvXv34plnnkG7du0QFhYGb29vREREoF27dhg9ejS+/fZbdO7cWVsvLVq0QPfu3e3fx8bG2v9SVJEnnngCH374Idq1a4eAgABER0dj6NCh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OHToEHr27IkBAwZgz549WL58OX766SeMHj3aIeuVV17BTTfdhJ07dyI5ORmPPfYY0tLSyrzeP//8E507d4a/vz++++47bN++HcOHD0dBQUGZ+7/44ot4//33MX/+fOzduxePP/44HnjgAaxfv96lfuvXr49bb70VixYtcti+aNEiDBs2zOF88xMnTsQrr7yCrVu3onr16ujTp4/9jCqV3Sbbtm3D2LFj8fzzzyMtLQ3/7//9P3Tu3NmlWg1BRinIJTq1jejkVqILx65szzlPdGY3kbWw6jM51KgrUxWHPjnUaFYcbjsONerKVMWhTw416spUxaFPDjXqyiyDxWKh3377jSwWi3LWvn37CAB9//339m2dOnWiBx54gIiIRowYQf/6178cjvnxxx+pWrVq9uuvV6+efX8iIqvVSjVq1KA333yTiIgOHz5MAGjnzp1ERDR58mRq0KAB5eXllVnT0KFD6e677yYiopycHAoKCqKNGzc67DNixAi6//77K+3v2WefpdatW9u/X758OUVGRlJOTg4REW3fvp28vLzo8OHDRET0/fffEwD66KOP7MdkZmZSYGAgLV++3KnbZNWqVRQWFkYXLlyotD5XuTJ7416TvvE54OcX//7GC+j/he2/X9wP5P4F3PQE0GVm1WZyqFFXpioOfXKo0aw43HYcatSVqYpDnxxq1JWpikOfHGrUlalZ06ZNkZSUhHfffRddu3bF77//jh9//BHPP/88AGD37t3Ys2cPli5daj+GiGC1WnH48GE0a9YMABxeu+7l5YVatWrZPx2zpF27dqFTp07w9fWttL7ff/8dly9fxm233eawPS8vD23btnW533/84x8YNWoUPv30U/zzn//E4sWL0a1bN9SvX99hvw4dOtj/PyoqCk2aNMG+ffsAVH6b3HbbbahXrx4aNmyInj17omfPnujXr5/HP3jKuEX6jWOBmBYAEfDTU8BXQ4CccwBZbZef21f1mRxq1JWpikOfHGo0Kw63HYcadWWq4tAnhxp1Zari0CeHGnVlesCIESMwZswYzJs3D4sWLUKjRo3QpUsXALbXpz/66KMYO3ZsqeOuu+46+/+XXHB7eXnBarWWeX1Fn5zpjOzsbADAF198gTp16jhc5u/v73ROET8/PwwZMgSLFi1C//79sWzZMqSkpLiUUdlt4ufnhx07diA1NRXffPMNpk6diueeew5bt25FRESEyzW7y7VFOhFgySx2dADgF2L7/+BaQLPBQGE+kLYc+GMNUM0X8I8EvH2Bpvd7JpNDjboyVXHok0ONZsXhtuNQo65MVRz65FCjrkxVHPrkUKOuzCo2cOBAjBs3DsuWLcP777+Pxx57zP6hOTfeeCN+++03XH/99YZdX6tWrfDee+8hPz+/0mfTmzdvDn9/f6Snp9t/cVD18MMPo2XLlnjjjTdQUFCA/v37l9pn8+bN9l9CsrKycODAAftfDZy5TXx8fHDrrbfi1ltvxbPPPouIiAh89913ZV6XLq4t0j/tDRz+0nFbwz5Arw8A/3DbnX7NQCD9O9tlfmHAiN+BgAjPZXKoUVemKg59cqjRrDjcdhxq1JWpikOfHGrUlamKQ58catSVWcVCQkJw3333YfLkybhw4QKGDRtmv2zSpElITEzE6NGj8fDDDyM4OBi//fYbvv32W8ydO9et6xs9ejRef/11/POf/8TkyZMRHh6OzZs3o3379mjSpInDvqGhoXjiiSfw+OOPw2q1omPHjjh//jw2bNiAsLAwDB061OXrb9asGRITEzFp0iQMHz68zGf2n3/+eURHR6NmzZp4+umnERMTY/+ApcpukzVr1uCPP/5A586dERkZiS+//BJWq7VUb7q5dnaX42W8C/ePz4GPbwP+3AAsS7hypwaAnExgy3TPZnKoUVemKg59cqjRrDjcdhxq1JWpikOfHGrUlamKQ58catSVaQIjRoxAVlYW7rjjDsTGxtq3t2rVCuvXr8eBAwfQqVMntG3bFlOnTnXYx1XR0dH47rvvkJ2djS5duqBdu3Z46623yn1Wfdq0aXjmmWfw4osvolmzZujZsye++OILNGjQwO0aRowYgby8PAwfPrzMy1966SWMGzcO7dq1w6lTp/D555/Dz88PQOW3SUREBD755BN0794dzZo1w/z58/Hhhx+iRYsWbtfrDi+iYufscZa1ELh0yvbarAMrgT0Ly9/X2w94aD8QWB3wDQb+/vOL9kwONerKVMWhTw41mhWH245DjboyVXHok0ONujJVceiTQ426Mp2Uk5ODw4cPo0GDBggICFDKulZNmzYNK1euLPWJqqmpqejWrRuysrI8+vpxZ7kye9cW6ecPA9//2/YbZv4lILo5cMvzQEA08EkvoODylX0jGgG3zgc+vt32eq8C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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "number_of_bars = len(df.columns) # one bar per year\n", + "colors = [\"darkred\", \"red\", \"darkorange\"]\n", + "\n", + "# Init the whole figure and axes\n", + "fig, axs = plt.subplots(nrows=1,\n", + " ncols=number_of_bars,\n", + " figsize=(8,6),)\n", + "\n", + "# Iterate over each bar and create it\n", + "for i,ax in enumerate(axs):\n", + " \n", + " col_name = df.columns[i]\n", + " values = df[col_name]/1000 # values from the i-th column\n", + " \n", + " Waffle.make_waffle(\n", + " ax=ax, # pass axis to make_waffle \n", + " rows=20,\n", + " columns=5,\n", + " values=values,\n", + " title={\"label\": col_name, \"loc\": \"left\"},\n", + " colors=colors,\n", + " vertical=True,\n", + " icons=['car-side', 'truck', 'motorcycle'],\n", + " font_size=12, # size of each point\n", + " icon_legend=True,\n", + " legend={'loc': 'upper left', 'bbox_to_anchor': (1, 1)},\n", + " )\n", + " \n", + "# Add a title\n", + "fig.suptitle('Vehicle Production by Year and Vehicle Type',\n", + " fontsize=14, fontweight='bold')\n", + "\n", + "\n", + "# Add a legend\n", + "legend_labels = df.index\n", + "legend_elements = [mpatches.Patch(color=colors[i],\n", + " label=legend_labels[i]) for i in range(len(colors))]\n", + "fig.legend(handles=legend_elements,\n", + " loc=\"upper right\",\n", + " title=\"Vehicle Types\",\n", + " bbox_to_anchor=(1.04, 0.9))\n", + "\n", + "plt.subplots_adjust(right=0.85)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Going further\n", + "\n", + "This post explains how to create a [waffle bar chart](https://python-graph-gallery.com/waffle-chart/).\n", + "\n", + "For more examples of **how to create or customize** your waffle chart, see the [waffle section](https://python-graph-gallery.com/waffle-chart/). You may also be interested in how to create a [waffle chart with grouping](https://python-graph-gallery.com/541-waffle-chart-with-additionnal-grouping/)." + ] + } + ], + "metadata": { + "chartType": "waffle", + "description": "A waffle chart is a graphical representation of data points in a dataset, where individual data points are represented by small squares on a two-dimensional grid. This type of plot allows us to visualize the distribution of categorical data by showing the proportion or count of each category within the grid.
Matplotlib and Pywaffle allows us to create waffle charts easily. You can check this introduction to waffle charts. In this post, we will explore how to leverage Matplotlib to create stacked waffle bar charts.", + "family": "partOfAWhole", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "keywords": "waffle, stacked, chart, matplotlib, bar", + "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.9.13" + }, + "seoDescription": "How to create a stacked waffle bar chart with matplotlib", + "slug": "558-waffle-bar-chart", + "title": "Stacked Waffle bar chart " + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/src/pages/barplot.js b/src/pages/barplot.js index 7d45a66594..3dc9edccdc 100644 --- a/src/pages/barplot.js +++ b/src/pages/barplot.js @@ -285,6 +285,11 @@ export default function Barplot() { caption="Percent stacked barchart with python and seaborn" linkTo="/stacked-and-percent-stacked-barplot" /> +
diff --git a/src/pages/boxplot.js b/src/pages/boxplot.js index cbc26d71b0..1e4c8af735 100644 --- a/src/pages/boxplot.js +++ b/src/pages/boxplot.js @@ -223,9 +223,15 @@ export default function Boxplot() { linkTo="/509-introduction-to-swarm-plot-in-matplotlib" /> {' '} + diff --git a/src/pages/candlestick.js b/src/pages/candlestick.js index a9d148ae3e..9452a1217d 100644 --- a/src/pages/candlestick.js +++ b/src/pages/candlestick.js @@ -7,7 +7,7 @@ import Row from 'react-bootstrap/Row'; import ChartImageContainer from '../components/ChartImageContainer'; import ChartFamilySection from '../components/ChartFamilySection'; import { Link } from 'gatsby'; -import { Matplotlib, Seaborn } from '../components/MiscellaneousLogos'; +import { Matplotlib, Seaborn , Plotly} from '../components/MiscellaneousLogos'; import { Button, Col } from 'react-bootstrap'; import CodeChunk from '../components/CodeChunk'; import ChartImage from '../components/ChartImage'; @@ -132,6 +132,48 @@ export default function Boxplot() { + +

+ + Candlestick with Plotly +

+

+ Plotly is a library that allows you to create{' '} + interactive charts. You can find here its{' '} + + official documentation for candlestick charts. +

+

+ Building a candlestick chart with Plotly is made easy thanks to its{' '} + go.Candlestick() function. It takes as input a{' '} + fig object that can be customized with a{' '} + layout object. +

+

+ Check the example below to understand how to build it from your + dataset: +

+ + + + + +
+ + +