def create_state_ctrls(self, btn_width=70, btn_container_width=90, layout='row'): """ Create state buttons: Run, Pause, Stop, Exit, etc. """ btn_run = Button(label="Run", button_type="success") btn_run.on_click(self.on_run_handler) btn_pause = Toggle(label="Pause", button_type="primary") btn_pause.on_change('active', self.on_pause_handler) btn_stop = Button(label="Stop", button_type="default") btn_stop.on_click(self.on_stop_handler) btn_exit = Button(label="Exit", button_type="danger") btn_exit.on_click(self.on_exit_handler) tmp = [] for btn in [btn_run, btn_pause, btn_stop, btn_exit]: btn.width = btn_width tmp.append(widgetbox(btn, width = btn_container_width)) if layout == 'row': self.state_ctrls = row(tmp) else: self.state_ctrls = column(tmp)
def __init__(self, data): self.map_data = data p_wgs84 = pyproj.Proj(init='epsg:4326') p_web = pyproj.Proj(init='epsg:3857') self.map_data.shape_country['geometry'] = self.map_data.shape_country['geometry'].to_crs(epsg=3857) self.country_source = GeoJSONDataSource( geojson=self.map_data.shape_country.to_json() ) self.priority_toggles = {} self.priority_groups = {} self.priority_groups_rect = {} self.priority_names = { 10: 'High', 20: 'Medium', 30: 'Low' } self.map_width = 800 self.map_height = 800 tooltips_map = [ ("Name", "@names"), ("POI", "@categories"), ] hover_map = HoverTool(tooltips=tooltips_map, mode='mouse', names=['marker'] ) plot_options_map = dict(plot_height=self.map_height, plot_width=self.map_width, tools=["pan,wheel_zoom,reset,save", hover_map], sizing_mode="fixed", toolbar_location='above', title='BiH' ) self.figure_map = figure(**plot_options_map) self.figure_map.xgrid.grid_line_color = None self.figure_map.ygrid.grid_line_color = None self.figure_map.xaxis.visible = False self.figure_map.yaxis.visible = False tile_provider = get_provider(Vendors.CARTODBPOSITRON) self.figure_map.add_tile(tile_provider) self.figure_map.multi_line('xs', 'ys', source=self.country_source, color='red', line_width=3 ) for shape in self.map_data.shape_municipalities: shape['geometry'] = shape['geometry'].to_crs(epsg=3857) source = GeoJSONDataSource( geojson=shape.to_json() ) self.figure_map.patches('xs', 'ys', source=source, line_color='green', color='navy', alpha=0.1, line_width=2) for priority in map_data.priorities: df = self.map_data.data.loc[self.map_data.data['priority'] == priority] urls = ['BiH/static/symbols/' + str(icon) + '.png' for icon in df['icon'].tolist()] x = df['longitude'].tolist() y = df['latitude'].tolist() names = df['name'].tolist() categories = df['category'].tolist() x, y = pyproj.transform(p_wgs84, p_web, x, y) w = [32 for i in range(len(x))] h = [37 for i in range(len(x))] source_marker = ColumnDataSource(data={ 'urls': urls, 'x': x, 'y': y, 'w': w, 'h': h }) self.priority_groups[priority] = self.figure_map.image_url(url='urls', x='x', y='y', w='w', h='h', h_units='screen', w_units='screen', anchor='center', source=source_marker) source_tooltip = ColumnDataSource(data={ 'x': x, 'y': y, 'names': names, 'categories': categories, 'w': w, 'h': h }) self.priority_groups_rect[priority] = self.figure_map.rect( x='x', y='y', width='w', height='h', fill_alpha=0, line_alpha=0, height_units='screen', width_units='screen', name='marker', source=source_tooltip) self.table_source = ColumnDataSource(data={ 'category': self.map_data.categories['category'], 'icon': self.map_data.categories['icon'], 'priority': self.map_data.categories['priority'], 'priority_names': [self.priority_names[p] for p in self.map_data.categories['priority']] }) columns = [TableColumn(field="icon", title="Icon", width=40, formatter=HTMLTemplateFormatter( template='<img src="BiH/static/symbols/<%= value %>.png" height="37" width="32">' )), TableColumn(field="category", title="Category", width=180, formatter=HTMLTemplateFormatter( template='<div style="position:relative;top:6px;font-size:12px;"><%= value %></div>' )), TableColumn(field="priority_names", title="Priority", width=80, formatter=HTMLTemplateFormatter( template='<div style="position:relative;top:6px;font-size:12px;"><%= value %></div>' ) )] data_view = CDSView(source=self.table_source, filters=[]) self.table = DataTable(columns=columns, source=self.table_source, view=data_view, sizing_mode='stretch_height', index_position=None, fit_columns=True, width=300, row_height=38, selectable=False) for priority in self.map_data.priorities: toggle = Toggle(label=self.priority_names[priority], button_type='success', width=48) toggle.on_change("active", update_table) self.priority_toggles[priority] = toggle
def histogram_bokeh(ks_distributions, labels): """ Run an interactive bokeh application. This requires a running bokeh server! Use ``bokeh serve &`` to start a bokeh server in the background. :param ks_distributions: a list of Ks distributions (pandas data frames) :param labels: a list of labels for the corresponding distributions :return: bokeh app """ from bokeh.io import curdoc from bokeh.layouts import widgetbox, layout from bokeh.models.widgets import Select, TextInput, Slider, Div from bokeh.models.widgets import CheckboxGroup, Toggle from bokeh.plotting import figure, output_file, show from bokeh.client import push_session from pylab import cm from .utils import gaussian_kde from .modeling import reflect # helper functions def get_colors(cmap_choice='binary'): too_light = [ 'binary', 'hot', 'copper', 'pink', 'summer', 'bone', 'Pastel1', 'Pastel2', 'gist_ncar', 'nipy_spectral', 'Greens' ] cmap = cm.get_cmap(cmap_choice, len(ks_distributions)) if cmap_choice in too_light: cmap = cm.get_cmap(cmap_choice, len(ks_distributions) * 4) c = [] for i in range(cmap.N): rgb = cmap(i)[:3] # will return rgba, but we need only rgb c.append(matplotlib.colors.rgb2hex(rgb)) if cmap_choice in too_light: if len(ks_distributions) > 1: c = c[2:-2] else: c = [c[-1]] return c def get_data(df, var, scale, r1, r2, outliers_included): df = filter_group_data(df, min_ks=r1, max_ks=r2, weights_outliers_included=outliers_included) data = df[var].dropna() if scale == 'log10': data = np.log10(data) return data, df # get the distributions dists = [pd.read_csv(x, sep='\t') for x in ks_distributions] if labels: labels = labels.split(',') else: labels = ks_distributions # basics c = get_colors() variables = ['Ks', 'Ka', 'Omega'] scales = ['Normal', 'log10'] # set up widgets div = Div(text=BOKEH_APP_DIV, width=800) var = Select(title='Variable', value='Ks', options=variables) scale = Select(title='Scale', value='Normal', options=scales) r1 = TextInput(title="Minimum", value='0.1') r2 = TextInput(title="Maximum", value='5') bins = TextInput(title="Bins", value='50') bandwidth = TextInput(title="Bandwidth", value='0.1') line = Slider(title="Lines", start=0, end=1, value=0.3, step=0.1) density = CheckboxGroup(labels=["Histogram", "KDE"], active=[0]) density_alpha = Slider(title="Density alpha value", start=0, end=1, value=0.6, step=0.1) hist_alpha = Slider(title="Histogram alpha value", start=0, end=1, value=0.6, step=0.1) color_choice = Select(options=[ 'binary', 'hsv', 'hot', 'magma', 'viridis', 'Greens', 'spring', 'autumn', 'copper', 'cool', 'winter', 'pink', 'summer', 'bone', 'RdBu', 'RdYlGn', 'coolwarm', 'inferno', 'Pastel1', 'Pastel2', 'tab10', 'gnuplot', 'brg', 'gist_ncar', 'jet', 'rainbow', 'nipy_spectral', 'ocean', 'cubehelix' ], value='binary', title='Color map') no_reweight = Toggle(label="Don't adapt weights when filtering", active=False) # set up figure p1 = figure( plot_width=1000, plot_height=700, # output_backend="svg", tools='pan,wheel_zoom,xwheel_zoom,ywheel_zoom,save') p1.xgrid.grid_line_color = None p1.ygrid.grid_line_color = None p1.border_fill_color = 'white' p1.outline_line_color = None p1.yaxis.axis_label = 'Duplications' p1.xaxis.axis_label = 'Ks' # draw initial plot hist_dict = {} density_dict = {} all_data = [] # set up callbacks def update(selected=None): redraw_plots() def redraw_plots(): print(density.active) c = get_colors(color_choice.value) p1.legend.items = [] all_data = [] for i in range(len(dists)): df = dists[i] data, df = get_data(df, var.value, scale.value, float(r1.value), float(r2.value), no_reweight.active) all_data.append(data) edges = np.histogram(np.hstack(tuple(all_data)), bins=int(bins.value))[1] for i in range(len(dists)): if density.active == [0]: hist = np.histogram(all_data[i], bins=int(bins.value))[0] p1.yaxis.axis_label = 'Duplications' else: hist = np.histogram(all_data[i], bins=int(bins.value), density=True)[0] p1.yaxis.axis_label = 'density' # First histograms if i in hist_dict: remove_plot(hist_dict, i) if 0 in density.active: hist_dict[i] = p1.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:], fill_color=c[i], line_color="black", fill_alpha=hist_alpha.value, line_alpha=line.value, legend=labels[i]) # Then KDEs if i in density_dict: density_dict[i].data_source.data['x'] = [] density_dict[i].data_source.data['y'] = [] if 1 in density.active: X = reflect(all_data[i]) kde = gaussian_kde(X, bw_method=float(bandwidth.value)) x = np.linspace( float(r1.value) + 0.000001, float(r2.value), 1000) if scale.value == 'log10': x = np.log10(x) pdf = np.array(kde(x)) * 2 # add boundaries such that it is a nice curve! pdf = np.hstack([0, pdf, 0]) if scale.value == 'log10': x = np.hstack([ np.log10(float(r1.value) + 0.00000099), x, np.log10(float(r2.value) + 0.000001) ]) else: x = np.hstack( [float(r1.value), x, float(r2.value) + 0.000001]) density_dict[i] = p1.patch(x=x, y=pdf, fill_color=c[i], line_width=2, line_color="black", line_alpha=line.value, alpha=density_alpha.value, legend=labels[i]) p1.legend.label_text_font_style = "italic" p1.legend.click_policy = "hide" p1.legend.inactive_fill_alpha = 0.6 v = var.value if v == "Omega": v = "Ka/Ks" if scale.value == 'log10': v = 'log10(' + v + ')' p1.xaxis.axis_label = v def remove_plot(hist_dict, i): hist_dict[i].data_source.data["top"] = [] hist_dict[i].data_source.data["left"] = [] hist_dict[i].data_source.data["right"] = [] def change_update(attrname, old, new): update() def feat_change(attrname, old, new): c = get_colors(color_choice.value) for i, d in density_dict.items(): d.glyph.fill_color = c[i] d.glyph.line_color = "black" d.glyph.fill_alpha = density_alpha.value d.glyph.line_alpha = line.value for i, d in hist_dict.items(): d.glyph.fill_color = c[i] d.glyph.line_color = "black" d.glyph.fill_alpha = hist_alpha.value d.glyph.line_alpha = line.value def bins_update(attrname, old, new): update() var.on_change('value', bins_update) bandwidth.on_change('value', bins_update) scale.on_change('value', bins_update) r1.on_change('value', bins_update) r2.on_change('value', bins_update) line.on_change('value', feat_change) bins.on_change('value', bins_update) color_choice.on_change('value', feat_change) density.on_change('active', bins_update) density_alpha.on_change('value', feat_change) hist_alpha.on_change('value', feat_change) no_reweight.on_change("active", bins_update) # set up layout widgets1 = widgetbox(var, scale, color_choice, density, line, hist_alpha, density_alpha, r1, r2, bins, bandwidth, no_reweight, sizing_mode='fixed') l = layout([ [div], [widgets1, p1], ], sizing_mode='fixed') # initialize update() session = push_session(curdoc()) curdoc().add_root(l) session.show(l) # open the document in a browser session.loop_until_closed() # run forever return # show(p1)
def make_start_end_figure(doc): """ Creates a Bokeh app for visualizations of start and end of hurricanes """ df_spawn_end = pd.read_csv('files/df_start_end_bokeh.csv', index_col=0) year_min, year_max, lon_boundaries, lat_boundaries = get_boundaries(df_spawn_end) gulf_stream_lon1, gulf_stream_lon2, gulf_stream_lat1, gulf_stream_lat2 = get_gulf_stream() # credits of the map url = 'http://a.basemaps.cartocdn.com/rastertiles/voyager/{Z}/{X}/{Y}.png' attribution = "Tiles by Carto, under CC BY 3.0. Data by OSM, under ODbL" add_paragraph = additional_legend(loc='tracks') # ----------------------------------------------------- # WIDGETS # ----------------------------------------------------- # definition and configuration of the number selection options_number = ['-1'] + [str(x) for x in list(np.arange(1, 21))] select_number = Select(title='Number of hurricanes:', value='5', options=options_number) # definition and configuration of the zone selection options_zone = ['All', 'Mexico_Caribbean', 'Atlantic'] select_zone = Select(title='Spawning Zone:', value='All', options=options_zone) # Definition of buttons for end points and distances toggle_month = Toggle(label="Show end points", button_type="success") toggle_dist_month = Toggle(label="Show distance traveled", button_type="success") # definition and configuration of the year and month sliders slider_year = RangeSlider(start=year_min, end=year_max, value=(year_min, year_max), step=1, title="Years") slider_month = RangeSlider(start=1, end=12, value=(1, 12), step=1, title="Months") # End points toggle_season = Toggle(label="Show end points", button_type="success") toggle_dist_season = Toggle(label="Show distance traveled", button_type="success") # definition and configuration of the number selection select_number_season = Select(title='Number of hurricanes:', value='5', options=options_number) # definition and configuration of the zone selection select_zone_season = Select(title='Spawning Zone:', value='All', options=options_zone) # definition and configuration of the year and sliders slider_year_season = RangeSlider(start=year_min, end=year_max, value=(year_min, year_max), step=1, title="Years") # definition and configuration of the season selection options_season = ['All', 'Winter', 'Spring', 'Summer', 'Autumn'] select_season = Select(title='Season:', value='All', options=options_season) # ------------------------------------------------------- # DATA SOURCE AND RANDOMIZATION # ------------------------------------------------------- np.random.seed(42) n = 5 select_list = list(np.random.choice(df_spawn_end.index, size=n, replace=False)) filtr = df_spawn_end.index.map(lambda x: x in select_list) source = ColumnDataSource(data=df_spawn_end[filtr]) # -------------------------------------------------------- # FIRST TAB # -------------------------------------------------------- # Initialization of the map p = figure(tools='pan, wheel_zoom', x_range=(lon_boundaries[0], lon_boundaries[1]), y_range=(lat_boundaries[0], lat_boundaries[1]), x_axis_type="mercator", y_axis_type="mercator") p.add_tile(WMTSTileSource(url=url, attribution=attribution)) # Add data points # - Start # - End # - Start with size adjusted to the traveled distance c1 = p.circle(x='x_start', y='y_start', fill_color='green', size=8, source=source, legend_label='Start points') c2 = p.circle(x='x_end', y='y_end', fill_color='orange', size=8, source=source, legend_label='End points') d1 = p.circle(x='x_start', y='y_start', fill_color='green', radius='Distance_draw', source=source) # Line between start and end points s1 = p.segment(x0='x_start', y0='y_start', x1='x_end', y1='y_end', line_dash='dashed', source=source) # Initial configuration of WIDGETS for FIRST TAB # - Don't show end points # - Don't show segments between start and end points # - Uniform size for starting points c2.visible, s1.visible, d1.visible = False, False, False # Configuration of the hovertool hover = HoverTool(tooltips=[("ID", "@ID"), ("Duration", "@Duration"), ("Distance", "@Distance")], renderers=[c1, c2, d1], formatters={'Duration': 'printf'}) p.tools.append(hover) # Draw the Gulf Stream p.segment(x0=gulf_stream_lon1[:-1], y0=gulf_stream_lat1[:-1], x1=gulf_stream_lon1[1:], y1=gulf_stream_lat1[1:], legend_label='Gulf Stream', color='red', line_alpha=0.5, line_width=2) p.segment(x0=gulf_stream_lon2[:-1], y0=gulf_stream_lat2[:-1], x1=gulf_stream_lon2[1:], y1=gulf_stream_lat2[1:], color='red', line_alpha=0.5, line_width=2) p.legend.location = "top_left" # DataFrame display no_cols = ['x_start', 'x_end', 'y_start', 'y_end', 'Distance_draw'] cols = [TableColumn(field=col, title=col) for col in df_spawn_end.columns if col not in no_cols] data_table = DataTable(columns=cols, source=source, width=1100, selectable=False) # ------------------------------------------------------------------------ # UPDATING FIRST TAB # ------------------------------------------------------------------------ # updating process of the data underlying the map depending on user actions. def update_map_se(attr, old, new): yr = slider_year.value month = slider_month.value zone = select_zone.value n = select_number.value n = int(n) if zone == 'All': df_temp = df_spawn_end.loc[(df_spawn_end['Year_start'] >= yr[0]) & (df_spawn_end['Year_start'] <= yr[1]) & (df_spawn_end['Month_start'] >= month[0]) & (df_spawn_end['Month_start'] <= month[1])] else: df_temp = df_spawn_end.loc[(df_spawn_end.Zones_start == zone) & (df_spawn_end['Year_start'] >= yr[0]) & (df_spawn_end['Year_start'] <= yr[1]) & (df_spawn_end['Month_start'] >= month[0]) & (df_spawn_end['Month_start'] <= month[1])] if n == -1: source.data = ColumnDataSource.from_df(df_temp) else: if n > len(df_temp): # For cases where there are not enough data points n = int(len(df_temp)) np.random.seed(42) select_list = list(np.random.choice(df_temp.index, size=n, replace=False)) filtr = df_temp.index.map(lambda x: x in select_list) source.data = ColumnDataSource.from_df(df_temp.loc[filtr]) def month_active(atrr, old, new): active = toggle_month.active dist = toggle_dist_month.active if not active: c2.visible, s1.visible = False, False toggle_month.label = "Show end points" else: c2.visible, s1.visible = True, True toggle_month.label= "Unshow end points" if not dist: c1.visible, d1.visible = True, False toggle_dist_month.label = "Show distance traveled" else: c1.visible, d1.visible = False, True toggle_dist_month.label = "Unshow distance traveled" # activation of the changes on user action select_number.on_change('value', update_map_se) slider_year.on_change('value', update_map_se) slider_month.on_change('value', update_map_se) select_zone.on_change('value', update_map_se) toggle_month.on_change('active', month_active) toggle_dist_month.on_change('active', month_active) # Make first tab tab_month = Panel(child=column(row(column(slider_year, slider_month, select_number, select_zone, toggle_month, toggle_dist_month), p, add_paragraph), data_table), title="Monthly") # ---------------------------------------------------------------------------- # SECOND TAB # ---------------------------------------------------------------------------- p_season = figure(tools='pan, wheel_zoom', x_range=(lon_boundaries[0], lon_boundaries[1]), y_range=(lat_boundaries[0], lat_boundaries[1]), x_axis_type="mercator", y_axis_type="mercator") p_season.add_tile(WMTSTileSource(url=url, attribution=attribution)) # Add data points # - Start # - End # - Start with size adjusted to the traveled distance c3 = p_season.circle(x='x_start', y='y_start', fill_color='green', size=8, source=source, legend_label='Start points') c4 = p_season.circle(x='x_end', y='y_end', fill_color='orange', size=8, source=source, legend_label='End points') d2 = p_season.circle(x='x_start', y='y_start', fill_color='green', radius='Distance_draw', source=source) # line between start and end points s2 = p_season.segment(x0='x_start', y0='y_start', x1='x_end', y1='y_end', line_dash='dashed', source=source) # Initial configuration of WIDGETS for SECOND TAB # - Don't show end points # - Don't show segments between start and end points # - Uniform size for starting points c4.visible, s2.visible, d2.visible = False, False, False # Configuration of the hovertool hover_season = HoverTool(tooltips=[("ID", "@ID"), ("Duration", "@Duration"), ("Distance", "@Distance")], renderers=[c3, c4], formatters={'Duration': 'printf'}) p_season.tools.append(hover_season) # Gulf Stream p_season.segment(x0=gulf_stream_lon1[:-1], y0=gulf_stream_lat1[:-1], x1=gulf_stream_lon1[1:], y1=gulf_stream_lat1[1:], legend_label='Gulf Stream', color='red', line_alpha=0.5, line_width=2) p_season.segment(x0=gulf_stream_lon2[:-1], y0=gulf_stream_lat2[:-1], x1=gulf_stream_lon2[1:], y1=gulf_stream_lat2[1:], color='red', line_alpha=0.5, line_width=2) p_season.legend.location = "top_left" # ------------------------------------------------------------------------ # UPDATING SECOND TAB # ------------------------------------------------------------------------ # updating process of the data underlying the map depending on user actions. def update_map_season(attr, old, new): yr = slider_year_season.value season = select_season.value zone = select_zone_season.value n = select_number_season.value n = int(n) if (zone == 'All') & (season == 'All'): df_temp = df_spawn_end.loc[(df_spawn_end['Year_start'] >= yr[0]) & (df_spawn_end['Year_start'] <= yr[1])] elif (zone != 'All') & (season == 'All'): df_temp = df_spawn_end.loc[(df_spawn_end.Zones_start == zone) & (df_spawn_end['Year_start'] >= yr[0]) & (df_spawn_end['Year_start'] <= yr[1])] elif (zone == 'All') & (season != 'All'): df_temp = df_spawn_end.loc[(df_spawn_end.Season_start == season) & (df_spawn_end['Year_start'] >= yr[0]) & (df_spawn_end['Year_start'] <= yr[1])] else: df_temp = df_spawn_end.loc[(df_spawn_end.Zones_start == zone) & (df_spawn_end.Season_start == season) & (df_spawn_end['Year_start'] >= yr[0]) & (df_spawn_end['Year_start'] <= yr[1])] if n == -1: source.data = ColumnDataSource.from_df(df_temp) else: if n > len(df_temp): # For cases where there are not enough data points n = int(len(df_temp)) np.random.seed(42) select_list = list(np.random.choice(df_temp.index, size=n, replace=False)) filtr = df_temp.index.map(lambda x: x in select_list) source.data = ColumnDataSource.from_df(df_temp.loc[filtr]) def season_active(atrr, old, new): active = toggle_season.active dist = toggle_dist_season.active if not active: c4.visible, s2.visible = False, False toggle_season.label = "Show end points" else: c4.visible, s2.visible = True, True toggle_season.label = "Show end points" if not dist: c3.visible, d2.visible = True, False toggle_dist_season.label = "Show distance traveled" else: c3.visible, d2.visible = False, True toggle_dist_season.label = "Unshow distance traveled" select_number_season.on_change('value', update_map_season) slider_year_season.on_change('value', update_map_season) select_season.on_change('value', update_map_season) select_zone_season.on_change('value', update_map_season) toggle_season.on_change('active', season_active) toggle_dist_season.on_change('active', season_active) # Make second tab tab_season = Panel(child=column(row(column(slider_year_season, select_number_season, select_season, select_zone_season,toggle_season, toggle_dist_season), p_season, add_paragraph), data_table), title="Seasonal") # ---------------------------------------------------------------------------- # FINAL SET UP # ---------------------------------------------------------------------------- tabs = Tabs(tabs=[tab_month, tab_season]) def tab_change(atrr, old, new): if tabs.active == 0: update_map_se('', '', '') else: update_map_season('', '', '') tabs.on_change('active', tab_change) # Make document doc.add_root(tabs) doc.title = 'Hurricanes' doc.theme = Theme(filename="theme.yaml")
save_button = Button(label='Save', button_type="success") toggle_2d = Toggle(label='2D Projection') def show_2d_projection(attr, old, new): if new is False: time_slider.disabled = False update_plot() else: time_slider.disabled = True image_source.data['image'] = [calculate_2d_projection()] toggle_2d.on_change('active', show_2d_projection) fov_input = TextInput(value='870', title='FOV (μm)') def update_pixel_to_micron(attr, old, new): x_pixel_to_micron_input.value = str(calc_x_pixel_to_micron()) y_pixel_to_micron_input.value = str(calc_y_pixel_to_micron()) fov_input.on_change('value', update_pixel_to_micron) zoom_factor_input = TextInput(value=config['null'], title='Zoom Factor') zoom_factor_input.disabled = True image_shape_input = TextInput(value=config['null'], title='Image Shape') image_shape_input.disabled = True
def plot(self): def update(): self.refresh_ticks += 1 self.query(self.selected_color, self.selected_year, self.selected_month) self.hot_map_update() self.trip_hour_update() self.trip_distance_update() self.trip_fare_update() self.tasks_stat_update() # self.resource_usage_update() def on_select(): BOROUGHS_CODE = {v: k for k, v in NYCBorough.BOROUGHS.items()} self.selected_color = 'green' if color.active == 1 else 'yellow' pickup.label = 'Pickups' if pickup.active else 'Dropoffs' self.selected_type = pickup.label self.selected_borough = BOROUGHS_CODE[borough.value] borough.label = borough.value self.selected_year = int(year.value) self.selected_month = int(month.value) def on_submit(): self.logger.debug('submit (%s, %s, %s, %s, %s)' % \ (self.selected_type, NYCBorough.BOROUGHS[self.selected_borough], self.selected_color, self.selected_year, self.selected_month)) self.tasks.create_tasks(self.selected_color, self.selected_year, self.selected_month) cwd = os.path.dirname(__file__) desc = Div(text=open(os.path.join(cwd, "description.html")).read(), width=1000) # Create input controls color = RadioButtonGroup(labels=['Yellow', 'Green'], active=1) color.on_change('active', lambda attr, old, new: on_select()) pickup = Toggle(label='Pickups', button_type="primary", active=True) pickup.on_change('active', lambda attr, old, new: on_select()) # BUG: Dropdown menu value cannot be integer, i.e., ('Mahattan', '1') borough_menu = [('All Boroughs', 'All Boroughs'), None, ('Manhattan', 'Manhattan'), ('Bronx', 'Bronx'), ('Brooklyn', 'Brooklyn'), ('Queens', 'Queens'), ('Staten Island', 'Staten Island')] # https://github.com/bokeh/bokeh/issues/4915 borough = Dropdown(label="Boroughs", button_type="warning", menu=borough_menu, value='All Boroughs') borough.on_change('value', lambda attr, old, new: on_select()) year = Select(title="Year:", value=str(self.selected_year), options=[ str(y) for y in range(MIN_DATE['yellow'].year, MAX_DATE['yellow'].year + 1) ]) year.on_change('value', lambda attr, old, new: on_select()) month = Select(title="Month:", value=str(self.selected_month), options=[str(m) for m in range(1, 13)]) month.on_change('value', lambda attr, old, new: on_select()) submit = Button(label="Submit", button_type="success") submit.on_click(on_submit) controls = [color, pickup, borough, year, month, submit] self.query(self.selected_color, self.selected_year, self.selected_month) self.hot_map_init() self.trip_hour_init() self.trip_distance_init() self.trip_fare_init() self.tasks_stat_init() self.resource_usage_init() rightdown_row = row([self.trip_distance, self.trip_fare]) right_column = column([self.trip_hour, rightdown_row]) inputs = widgetbox(*controls, width=140, sizing_mode="fixed") l = layout([ [desc], [inputs, self.hot_map, right_column], [self.tasks_stat, self.resource_usage], ], sizing_mode="fixed") curdoc().add_root(l) curdoc().add_periodic_callback(update, 5000) curdoc().title = "NYC Taxi Data Explorer"