#!/usr/bin/env python # coding: utf-8 # In[1]: import pandas as pd # pandas import for data manipulation import numpy as np import ipywidgets as widgets # Jupyter import for iteractive widgets () from ipywidgets import interact, interact_manual, interactive, HBox, VBox, Layout import matplotlib.pyplot as plt from IPython.display import display # import bokeh palette to color graphs from bokeh.palettes import Category10_10 as palette import itertools # import itertool to loop over palette # %matplotlib inline raw_data = pd.read_csv('data.csv', sep=',', skiprows=0, index_col=False) # read data # In[2]: def wm(df): wm = sum(df['price']*df['results'])/sum(df['results']) return wm def std(df): p_mean = wm(df) std = (sum(df['results']*(df['price']-(p_mean))**2) / (sum(df['results'])-1))**0.5 return std # In[3]: def color_picker(models, model, colors): if len(models) <= len(palette): # give each model in the list sequential palette color current_color = palette[models.index(model)] else: # cycle through palette if more models than colors current_color = next(colors) return current_color # In[4]: def default_graph(): fig, ax = plt.subplots(1, 1, figsize=(8, 6)) ax.grid(True) ax.set_title('Trend', fontsize=16) ax.set_xlabel('Year', fontsize=16) ax.set_ylabel('Price', fontsize=16) ax.autoscale(tight=True) return fig, ax def default_dist(): fig, ax = plt.subplots(1, 1, figsize=(8, 6)) ax.grid(True) ax.set_title('Distribution', fontsize=16) ax.set_xlabel('Price', fontsize=16) ax.set_ylabel('Offers', fontsize=16) ax.autoscale(tight=True) return fig, ax # In[5]: # make a cyclable palette for large models lists colors = itertools.cycle(palette) def update(models=['renault clio (FR)'], year=2012, checkbox_status=False): # create 2 output widgets to intercept graphs out1 = widgets.Output() out2 = widgets.Output() # create a Tab widget to arrange Output widgets tab = widgets.Tab(children=[out2, out1]) tab.set_title(0, 'Distribution') tab.set_title(1, 'Trend') # redirect mpl output to one Output widget (tabs separation) with out1: fig, ax = default_graph() for model in models: # loop through the selected models # set color scheme for selected models current_color = color_picker(models, model, colors) price_by_year = pd.DataFrame() # create empty data frame price_by_year['year'] = raw_data[raw_data['model'] == model]['year'].unique() # get years for a specific model price_by_year['price'] = raw_data[raw_data['model'] == model][[ 'year', 'results', 'price']].groupby('year').apply(wm).values # get weighted mean price per year price_by_year['std'] = raw_data[raw_data['model'] == model][[ 'year', 'results', 'price']].groupby('year').apply(std).values # get standard deviation price_by_year['lower'] = price_by_year['price'] - \ price_by_year['std'] # get lower band limit price_by_year['upper'] = price_by_year['price'] + \ price_by_year['std'] # get upper band limit if checkbox_status: ax.fill_between(price_by_year['year'], price_by_year['lower'], price_by_year['upper'], facecolor=current_color, alpha=0.3) ax.plot(price_by_year['year'], price_by_year['price'], lw=3, color=current_color, marker=".", markersize=10, label=model) # display(fig) plt.show(fig) # redirect mpl output to the second Output widget (tabs separation) with out2: fig2, ax2 = default_dist() for model in models: # loop through the selected models # set color scheme for selected models current_color = color_picker(models, model, colors) # prepare price distribution for a selected year df = raw_data[(raw_data['model'] == model) & ( raw_data['year'] == year)] # create filtered df # introduce shift of bars in bar plot for better visibility shift = models.index(model)*200/len(models) # smoothen results by rolling mean with window 5 x = df['price'].values+shift # create array of bar width parameters for mpl bar plot width_arr = np.ones(len(x))*150 # calculate sliding window mean with winndow size 5 y_rolling_mean = df['results'].rolling(5).mean().values # create bar plot ax2.bar(x, y_rolling_mean, color=current_color, width=width_arr, linewidth=1, label=model, alpha=1.0) plt.show(fig2) # add legends to the plots ax2.legend(loc='best') ax.legend(loc='best') # display graphs wrapped in Tab widgets display(tab) return # create instance of Interactive widget acting as a container for other widgets widget = interactive(update, models=widgets.SelectMultiple( options=list(raw_data['model'].unique()), value=[], # rows=8, description='Model', disabled=False), year=widgets.IntSlider( value=2012, min=2008, max=2016, step=1, description='year', disabled=False, continuous_update=True, orientation='horizontal', readout=True, readout_format='d'), checkbox_status=widgets.Checkbox( value=False, description='Show trend error bar', disabled=False) ) # create vertical column with control elements controls = VBox(widget.children[:-1], layout=Layout(width='35%', height='400px')) # declare output window as the Output widget (last in child list) of interactive widget output = widget.children[-1] # display created design display(HBox([controls, output])) #show(update(), notebook_handle=True) # In[ ]: # In[ ]: # In[ ]: