具有多个 iPyWidgets 下拉菜单的交互式 Covid 图
Interactive Covid Plot with Multiple iPyWidgets Dropdowns
我正在尝试组装一个 Jupyter Notebook,它允许用户在下拉列表中输入一个州,这会将第二个下拉列表中的结果更改为仅显示该州的城市。一旦选择了城市,就可以按下一个按钮来刷新图表(我知道你可以使用 manual with interact,但无法让它正常运行)并显示结果数据(covid cases over time)。我在制作小部件方面取得了一些成功,但我无法正确绘制数据。
这是我第一次在 Jupyter 中使用小部件,我对交互、交互、显示和观察有点迷茫(更不用说已弃用的 on_trait_change)。这是我目前所拥有的...
from ipywidgets import interact, widgets
from bqplot import pyplot as plt
import pandas as pd
#make example DF
date_list = ['2020-02-01','2020-02-01','2020-02-01','2020-02-01','2020-02-02','2020-02-02','2020-02-02','2020-02-02']
state_list = ['CA','NY','CA','NY','CA','NY','CA','NY']
city_list = ['San Fran','NYC','LA','Albany','San Fran','NYC','LA','Albany']
cases_list = [0,0,0,0,2,6,4,8]
df = pd.DataFrame(index=date_list)
df['state'] = state_list
df['city'] = city_list
df['cases'] = cases_list
#getting unique state and city list sorted in alphabetical order
state_unique = df['state'].unique()
state_unique.sort()
state = widgets.Dropdown(
options=['All'] + list(state_unique),
value='CA', #indicates default starting value
description='State:', #this is the label for the dropdown
)
city = widgets.Dropdown(
description='City:',
)
# function that updates 'city' dropdown depending on value in 'state' dropdown
def list_cities(x):
if state.value == 'All':
city.options = ['']
return city_list
else:
temp = ['All'] + sorted(df.loc[df['state'].eq(state.value),'city'].unique())
city.options = temp
state.observe(list_cities, names = 'value') #the names part tells the observe the change name to look for, this is only looking for value changes
b_refresh = widgets.Button(
description='Refresh',
icon='fa-refresh',
button_style='warning',
layout=widgets.Layout(width='100px')
)
# plotting function
def set_plot(x_data,y_data):
plt.plot(x_data, y_data)
plt.show()
x = list(df.index.unique())
y = df.loc[\
(df['city']==city.value)&\
(df['state']==state.value),'cases']
b_refresh.on_click(set_plot(x, y))
display (state,city,b_refresh)
from ipywidgets.widgets import Dropdown, Button
from ipywidgets.widgets import Layout, HBox, VBox
import bqplot as bq
import pandas as pd
#make example DF
date_list = ['2020-02-01','2020-02-01','2020-02-01','2020-02-01','2020-02-07','2020-02-07','2020-02-07','2020-02-07']
state_list = ['CA','NY','CA','NY','CA','NY','CA','NY']
city_list = ['San Fran','NYC','LA','Albany','San Fran','NYC','LA','Albany']
cases_list = [0,10,0,12,2,6,4,8]
df = pd.DataFrame(index=date_list)
df['state'] = state_list
df['city'] = city_list
df['cases'] = cases_list
df.index = pd.to_datetime(df.index)
df.rename_axis("date", axis='index', inplace=True)
#getting unique state list sorted in alphabetical order
state_unique = df['state'].unique()
state_unique.sort()
#make graphical parts - 2 dropdowns and refresh button
state = Dropdown(
options=['All'] + list(state_unique),
value='All', #indicates default starting value
description='State:', #this is the label for the dropdown
layout=Layout(width='200px',
margin = '0px 0px 0px 0px')
)
city = Dropdown(
description='City:',
layout=Layout(width='200px',
margin = '0px 0px 0px 0px')
)
b_refresh = Button(
description='Refresh',
icon='fa-refresh',
button_style='warning',
layout=Layout(width='100px',
margin = '0px 0px 0px 60px')
)
#make graph parts
x = list(df.index.unique())
y = list(df.groupby('date')['cases'].sum())
xs = bq.DateScale()
ys = bq.LinearScale(min=0)
line = bq.Lines(
x=x,
y=y,
scales={'x': xs, 'y': ys}
)
x_ax = bq.Axis(
scale=xs,
label='Dates',
grid_lines='solid',
tick_format='%m-%d',
tick_rotate=-0,
label_location ='middle',
label_offset = "40px"
)
y_ax = bq.Axis(
scale=ys,
orientation='vertical',
tick_format=',d',
label='FillInLater',
grid_lines='solid',
label_offset = "60px"
)
# function that updates 'city' dropdown depending on value in 'state' dropdown
def list_cities(x):
if state.value == 'All':
global y
city.options = ['']
y = list(df.groupby('date')['cases'].sum())
else:
temp = ['All'] + sorted(df.loc[df['state'].eq(state.value),'city'].unique())
city.options = temp
update_city(x)
# function that updates graph's y values depending on value in 'city' dropdown
def update_city(x):
global y
if city.value == 'All':
matching_cities = df.loc[(df['state']==state.value),'cases'].to_frame(name='cases')
y = list(matching_cities.groupby('date')['cases'].sum())
else:
y = list(df.loc[\
(df['city']==city.value)&\
(df['state']==state.value),'cases'])
# update plot function
def set_plot(b):
global y
line.y = [y]
#assign widget actions to functions
state.observe(list_cities, names = 'value') #the names part tells .observe the change name to look for, this is only looking for value changes
city.observe(update_city, names = 'value')
b_refresh.on_click(set_plot)
#display all
fig = bq.Figure(
layout=Layout(width='95%', height='400px', border ='solid 1px gray'),
axes=[x_ax, y_ax],
marks=[line],
fig_margin=dict(top=10, bottom=80, left=80, right=20),
animation_duration=500
)
box = HBox(
children=(state, city, b_refresh),
layout=Layout(margin = '10px 0px 10px 0px')
)
vert_box = VBox(
children=(box, fig),
layout=Layout(border='solid 1px gray', margin = '0 0 0 0')
)
display (vert_box)
我正在尝试组装一个 Jupyter Notebook,它允许用户在下拉列表中输入一个州,这会将第二个下拉列表中的结果更改为仅显示该州的城市。一旦选择了城市,就可以按下一个按钮来刷新图表(我知道你可以使用 manual with interact,但无法让它正常运行)并显示结果数据(covid cases over time)。我在制作小部件方面取得了一些成功,但我无法正确绘制数据。
这是我第一次在 Jupyter 中使用小部件,我对交互、交互、显示和观察有点迷茫(更不用说已弃用的 on_trait_change)。这是我目前所拥有的...
from ipywidgets import interact, widgets
from bqplot import pyplot as plt
import pandas as pd
#make example DF
date_list = ['2020-02-01','2020-02-01','2020-02-01','2020-02-01','2020-02-02','2020-02-02','2020-02-02','2020-02-02']
state_list = ['CA','NY','CA','NY','CA','NY','CA','NY']
city_list = ['San Fran','NYC','LA','Albany','San Fran','NYC','LA','Albany']
cases_list = [0,0,0,0,2,6,4,8]
df = pd.DataFrame(index=date_list)
df['state'] = state_list
df['city'] = city_list
df['cases'] = cases_list
#getting unique state and city list sorted in alphabetical order
state_unique = df['state'].unique()
state_unique.sort()
state = widgets.Dropdown(
options=['All'] + list(state_unique),
value='CA', #indicates default starting value
description='State:', #this is the label for the dropdown
)
city = widgets.Dropdown(
description='City:',
)
# function that updates 'city' dropdown depending on value in 'state' dropdown
def list_cities(x):
if state.value == 'All':
city.options = ['']
return city_list
else:
temp = ['All'] + sorted(df.loc[df['state'].eq(state.value),'city'].unique())
city.options = temp
state.observe(list_cities, names = 'value') #the names part tells the observe the change name to look for, this is only looking for value changes
b_refresh = widgets.Button(
description='Refresh',
icon='fa-refresh',
button_style='warning',
layout=widgets.Layout(width='100px')
)
# plotting function
def set_plot(x_data,y_data):
plt.plot(x_data, y_data)
plt.show()
x = list(df.index.unique())
y = df.loc[\
(df['city']==city.value)&\
(df['state']==state.value),'cases']
b_refresh.on_click(set_plot(x, y))
display (state,city,b_refresh)
from ipywidgets.widgets import Dropdown, Button
from ipywidgets.widgets import Layout, HBox, VBox
import bqplot as bq
import pandas as pd
#make example DF
date_list = ['2020-02-01','2020-02-01','2020-02-01','2020-02-01','2020-02-07','2020-02-07','2020-02-07','2020-02-07']
state_list = ['CA','NY','CA','NY','CA','NY','CA','NY']
city_list = ['San Fran','NYC','LA','Albany','San Fran','NYC','LA','Albany']
cases_list = [0,10,0,12,2,6,4,8]
df = pd.DataFrame(index=date_list)
df['state'] = state_list
df['city'] = city_list
df['cases'] = cases_list
df.index = pd.to_datetime(df.index)
df.rename_axis("date", axis='index', inplace=True)
#getting unique state list sorted in alphabetical order
state_unique = df['state'].unique()
state_unique.sort()
#make graphical parts - 2 dropdowns and refresh button
state = Dropdown(
options=['All'] + list(state_unique),
value='All', #indicates default starting value
description='State:', #this is the label for the dropdown
layout=Layout(width='200px',
margin = '0px 0px 0px 0px')
)
city = Dropdown(
description='City:',
layout=Layout(width='200px',
margin = '0px 0px 0px 0px')
)
b_refresh = Button(
description='Refresh',
icon='fa-refresh',
button_style='warning',
layout=Layout(width='100px',
margin = '0px 0px 0px 60px')
)
#make graph parts
x = list(df.index.unique())
y = list(df.groupby('date')['cases'].sum())
xs = bq.DateScale()
ys = bq.LinearScale(min=0)
line = bq.Lines(
x=x,
y=y,
scales={'x': xs, 'y': ys}
)
x_ax = bq.Axis(
scale=xs,
label='Dates',
grid_lines='solid',
tick_format='%m-%d',
tick_rotate=-0,
label_location ='middle',
label_offset = "40px"
)
y_ax = bq.Axis(
scale=ys,
orientation='vertical',
tick_format=',d',
label='FillInLater',
grid_lines='solid',
label_offset = "60px"
)
# function that updates 'city' dropdown depending on value in 'state' dropdown
def list_cities(x):
if state.value == 'All':
global y
city.options = ['']
y = list(df.groupby('date')['cases'].sum())
else:
temp = ['All'] + sorted(df.loc[df['state'].eq(state.value),'city'].unique())
city.options = temp
update_city(x)
# function that updates graph's y values depending on value in 'city' dropdown
def update_city(x):
global y
if city.value == 'All':
matching_cities = df.loc[(df['state']==state.value),'cases'].to_frame(name='cases')
y = list(matching_cities.groupby('date')['cases'].sum())
else:
y = list(df.loc[\
(df['city']==city.value)&\
(df['state']==state.value),'cases'])
# update plot function
def set_plot(b):
global y
line.y = [y]
#assign widget actions to functions
state.observe(list_cities, names = 'value') #the names part tells .observe the change name to look for, this is only looking for value changes
city.observe(update_city, names = 'value')
b_refresh.on_click(set_plot)
#display all
fig = bq.Figure(
layout=Layout(width='95%', height='400px', border ='solid 1px gray'),
axes=[x_ax, y_ax],
marks=[line],
fig_margin=dict(top=10, bottom=80, left=80, right=20),
animation_duration=500
)
box = HBox(
children=(state, city, b_refresh),
layout=Layout(margin = '10px 0px 10px 0px')
)
vert_box = VBox(
children=(box, fig),
layout=Layout(border='solid 1px gray', margin = '0 0 0 0')
)
display (vert_box)