{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd # pandas import for data manipulation\n", "import numpy as np\n", "import ipywidgets as widgets\n", "# Jupyter import for iteractive widgets ()\n", "from ipywidgets import interact, interact_manual, interactive, HBox, VBox, Layout\n", "import matplotlib.pyplot as plt\n", "from IPython.display import display\n", "\n", "# import bokeh palette to color graphs\n", "from bokeh.palettes import Category10_10 as palette\n", "import itertools # import itertool to loop over palette\n", "\n", "# %matplotlib inline\n", "raw_data = pd.read_csv('data.csv',\n", " sep=',', skiprows=0, index_col=False) # read data" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "code_folding": [] }, "outputs": [], "source": [ "def wm(df):\n", " wm = sum(df['price']*df['results'])/sum(df['results'])\n", " return wm\n", "\n", "\n", "def std(df):\n", " p_mean = wm(df)\n", " std = (sum(df['results']*(df['price']-(p_mean))**2) /\n", " (sum(df['results'])-1))**0.5\n", " return std" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "code_folding": [] }, "outputs": [], "source": [ "def color_picker(models, model, colors):\n", " if len(models) <= len(palette):\n", " # give each model in the list sequential palette color\n", " current_color = palette[models.index(model)]\n", " else:\n", " # cycle through palette if more models than colors\n", " current_color = next(colors)\n", " return current_color" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "code_folding": [] }, "outputs": [], "source": [ "def default_graph():\n", " fig, ax = plt.subplots(1, 1, figsize=(8, 6))\n", " ax.grid(True)\n", " ax.set_title('Trend', fontsize=16)\n", " ax.set_xlabel('Year', fontsize=16)\n", " ax.set_ylabel('Price', fontsize=16)\n", " ax.autoscale(tight=True)\n", "\n", " return fig, ax\n", "\n", "\n", "def default_dist():\n", " fig, ax = plt.subplots(1, 1, figsize=(8, 6))\n", " ax.grid(True)\n", " ax.set_title('Distribution', fontsize=16)\n", " ax.set_xlabel('Price', fontsize=16)\n", " ax.set_ylabel('Offers', fontsize=16)\n", " ax.autoscale(tight=True)\n", " return fig, ax" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "code_folding": [ 13 ], "scrolled": false }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "c2a639efe187442bb498b76a5c8df7e5", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(VBox(children=(SelectMultiple(description='Model', options=('opel corsa (FR)', 'opel corsa (DE)…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# make a cyclable palette for large models lists\n", "colors = itertools.cycle(palette)\n", "\n", "\n", "def update(models=['renault clio (FR)'], year=2012, checkbox_status=False):\n", "\n", " # create 2 output widgets to intercept graphs\n", " out1 = widgets.Output()\n", " out2 = widgets.Output()\n", "\n", " # create a Tab widget to arrange Output widgets\n", " tab = widgets.Tab(children=[out2, out1])\n", " tab.set_title(0, 'Distribution')\n", " tab.set_title(1, 'Trend')\n", "\n", " # redirect mpl output to one Output widget (tabs separation)\n", " with out1:\n", " fig, ax = default_graph()\n", " for model in models: # loop through the selected models\n", "\n", " # set color scheme for selected models\n", " current_color = color_picker(models, model, colors)\n", "\n", " price_by_year = pd.DataFrame() # create empty data frame\n", "\n", " price_by_year['year'] = raw_data[raw_data['model']\n", " == model]['year'].unique() # get years for a specific model\n", "\n", " price_by_year['price'] = raw_data[raw_data['model'] == model][[\n", " 'year', 'results', 'price']].groupby('year').apply(wm).values # get weighted mean price per year\n", "\n", " price_by_year['std'] = raw_data[raw_data['model'] == model][[\n", " 'year', 'results', 'price']].groupby('year').apply(std).values # get standard deviation\n", "\n", " price_by_year['lower'] = price_by_year['price'] - \\\n", " price_by_year['std'] # get lower band limit\n", "\n", " price_by_year['upper'] = price_by_year['price'] + \\\n", " price_by_year['std'] # get upper band limit\n", "\n", " if checkbox_status:\n", "\n", " ax.fill_between(price_by_year['year'], price_by_year['lower'],\n", " price_by_year['upper'], facecolor=current_color, alpha=0.3)\n", " ax.plot(price_by_year['year'], price_by_year['price'], lw=3,\n", " color=current_color, marker=\".\", markersize=10, label=model)\n", "\n", " # display(fig)\n", " plt.show(fig)\n", "\n", " # redirect mpl output to the second Output widget (tabs separation)\n", " with out2:\n", " fig2, ax2 = default_dist()\n", "\n", " for model in models: # loop through the selected models\n", "\n", " # set color scheme for selected models\n", " current_color = color_picker(models, model, colors)\n", "\n", " # prepare price distribution for a selected year\n", "\n", " df = raw_data[(raw_data['model'] == model) & (\n", " raw_data['year'] == year)] # create filtered df\n", " # introduce shift of bars in bar plot for better visibility\n", " shift = models.index(model)*200/len(models)\n", " # smoothen results by rolling mean with window 5\n", " x = df['price'].values+shift\n", " # create array of bar width parameters for mpl bar plot\n", " width_arr = np.ones(len(x))*150\n", " # calculate sliding window mean with winndow size 5\n", " y_rolling_mean = df['results'].rolling(5).mean().values\n", " # create bar plot\n", " ax2.bar(x, y_rolling_mean, color=current_color,\n", " width=width_arr, linewidth=1, label=model, alpha=1.0)\n", "\n", " plt.show(fig2)\n", "\n", " # add legends to the plots\n", " ax2.legend(loc='best')\n", " ax.legend(loc='best')\n", " # display graphs wrapped in Tab widgets\n", " display(tab)\n", "\n", " return\n", "\n", "\n", "# create instance of Interactive widget acting as a container for other widgets\n", "widget = interactive(update, models=widgets.SelectMultiple(\n", " options=list(raw_data['model'].unique()),\n", " value=[],\n", " # rows=8,\n", " description='Model',\n", " disabled=False),\n", " year=widgets.IntSlider(\n", " value=2012,\n", " min=2008,\n", " max=2016,\n", " step=1,\n", " description='year',\n", " disabled=False,\n", " continuous_update=True,\n", " orientation='horizontal',\n", " readout=True,\n", " readout_format='d'),\n", " checkbox_status=widgets.Checkbox(\n", " value=False,\n", " description='Show trend error bar',\n", " disabled=False)\n", ")\n", "\n", "# create vertical column with control elements\n", "controls = VBox(widget.children[:-1],\n", " layout=Layout(width='35%', height='400px'))\n", "# declare output window as the Output widget (last in child list) of interactive widget\n", "output = widget.children[-1]\n", "\n", "# display created design\n", "display(HBox([controls, output]))\n", "\n", "#show(update(), notebook_handle=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.9" }, "toc": { "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }