# 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)