Issue
In Jupyter Notebook I am trying to get 3 cascading dropdown list boxes to function dependant on the values defined in the list boxes.
It works to a fashion but it always takes 2 refreshes of various dropdown list boxes to get the data I want displayed
I started with the example in this article from towardsdatascience and modified it to add the third dropdown box.
I cannot work out where my change or observe is not doing a dynamic update so that no matter what I select I will get a new refresh when ever a dropdown list box is changed.
All help gratefully received Apologies if there is too much code/debug but i see others getting slated for not providing enough.
Here is the code.
# Modified From: - https://towardsdatascience.com/bring-your-jupyter-notebook-to-life-with-
interactive-widgets-bc12e03f0916
import pandas as pd
import numpy as np
import ipywidgets as widgets
from ipywidgets import Layout, AppLayout
from IPython.display import display
# From moriginal article. We use local file
# url = "https://data.london.gov.uk/download/number-international-visitors-london/b1e0f953-4c8a-4b45-95f5-e0d143d5641e/international-visitors-london-raw.csv"
# df_london = pd.read_csv(url)
# Initially, we will get the data and load it into a dataframe:
file = 'C:\\Users\\smelly\\data\\csv\\international-visitors-london-raw.csv'
df_london = pd.read_csv(file, encoding = 'ISO-8859-1')
# Example of when the dropdown year is selected a new text box is
# displayed to show the purpose filter
ALL = 'ALL'
def unique_sorted_values_plus_ALL(array):
unique = array.unique().tolist()
unique.sort()
unique.insert(0, ALL)
return unique
# variable to store the common output for both dropdowns
output = widgets.Output()
# Here are the three dropdowns:
dropdown_year = widgets.Dropdown(description='Year of Visit',
options = unique_sorted_values_plus_ALL(df_london.year))
dropdown_purpose = widgets.Dropdown(description='Purpose of Visit',
options = unique_sorted_values_plus_ALL(df_london.purpose))
dropdown_market = widgets.Dropdown(description='Country Market',
options = unique_sorted_values_plus_ALL(df_london.market))
def common_filtering(year, purpose, market):
output.clear_output()
if (year == ALL) & (purpose == ALL) & (market == ALL):
common_filter = df_london
elif (year == ALL):
common_filter = df_london[df_london.market == market]
elif (year == ALL):
lcommon_filter = df_london[df_london.purpose == purpose]
elif (purpose == ALL):
common_filter = df_london[df_london.year == year]
else:
common_filter = df_london[(df_london.year == year) &
(df_london.purpose == purpose) &
(df_london.market == market)]
with output:
display(common_filter)
# We amend the event handlers to call the lcommon_filtering function and pass the change.new value as well as the
# current value of the other dropdown:
def dropdown_year_eventhandler(change):
common_filtering(change.new, dropdown_purpose.value, dropdown_market.value)
def dropdown_purpose_eventhandler(change):
common_filtering(dropdown_year.value, dropdown_market.value, change.new)
def dropdown_market_eventhandler(change):
common_filtering(dropdown_year.value, dropdown_purpose.value, change.new)
# We bind the handlers to the dropdowns, and that’s it!
dropdown_year.observe(dropdown_year_eventhandler, names='value')
dropdown_purpose.observe(dropdown_purpose_eventhandler, names='value')
dropdown_market.observe(dropdown_market_eventhandler, names='value')
display(dropdown_year)
display(dropdown_purpose)
display(dropdown_market)
display(output)
Output If run the above in my Jupyter Notebook here is the output I get:
Set Year of Visit to 2004 - dataframe refreshes showing only entries for 2004
Set Year of Visit to 2004 - dataframe refreshes showing only entries for 2004
year quarter market dur_stay mode purpose area Visits (000s) Spend (£m) Nights (000s) sample
6637 2004 January-March Belgium 1-3 nights Air Holiday LONDON 4.443318 1.824694 7.118778 5
6638 2004 January-March Belgium 1-3 nights Air Business LONDON 7.285553 2.124391 11.397926 13
6639 2004 January-March Belgium 1-3 nights Air VFR LONDON 0.502538 0.040518 1.053520 1
6640 2004 January-March Belgium 1-3 nights Air Miscellaneous LONDON 0.380132 0.118981 0.760264 1
6641 2004 January-March Belgium 1-3 nights Sea Holiday LONDON 9.906320 1.340740 29.719000 6
... ... ... ... ... ... ... ... ... ... ... ...
10153 2004 October-December Other Africa 15+ nights Air Holiday LONDON 0.886168 0.429408 11.692750 2
10154 2004 October-December Other Africa 15+ nights Air Business LONDON 0.960389 2.196219 29.084010 3
10155 2004 October-December Other Africa 15+ nights Air VFR LONDON 3.969384 2.211225 221.007949 11
10156 2004 October-December Other Africa 15+ nights Air Study LONDON 1.405100 4.917840 140.509995 1
10157 2004 October-December Other Africa 15+ nights Air Miscellaneous LONDON 0.614155 0.315062 48.518200 1
Set purpose of Visit to Business - Nothing changes
Set Year of Visit to 2004 - dataframe refreshes showing only entries for 2004
year quarter market dur_stay mode purpose area Visits (000s) Spend (£m) Nights (000s) sample
6637 2004 January-March Belgium 1-3 nights Air Holiday LONDON 4.443318 1.824694 7.118778 5
6638 2004 January-March Belgium 1-3 nights Air Business LONDON 7.285553 2.124391 11.397926 13
6639 2004 January-March Belgium 1-3 nights Air VFR LONDON 0.502538 0.040518 1.053520 1
6640 2004 January-March Belgium 1-3 nights Air Miscellaneous LONDON 0.380132 0.118981 0.760264 1
6641 2004 January-March Belgium 1-3 nights Sea Holiday LONDON 9.906320 1.340740 29.719000 6
... ... ... ... ... ... ... ... ... ... ... ...
10153 2004 October-December Other Africa 15+ nights Air Holiday LONDON 0.886168 0.429408 11.692750 2
10154 2004 October-December Other Africa 15+ nights Air Business LONDON 0.960389 2.196219 29.084010 3
10155 2004 October-December Other Africa 15+ nights Air VFR LONDON 3.969384 2.211225 221.007949 11
10156 2004 October-December Other Africa 15+ nights Air Study LONDON 1.405100 4.917840 140.509995 1
10157 2004 October-December Other Africa 15+ nights Air Miscellaneous LONDON 0.614155 0.315062 48.518200
Set country Market to Belgium - Dataframe updates showing year 2004, market = Belgium, purpose = Business Works as expected
Set country Market to Belgium - Dataframe updates showing year 2004, market = Belgium, purpose = Business
year quarter market dur_stay mode purpose area Visits (000s) Spend (£m) Nights (000s) sample
6638 2004 January-March Belgium 1-3 nights Air Business LONDON 7.285553 2.124391 11.397926 13
6642 2004 January-March Belgium 1-3 nights Sea Business LONDON 3.348380 0.558413 6.682670 2
6645 2004 January-March Belgium 1-3 nights Tunnel Business LONDON 8.896553 2.482150 14.327898 20
6649 2004 January-March Belgium 4-7 nights Air Business LONDON 1.873621 1.522606 6.717740 4
6652 2004 January-March Belgium 4-7 nights Sea Business LONDON 1.674190 0.386508 6.682670 1
6654 2004 January-March Belgium 4-7 nights Tunnel Business LONDON 1.161537 0.666272 5.417160 3
6657 2004 January-March Belgium 8-14 nights Tunnel Business LONDON 0.391887 0.589908 5.474880 1
7436 2004 April-June Belgium 1-3 nights Air Business LONDON 12.233637 3.012382 17.830062 13
7440 2004 April-June Belgium 1-3 nights Sea Business LONDON 2.438620 0.174643 7.422190 1
7443 2004 April-June Belgium 1-3 nights Tunnel Business LONDON 9.825394 2.489263 15.252250 21
7446 2004 April-June Belgium 4-7 nights Air Business LONDON 0.779633 0.299457 3.480100 2
7451 2004 April-June Belgium 4-7 nights Tunnel Business LONDON 0.427832 0.547138 1.736200 1
7455 2004 April-June Belgium 8-14 nights Air Business LONDON 0.553725 1.660990 4.364970 1
7458 2004 April-June Belgium 8-14 nights Tunnel Business LONDON 0.445658 0.000000 4.069230 1
7461 2004 April-June Belgium 15+ nights Air Business LONDON 1.714030 0.875407 91.202904 1
8313 2004 July-September Belgium 1-3 nights Air Business LONDON 5.428023 2.023622 9.563622 9
8317 2004 July-September Belgium 1-3 nights Sea Business LONDON 1.936040 0.038780 5.795310 1
8320 2004 July-September Belgium 1-3 nights Tunnel Business LONDON 10.915149 3.652393 16.873318 21
8326 2004 July-September Belgium 4-7 nights Tunnel Business LONDON 2.032828 1.041474 10.141750 3
9291 2004 October-December Belgium 1-3 nights Air Business LONDON 13.759479 5.657460 19.735172 20
9296 2004 October-December Belgium 1-3 nights Sea Business LONDON 2.033270 0.026998 2.033270 1
9299 2004 October-December Belgium 1-3 nights Tunnel Business LONDON 7.496895 2.858201 11.117845 17
9302 2004 October-December Belgium 4-7 nights Air Business LONDON 1.145586 1.520935 4.933070 3
9305 2004 October-December Belgium 4-7 nights Tunnel Business LONDON 0.843375 0.503309 3.373500 2
9308 2004 October-December Belgium 8-14 nights Air Business LONDON 0.321972 0.052481 3.219720 1
9309 2004 October-December Belgium 8-14 nights Tunnel Business LONDON 0.830616 0.246976 5.399000 1
Solution
You had some errors with your filter choosing logic, and also in your event handler code, See below for a different implementation handling your inputs a bit clearer.
import functools
def common_filtering(year, purpose, market):
df = df_london.copy()
filters = []
if year is not ALL:
filters.append(df['year']==year)
if purpose is not ALL:
filters.append(df['purpose']==purpose)
if market is not ALL:
filters.append(df['market']==market)
output.clear_output()
with output:
if filters:
df_filter = functools.reduce(lambda x,y: x&y, filters)
display(df.loc[df_filter])
else:
display(df)
def dropdown_year_eventhandler(change):
common_filtering(change.new, dropdown_purpose.value, dropdown_market.value)
def dropdown_purpose_eventhandler(change):
common_filtering(dropdown_year.value, change.new, dropdown_market.value,)
def dropdown_market_eventhandler(change):
common_filtering(dropdown_year.value, dropdown_purpose.value, change.new)
Answered By - ac24
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.