def modify_doc(doc): plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) slider = Slider(start=0, end=10, value=1, title="bar", css_classes=["foo"], width=300) def cb(attr, old, new): slider.title = "baz" slider.on_change('value', cb) doc.add_root(column(slider, plot))
def modify_doc(doc): plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) slider = Slider(start=0, end=10, value=1, title="bar", css_classes=["foo"], width=300, callback_policy="mouseup") def cbv(attr, old, new): junk['v'] += 1 def cbvt(attr, old, new): junk['vt'] += 1 slider.on_change('value', cbv) slider.on_change('value_throttled', cbvt) doc.add_root(column(slider, plot))
def main(options, args): #logger = log.get_logger("ginga", options=options) logger = log.get_logger("ginga", level=20, log_file="/tmp/ginga.log") #TOOLS = "pan,wheel_zoom,box_select,tap" TOOLS = "box_select" # create a new plot with default tools, using figure fig = figure(x_range=[0, 600], y_range=[0, 600], plot_width=600, plot_height=600, tools=TOOLS) viewer = ib.CanvasView(logger) viewer.set_figure(fig) bd = viewer.get_bindings() bd.enable_all(True) ## box_select_tool = fig.select(dict(type=BoxSelectTool)) ## box_select_tool.select_every_mousemove = True #tap_tool = fig.select_one(TapTool).renderers = [cr] # open a session to keep our local document in sync with server #session = push_session(curdoc()) #curdoc().add_periodic_callback(update, 50) def load_file(path): image = load_data(path, logger=logger) viewer.set_image(image) def load_file_cb(attr_name, old_val, new_val): #print(attr_name, old_val, new_val) load_file(new_val) def zoom_ctl_cb(attr_name, old_val, new_val): if new_val >= 0: new_val += 2 viewer.zoom_to(int(new_val)) scale = viewer.get_scale() logger.info("%f" % scale) viewer.onscreen_message("%f" % (scale), delay=0.3) # add a entry widget and configure with the call back #dstdir = options.indir dstdir = "" path_w = TextInput(value=dstdir, title="File:") path_w.on_change('value', load_file_cb) slide = Slider(start=-20, end=20, step=1, value=1) slide.on_change('value', zoom_ctl_cb) layout = column(fig, path_w, slide) curdoc().add_root(layout) if len(args) > 0: load_file(args[0])
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) slider = Slider(start=0, end=10, value=1, title="bar", css_classes=["foo"], width=300) def cb(attr, old, new): source.data['val'] = [old, new] slider.on_change('value', cb) doc.add_root(column(slider, plot))
def test_js_on_change_executes(self, bokeh_model_page): slider = Slider(start=0, end=10, value=1, title="bar", css_classes=["foo"], width=300) slider.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = bokeh_model_page(slider) drag_slider(page.driver, ".foo", 150) results = page.results assert float(results['value']) > 1 assert page.has_no_console_errors()
def modify_doc(doc): x = np.linspace(0, 10, 1000) y = np.log(x) * np.sin(x) source = ColumnDataSource(data=dict(x=x, y=y)) plot = figure(title="Simple plot with slider") plot.line('x', 'y', source=source) slider = Slider(start=1, end=10, value=1, step=0.1) def callback(attr, old, new): y = np.log(x) * np.sin(x*new) source.data = dict(x=x, y=y) slider.on_change('value', callback) doc.add_root(row(widgetbox(slider), plot))
def modify_doc(doc): df = sea_surface_temperature.copy() source = ColumnDataSource(data=df) plot = figure(x_axis_type='datetime', y_range=(0, 25), y_axis_label='Temperature (Celsius)', title="Sea Surface Temperature at 43.18, -70.43") plot.line('time', 'temperature', source=source) def callback(attr, old, new): if new == 0: data = df else: data = df.rolling('{0}D'.format(new)).mean() source.data = ColumnDataSource(data=data).data slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days") slider.on_change('value', callback) doc.add_root(column(slider, plot)) doc.theme = Theme(filename="theme.yaml")
def modify_doc(doc): data_url = "http://www.neracoos.org/erddap/tabledap/B01_sbe37_all.csvp?time,temperature&depth=1&temperature_qc=0&time>=2016-02-15&time<=2017-03-22" df = pd.read_csv(data_url, parse_dates=True, index_col=0) df = df.rename(columns={'temperature (celsius)': 'temperature'}) df.index.name = 'time' source = ColumnDataSource(data=df) plot = figure(x_axis_type='datetime', y_range=(0, 25), y_axis_label='Temperature (Celsius)', title="Sea Surface Temperature at 43.18, -70.43") plot.line('time', 'temperature', source=source) def callback(attr, old, new): if new == 0: data = df else: data = df.rolling('{0}D'.format(new)).mean() source.data = ColumnDataSource(data=data).data slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days") slider.on_change('value', callback) doc.add_root(column(slider, plot)) doc.theme = Theme(json=yaml.load(""" attrs: Figure: background_fill_color: "#DDDDDD" outline_line_color: white toolbar_location: above height: 500 width: 800 Grid: grid_line_dash: [6, 4] grid_line_color: white """))
# create a data source to enable refreshing of fill & text color source = ColumnDataSource(data=dict(color=[hex_color], text_color=[text_color])) # create first plot, as a rect() glyph and centered text label, with fill and text color taken from source p1 = figure(x_range=(-8, 8), y_range=(-4, 4), plot_width=600, plot_height=300, title='move sliders to change', tools='') p1.rect(0, 0, width=18, height=10, fill_color='color', line_color = 'black', source=source) p1.text(0, 0, text='color', text_color='text_color', alpha=0.6667, text_font_size='36pt', text_baseline='middle', text_align='center', source=source) red_slider = Slider(title="R", start=0, end=255, value=255, step=1) green_slider = Slider(title="G", start=0, end=255, value=255, step=1) blue_slider = Slider(title="B", start=0, end=255, value=255, step=1) # the callback function to update the color of the block and associated label text # NOTE: the JS functions for converting RGB to hex are taken from the excellent answer # by Tim Down at http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb callback = CustomJS(args=dict(source=source, red=red_slider, blue=blue_slider, green=green_slider), code=""" function componentToHex(c) { var hex = c.toString(16) return hex.length == 1 ? "0" + hex : hex } function rgbToHex(r, g, b) { return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b) } function toInt(v) {
y[i] = Math.pow(x[i], f) } source.change.emit(); """) callback_ion = CustomJS(args=dict(source=source), code=""" var data = source.data; var f = cb_obj.range var x = data['x'] var y = data['y'] var pow = (Math.log(y[100])/Math.log(x[100])) console.log(pow) var delta = (f[1] - f[0])/x.length for (var i = 0; i < x.length; i++) { x[i] = delta*i + f[0] y[i] = Math.pow(x[i], pow) } source.change.emit(); """) slider = Slider(start=0, end=5, step=0.1, value=1, title="Bokeh Slider - Power") slider.js_on_change('value', callback_single) ion_range_slider = IonRangeSlider(start=0.01, end=0.99, step=0.01, range=(min(x), max(x)), title='Ion Range Slider - Range', callback_policy='continuous', callback=callback_ion) layout = column(plot, slider, ion_range_slider) show(layout)
def geoplot(gdf_in, figure=None, figsize=None, title="", xlabel="Longitude", ylabel="Latitude", xlim=None, ylim=None, color="blue", colormap=None, colormap_uselog=False, colormap_range=None, category=None, dropdown=None, slider=None, slider_range=None, slider_name="", show_colorbar=True, xrange=None, yrange=None, hovertool=True, hovertool_columns=[], hovertool_string=None, simplify_shapes=None, tile_provider="CARTODBPOSITRON_RETINA", tile_provider_url=None, tile_attribution="", tile_alpha=1, panning=True, zooming=True, toolbar_location="right", show_figure=True, return_figure=True, return_html=False, legend=True, webgl=True, **kwargs): """Doc-String: TODO""" # Imports: import bokeh.plotting from bokeh.plotting import show from bokeh.models import ( HoverTool, LogColorMapper, LinearColorMapper, GeoJSONDataSource, WheelZoomTool, ColorBar, BasicTicker, LogTicker, Dropdown, Slider, ColumnDataSource, ) from bokeh.models.callbacks import CustomJS from bokeh.models.widgets import Dropdown from bokeh.palettes import all_palettes from bokeh.layouts import row, column # Make a copy of the input geodataframe: gdf = gdf_in.copy() # Check layertypes: if type(gdf) != pd.DataFrame: layertypes = [] if "Point" in str(gdf.geom_type.unique()): layertypes.append("Point") if "Line" in str(gdf.geom_type.unique()): layertypes.append("Line") if "Polygon" in str(gdf.geom_type.unique()): layertypes.append("Polygon") if len(layertypes) > 1: raise Exception( "Can only plot GeoDataFrames/Series with single type of geometry (either Point, Line or Polygon). Provided is a GeoDataFrame/Series with types: %s" % layertypes) else: layertypes = ["Point"] # Get and check provided parameters for geoplot: figure_options = { "title": title, "x_axis_label": xlabel, "y_axis_label": ylabel, "plot_width": 600, "plot_height": 400, "toolbar_location": toolbar_location, "active_scroll": "wheel_zoom", "x_axis_type": "mercator", "y_axis_type": "mercator", } if not figsize is None: width, height = figsize figure_options["plot_width"] = width figure_options["plot_height"] = height if webgl: figure_options["output_backend"] = "webgl" if type(gdf) != pd.DataFrame: # Convert GeoDataFrame to Web Mercator Projection: gdf.to_crs({"init": "epsg:3857"}, inplace=True) # Simplify shapes if wanted: if isinstance(simplify_shapes, numbers.Number): if layertypes[0] in ["Line", "Polygon"]: gdf["geometry"] = gdf["geometry"].simplify(simplify_shapes) elif not simplify_shapes is None: raise ValueError( "<simplify_shapes> parameter only accepts numbers or None.") # Check for category, dropdown or slider (choropleth map column): category_options = 0 if not category is None: category_options += 1 category_columns = [category] if not dropdown is None: category_options += 1 category_columns = dropdown if not slider is None: category_options += 1 category_columns = slider if category_options > 1: raise ValueError( "Only one of <category>, <dropdown> or <slider> parameters is allowed to be used at once." ) # Check for category (single choropleth plot): if category is None: pass elif isinstance(category, (list, tuple)): raise ValueError( "For <category>, please provide an existing single column of the GeoDataFrame." ) elif category in gdf.columns: pass else: raise ValueError( "Could not find column '%s' in GeoDataFrame. For <category>, please provide an existing single column of the GeoDataFrame." % category) # Check for dropdown (multiple choropleth plots via dropdown selection): if dropdown is None: pass elif not isinstance(dropdown, (list, tuple)): raise ValueError( "For <dropdown>, please provide a list/tuple of existing columns of the GeoDataFrame." ) else: for col in dropdown: if col not in gdf.columns: raise ValueError( "Could not find column '%s' for <dropdown> in GeoDataFrame. " % col) # Check for slider (multiple choropleth plots via slider selection): if slider is None: pass elif not isinstance(slider, (list, tuple)): raise ValueError( "For <slider>, please provide a list/tuple of existing columns of the GeoDataFrame." ) else: for col in slider: if col not in gdf.columns: raise ValueError( "Could not find column '%s' for <slider> in GeoDataFrame. " % col) if not slider_range is None: if not isinstance(slider_range, Iterable): raise ValueError( "<slider_range> has to be a type that is iterable like list, tuple, range, ..." ) else: slider_range = list(slider_range) if len(slider_range) != len(slider): raise ValueError( "The number of elements in <slider_range> has to be the same as in <slider>." ) steps = [] for i in range(len(slider_range) - 1): steps.append(slider_range[i + 1] - slider_range[i]) if len(set(steps)) > 1: raise ValueError( "<slider_range> has to have equal step size between each elements (like a range-object)." ) else: slider_step = steps[0] slider_start = slider_range[0] slider_end = slider_range[-1] # Check colormap if either <category>, <dropdown> or <slider> is choosen: if category_options == 1: if colormap is None: colormap = blue_colormap elif isinstance(colormap, (tuple, list)): if len(colormap) > 1: pass else: raise ValueError( "<colormap> only accepts a list/tuple of at least two colors or the name of one of the following predefined colormaps (see also https://bokeh.pydata.org/en/latest/docs/reference/palettes.html ): %s" % (list(all_palettes.keys()))) elif isinstance(colormap, str): if colormap in all_palettes: colormap = all_palettes[colormap] colormap = colormap[max(colormap.keys())] else: raise ValueError( "Could not find <colormap> with name %s. The following predefined colormaps are supported (see also https://bokeh.pydata.org/en/latest/docs/reference/palettes.html ): %s" % (colormap, list(all_palettes.keys()))) else: raise ValueError( "<colormap> only accepts a list/tuple of at least two colors or the name of one of the following predefined colormaps (see also https://bokeh.pydata.org/en/latest/docs/reference/palettes.html ): %s" % (list(all_palettes.keys()))) else: if isinstance(color, str): colormap = [color] else: raise ValueError( "<color> has to be a string specifying the fill_color of the map glyph." ) # Check xlim & ylim: if xlim is not None: if isinstance(xlim, (tuple, list)): if len(xlim) == 2: from pyproj import Proj, transform inProj = Proj(init="epsg:4326") outProj = Proj(init="epsg:3857") xmin, xmax = xlim for _ in [xmin, xmax]: if not -180 < _ <= 180: raise ValueError( "Limits for x-axis (=Longitude) have to be between -180 and 180." ) if not xmin < xmax: raise ValueError("xmin has to be smaller than xmax.") xmin = transform(inProj, outProj, xmin, 0)[0] xmax = transform(inProj, outProj, xmax, 0)[0] figure_options["x_range"] = (xmin, xmax) else: raise ValueError( "Limits for x-axis (=Longitude) have to be of form [xmin, xmax] with values between -180 and 180." ) else: raise ValueError( "Limits for x-axis (=Longitude) have to be of form [xmin, xmax] with values between -180 and 180." ) if ylim is not None: if isinstance(ylim, (tuple, list)): if len(ylim) == 2: from pyproj import Proj, transform inProj = Proj(init="epsg:4326") outProj = Proj(init="epsg:3857") ymin, ymax = ylim for _ in [ymin, ymax]: if not -90 < _ <= 90: raise ValueError( "Limits for y-axis (=Latitude) have to be between -90 and 90." ) if not ymin < ymax: raise ValueError("ymin has to be smaller than ymax.") ymin = transform(inProj, outProj, 0, ymin)[1] ymax = transform(inProj, outProj, 0, ymax)[1] figure_options["y_range"] = (ymin, ymax) else: raise ValueError( "Limits for y-axis (=Latitude) have to be of form [ymin, ymax] with values between -90 and 90." ) else: raise ValueError( "Limits for y-axis (=Latitude) have to be of form [ymin, ymax] with values between -90 and 90." ) # Create Figure to draw: old_layout = None if figure is None: p = bokeh.plotting.figure(**figure_options) # Add Tile Source as Background: p = _add_backgroundtile(p, tile_provider, tile_provider_url, tile_attribution, tile_alpha) elif isinstance(figure, type(bokeh.plotting.figure())): p = figure elif isinstance(figure, type(column())): old_layout = figure p = _get_figure(old_layout) else: raise ValueError( "Parameter <figure> has to be of type bokeh.plotting.figure or bokeh.layouts.column." ) # Get ridd of zoom on axes: for t in p.tools: if type(t) == WheelZoomTool: t.zoom_on_axis = False # Hide legend if wanted: legend_input = legend if isinstance(legend, str): pass else: legend = "GeoLayer" # Define colormapper: if len(colormap) == 1: kwargs["fill_color"] = colormap[0] elif not category is None: # Check if category column is numerical: if not issubclass(gdf[category].dtype.type, np.number): raise NotImplementedError( "<category> plot only yet implemented for numerical columns. Column '%s' is not numerical." % category) field = category colormapper_options = {"palette": colormap} if not colormap_range is None: if not isinstance(colormap_range, (tuple, list)): raise ValueError( "<colormap_range> can only be 'None' or a tuple/list of form (min, max)." ) elif len(colormap_range) == 2: colormapper_options["low"] = colormap_range[0] colormapper_options["high"] = colormap_range[1] else: colormapper_options["low"] = gdf[field].min() colormapper_options["high"] = gdf[field].max() if colormap_uselog: colormapper = LogColorMapper(**colormapper_options) else: colormapper = LinearColorMapper(**colormapper_options) kwargs["fill_color"] = {"field": "Colormap", "transform": colormapper} if not isinstance(legend, str): legend = str(field) elif not dropdown is None: # Check if all columns in dropdown selection are numerical: for col in dropdown: if not issubclass(gdf[col].dtype.type, np.number): raise NotImplementedError( "<dropdown> plot only yet implemented for numerical columns. Column '%s' is not numerical." % col) field = dropdown[0] colormapper_options = {"palette": colormap} if not colormap_range is None: if not isinstance(colormap_range, (tuple, list)): raise ValueError( "<colormap_range> can only be 'None' or a tuple/list of form (min, max)." ) elif len(colormap_range) == 2: colormapper_options["low"] = colormap_range[0] colormapper_options["high"] = colormap_range[1] else: colormapper_options["low"] = gdf[dropdown].min().min() colormapper_options["high"] = gdf[dropdown].max().max() if colormap_uselog: colormapper = LogColorMapper(**colormapper_options) else: colormapper = LinearColorMapper(**colormapper_options) kwargs["fill_color"] = {"field": "Colormap", "transform": colormapper} legend = " " + field elif not slider is None: # Check if all columns in dropdown selection are numerical: for col in slider: if not issubclass(gdf[col].dtype.type, np.number): raise NotImplementedError( "<slider> plot only yet implemented for numerical columns. Column '%s' is not numerical." % col) field = slider[0] colormapper_options = {"palette": colormap} if not colormap_range is None: if not isinstance(colormap_range, (tuple, list)): raise ValueError( "<colormap_range> can only be 'None' or a tuple/list of form (min, max)." ) elif len(colormap_range) == 2: colormapper_options["low"] = colormap_range[0] colormapper_options["high"] = colormap_range[1] else: colormapper_options["low"] = gdf[slider].min().min() colormapper_options["high"] = gdf[slider].max().max() if colormap_uselog: colormapper = LogColorMapper(**colormapper_options) else: colormapper = LinearColorMapper(**colormapper_options) kwargs["fill_color"] = {"field": "Colormap", "transform": colormapper} if not isinstance(legend, str): legend = "Geolayer" # Check that only hovertool_columns or hovertool_string is used: if isinstance(hovertool_columns, (list, tuple, str)): if len(hovertool_columns) > 0 and hovertool_string is not None: raise ValueError( "Either <hovertool_columns> or <hovertool_string> can be used, but not both at the same time." ) else: raise ValueError( "<hovertool_columns> has to be a list of columns of the GeoDataFrame or the string 'all'." ) if hovertool_string is not None: hovertool_columns = "all" # Check for Hovertool columns: if hovertool: if not isinstance(hovertool_columns, (list, tuple)): if hovertool_columns == "all": hovertool_columns = list( filter(lambda col: col != "geometry", gdf.columns)) else: raise ValueError( "<hovertool_columns> has to be a list of columns of the GeoDataFrame or the string 'all'." ) elif len(hovertool_columns) == 0: if not category is None: hovertool_columns = [category] elif not dropdown is None: hovertool_columns = dropdown elif not slider is None: hovertool_columns = slider else: hovertool_columns = [] else: for col in hovertool_columns: if col not in gdf.columns: raise ValueError( "Could not find columns '%s' in GeoDataFrame. <hovertool_columns> has to be a list of columns of the GeoDataFrame or the string 'all'." % col) else: if category is None: hovertool_columns = [] else: hovertool_columns = [category] # Reduce DataFrame to needed columns: if type(gdf) == pd.DataFrame: gdf["Geometry"] = 0 additional_columns = ["x", "y"] else: additional_columns = ["geometry"] for kwarg, value in kwargs.items(): if isinstance(value, Hashable): if value in gdf.columns: additional_columns.append(value) if category_options == 0: gdf = gdf[list(set(hovertool_columns) | set(additional_columns))] else: gdf = gdf[list( set(hovertool_columns) | set(category_columns) | set(additional_columns))] gdf["Colormap"] = gdf[field] field = "Colormap" # Create GeoJSON DataSource for Plot: if type(gdf) != pd.DataFrame: geo_source = GeoJSONDataSource(geojson=gdf.to_json()) else: geo_source = gdf # Draw Glyph on Figure: layout = None if "Point" in layertypes: if "line_color" not in kwargs: kwargs["line_color"] = kwargs["fill_color"] glyph = p.scatter(x="x", y="y", source=geo_source, legend=legend, **kwargs) if "Line" in layertypes: if "line_color" not in kwargs: kwargs["line_color"] = kwargs["fill_color"] del kwargs["fill_color"] glyph = p.multi_line(xs="xs", ys="ys", source=geo_source, legend=legend, **kwargs) if "Polygon" in layertypes: if "line_color" not in kwargs: kwargs["line_color"] = "black" # Creates from a geoDataFrame with Polygons and Multipolygons a Pandas DataFrame # with x any y columns specifying the geometry of the Polygons: geo_source = ColumnDataSource(convert_geoDataFrame_to_patches(gdf)) # Plot polygons: glyph = p.patches(xs="__x__", ys="__y__", source=geo_source, legend=legend, **kwargs) # Add hovertool: if hovertool and (category_options == 1 or len(hovertool_columns) > 0): my_hover = HoverTool(renderers=[glyph]) if hovertool_string is None: my_hover.tooltips = [(str(col), "@{%s}" % col) for col in hovertool_columns] else: my_hover.tooltips = hovertool_string p.add_tools(my_hover) # Add colorbar: if show_colorbar and category_options == 1: colorbar_options = { "color_mapper": colormapper, "label_standoff": 12, "border_line_color": None, "location": (0, 0), } if colormap_uselog: colorbar_options["ticker"] = LogTicker() colorbar = ColorBar(**colorbar_options) p.add_layout(colorbar, "right") # Add Dropdown Widget: if not dropdown is None: # Define Dropdown widget: dropdown_widget = Dropdown(label="Select Choropleth Layer", menu=list(zip(dropdown, dropdown))) # Define Callback for Dropdown widget: callback = CustomJS( args=dict( dropdown_widget=dropdown_widget, geo_source=geo_source, legend=p.legend[0].items[0], ), code=""" //Change selection of field for Colormapper for choropleth plot: geo_source.data["Colormap"] = geo_source.data[dropdown_widget.value]; geo_source.change.emit(); //Change label of Legend: legend.label["value"] = " " + dropdown_widget.value; """, ) dropdown_widget.js_on_change("value", callback) # Add Dropdown widget above the plot: if old_layout is None: layout = column(dropdown_widget, p) else: layout = column(dropdown_widget, old_layout) # Add Slider Widget: if not slider is None: if slider_range is None: slider_start = 0 slider_end = len(slider) - 1 slider_step = 1 value2name = ColumnDataSource({ "Values": np.arange(slider_start, slider_end + slider_step, slider_step), "Names": slider, }) # Define Slider widget: slider_widget = Slider( start=slider_start, end=slider_end, value=slider_start, step=slider_step, title=slider_name, ) # Define Callback for Slider widget: callback = CustomJS( args=dict( slider_widget=slider_widget, geo_source=geo_source, value2name=value2name, ), code=""" //Change selection of field for Colormapper for choropleth plot: var slider_value = slider_widget.value; for(i=0; i<value2name.data["Names"].length; i++) { if (value2name.data["Values"][i] == slider_value) { var name = value2name.data["Names"][i]; } } geo_source.data["Colormap"] = geo_source.data[name]; geo_source.change.emit(); """, ) slider_widget.js_on_change("value", callback) # Add Slider widget above the plot: if old_layout is None: layout = column(slider_widget, p) else: layout = column(slider_widget, old_layout) # Hide legend if user wants: if legend_input is False: p.legend.visible = False # Set click policy for legend: p.legend.click_policy = "hide" # Set panning option: if panning is False: p.toolbar.active_drag = None # Set zooming option: if zooming is False: p.toolbar.active_scroll = None # Display plot and if wanted return plot: if layout is None: if old_layout is None: layout = p else: layout = old_layout # Display plot if wanted if show_figure: show(layout) # Return as (embeddable) HTML if wanted: if return_html: return embedded_html(layout) # Return plot: if return_figure: return layout
def colorbar_slider(fig): ''' Adds interactive sliders and text input boxes for the colorbar. Returns a layout object to be put into a gridplot ''' cb = get_colorbar_renderer(fig) data = get_image_data(fig) data = reject_outliers_quick(data) datamin = nanmin(data) datamax = nanmax(data) im = get_glyph_renderer(fig) # Get image renderer from bokeh.models import CustomJS, Slider, TextInput from bokeh.models.widgets import Button from bokeh.layouts import widgetbox model = Slider() # trick it into letting datamin and datamax into CustomJS model.tags.append(datamin) # Hide these in here model.tags.append(datamax) callback_u = CustomJS(args=dict(cb=cb, im=im, model=model), code=""" var cm = cb.color_mapper; var upp = upper_slider.get('value'); upper_input.value = upp.toString() lower_slider.end = upp cm.high = upp; im.glyph.color_mapper.high = upp; if (cm.low >= cm.high){ cm.low = upp/1.1 // to prevent limits being the same im.glyph.color_mapper.low = low/1.1; } if (upp > model.tags[1]){ upper_slider.end = upp } """) callback_l = CustomJS(args=dict(cb=cb, im=im, model=model), code=""" var cm = cb.color_mapper; var low = lower_slider.get('value'); lower_input.value = low.toString() upper_slider.start = low cm.low = low; im.glyph.color_mapper.low = low; if (cm.high <= cm.low){ cm.high = low*1.1 // to prevent limits being the same im.glyph.color_mapper.high = low*1.1; } if (low < model.tags[0]){ lower_slider.start = low }""") callback_ut = CustomJS(args=dict(cb=cb, im=im, model=model), code=""" var cm = cb.color_mapper; var upp = parseFloat(upper_input.get('value')); upper_slider.value = upp cm.high = upp; im.glyph.color_mapper.high = upp; if (cm.low >= cm.high){ cm.low = upp/1.1 // to prevent limits being the same im.glyph.color_mapper.low = upp/1.1; } if (upp > model.tags[1]){ upper_slider.end = upp } """) callback_lt = CustomJS(args=dict(cb=cb, im=im, model=model), code=""" var cm = cb.color_mapper; var low = parseFloat(lower_input.get('value')); lower_slider.value = low cm.low = low; im.glyph.color_mapper.low = low; if (cm.high <= cm.low){ cm.high = low*1.1 // to prevent limits being the same im.glyph.color_mapper.high = low*1.1; } if (low < model.tags[0]){ lower_slider.start = low } """) callback_reset_js = CustomJS(args=dict(cb=cb, im=im, model=model), code=""" var cm = cb.color_mapper; var low = model.tags[0]; var high = model.tags[1]; low = parseFloat(low.toPrecision(3)) // 3 sig figs high = parseFloat(high.toPrecision(3)) // 3 sig figs lower_slider.value = low; lower_slider.set('step', (high-low)/50); cm.low = low; upper_slider.value = high; upper_slider.set('step', (high-low)/50); cm.high = high; im.glyph.color_mapper.low = low; im.glyph.color_mapper.high = high; lower_input.value = low.toString(); upper_input.value = high.toString(); lower_slider.start = low; lower_slider.end = high; upper_slider.start = low; upper_slider.end = high; model.trigger('change') cb_obj.trigger('change)') """) reset_button = Button(label='Reset', callback = callback_reset_js) def callback_reset(*args, **kwargs): from IPython.display import Javascript, display # display(callback_reset_js) # callback_reset_js.name = None # callback_reset_js.name = 'test' # display('Plot updated, press reset to rescale!') # cb.color_mapper.low = datamin # cb.color_mapper.high = datamax # im.glyph.color_mapper.low = datamin # im.glyph.color_mapper.high = datamax # lower_slider.start = datamin # lower_slider.end = datamax # lower_slider.value = datamin # upper_slider.start = datamin # upper_slider.end = datamax # lower_slider.value = datamax # lower_input.value = str(datamin) # upper_input.value = str(datamax) # update() # fig.text(x=0,y=0,text='Plot updated, press reset to rescale!') # reset_button.label='Reset: Data changed! Press me!' # reset_button.trigger('clicks',0,1) reset_button.on_click(callback_reset) # def callback_die(attr, old, new): # from IPython.display import display # display('yoooo') # display(old) # display(new) # raise Exception() # exception_button = Button(label='KILL ME') # exception_button.on_click(callback_die) lower_slider = Slider(start=datamin, end=datamax, value=datamin, step=(datamax-datamin)/50, # smallest step is 1e-5 title="Lower lim", callback=callback_l) lower_slider.width=100 upper_slider = Slider(start=datamin, end=datamax, value=datamax, step=(datamax-datamin)/50, title="Upper lim", callback=callback_u) upper_slider.width=100 lower_input = TextInput(callback=callback_lt, value = str(datamin), width=50) upper_input = TextInput(callback=callback_ut, value = str(datamax), width=50) # add all of these widgets as arguments to the callback functions for callback in ['l', 'u', 'lt', 'ut', 'reset_js']: for widget in ['lower_slider', 'upper_slider','lower_input','upper_input', 'reset_button']: exec('callback_%s.args["%s"] = %s' %(callback, widget, widget)) wb = widgetbox([upper_slider, upper_input, lower_slider, lower_input, reset_button], width=100, sizing_mode = 'stretch_both') return wb
'Noisy Moons', 'Blobs', 'No Structure' ] algorithm_select = Select(value='MiniBatchKMeans', title='Select algorithm:', options=clustering_algorithms) dataset_select = Select(value='Noisy Circles', title='Select dataset:', options=datasets_names) samples_slider = Slider(title="Number of samples", value=1500.0, start=1000.0, end=3000.0, step=100) clusters_slider = Slider(title="Number of clusters", value=2.0, start=2.0, end=10.0, step=1) # set up callbacks def update_algorithm_or_clusters(attrname, old, new): global X algorithm = algorithm_select.value n_clusters = int(clusters_slider.value)
def create_layout(self): # create figure self.x_range = Range1d(start=self.model.map_extent[0], end=self.model.map_extent[2], bounds=None) self.y_range = Range1d(start=self.model.map_extent[1], end=self.model.map_extent[3], bounds=None) self.fig = Figure(tools='wheel_zoom,pan', x_range=self.x_range, lod_threshold=None, plot_width=self.model.plot_width, plot_height=self.model.plot_height, y_range=self.y_range) self.fig.min_border_top = 0 self.fig.min_border_bottom = 10 self.fig.min_border_left = 0 self.fig.min_border_right = 0 self.fig.axis.visible = False self.fig.xgrid.grid_line_color = None self.fig.ygrid.grid_line_color = None # add tiled basemap self.tile_source = WMTSTileSource(url=self.model.basemap) self.tile_renderer = TileRenderer(tile_source=self.tile_source) self.fig.renderers.append(self.tile_renderer) # add datashader layer self.image_source = ImageSource(url=self.model.service_url, extra_url_vars=self.model.shader_url_vars) self.image_renderer = DynamicImageRenderer(image_source=self.image_source) self.fig.renderers.append(self.image_renderer) # add label layer self.label_source = WMTSTileSource(url=self.model.labels_url) self.label_renderer = TileRenderer(tile_source=self.label_source) self.fig.renderers.append(self.label_renderer) # Add a hover tool hover_layer = HoverLayer() hover_layer.field_name = self.model.field_title hover_layer.is_categorical = self.model.field in self.model.categorical_fields self.fig.renderers.append(hover_layer.renderer) self.fig.add_tools(hover_layer.tool) self.model.hover_layer = hover_layer self.model.legend_side_vbox = VBox() self.model.legend_bottom_vbox = VBox() # add ui components controls = [] axes_select = Select.create(name='Axes', options=self.model.axes) axes_select.on_change('value', self.on_axes_change) controls.append(axes_select) self.field_select = Select.create(name='Field', options=self.model.fields) self.field_select.on_change('value', self.on_field_change) controls.append(self.field_select) self.aggregate_select = Select.create(name='Aggregate', options=self.model.aggregate_functions) self.aggregate_select.on_change('value', self.on_aggregate_change) controls.append(self.aggregate_select) transfer_select = Select.create(name='Transfer Function', options=self.model.transfer_functions) transfer_select.on_change('value', self.on_transfer_function_change) controls.append(transfer_select) color_ramp_select = Select.create(name='Color Ramp', options=self.model.color_ramps) color_ramp_select.on_change('value', self.on_color_ramp_change) controls.append(color_ramp_select) spread_size_slider = Slider(title="Spread Size (px)", value=0, start=0, end=10, step=1) spread_size_slider.on_change('value', self.on_spread_size_change) controls.append(spread_size_slider) hover_size_slider = Slider(title="Hover Size (px)", value=8, start=4, end=30, step=1) hover_size_slider.on_change('value', self.on_hover_size_change) controls.append(hover_size_slider) controls.append(self.model.legend_side_vbox) # add map components basemap_select = Select.create(name='Basemap', value='Imagery', options=self.model.basemaps) basemap_select.on_change('value', self.on_basemap_change) image_opacity_slider = Slider(title="Opacity", value=100, start=0, end=100, step=1) image_opacity_slider.on_change('value', self.on_image_opacity_slider_change) basemap_opacity_slider = Slider(title="Basemap Opacity", value=100, start=0, end=100, step=1) basemap_opacity_slider.on_change('value', self.on_basemap_opacity_slider_change) show_labels_chk = CheckboxGroup(labels=["Show Labels"], active=[0]) show_labels_chk.on_click(self.on_labels_change) map_controls = [basemap_select, basemap_opacity_slider, image_opacity_slider, show_labels_chk] self.controls = VBox(width=200, height=600, children=controls) self.map_controls = HBox(width=self.fig.plot_width, children=map_controls) self.map_area = VBox(width=self.fig.plot_width, children=[self.map_controls, self.fig, self.model.legend_bottom_vbox]) self.layout = HBox(width=1366, children=[self.controls, self.map_area])
select_rt.on_change('value', on_rt_change) ############## ############## # set max distance from gdelt to osm node #select_dist = Select(title="Max Node Distance (km):", # value=str(max_node_dist_km), # options=['0','1','2','3','4','5','6','7','8','9','10']) # #def on_dist_change(obj, attr, old, new): # print "Max Node Dist (km)", new # global max_node_dist_km # max_node_dist_km = int(new) # #select_dist.on_change('value', on_dist_change) select_dist = Slider(title="Max GDELT Distance to Road (km)", start=1, end=10, value=5, step=1) def on_dist_change(obj, attr, old, new): print "Max Node Dist (km)", new global max_node_dist_km max_node_dist_km = int(new) select_dist.on_change('value', on_dist_change) ############## ############## # set max aug distance #select_dist.on_change('value', on_dist_change) slider_rkm = Slider(title="Control Inference Distance (km)", start=0, end=10, value=r_km, step=0.5)
line_color='grey') p.line('x', 'y2', source=source_top_flange, line_width=3, line_alpha=0.6, line_color='grey') p.add_tools(HoverTool(tooltips=[("(gamma,delta_min)", "($x, $y)")])) p.add_tools(HoverTool(tooltips=[("(gamma,delta_max)", "($x, $y)")])) p.toolbar.active_scroll = p.select_one(WheelZoomTool) p.xaxis.axis_label = 'gamma, deg' p.yaxis.axis_label = 'delta, deg' p.background_fill_color = 'beige' p.background_fill_alpha = 0.2 slider = Slider(start=0., end=360., step=15., value=0., title='Position of Be window (0° downstream along beam)') slider.on_change('value', update_plot) imgs = row(p, g) layout = column(imgs, slider) #plt.show(layout, notebook_handle=True) #plt.show(p) p.x_range = Range1d(0, 180) p.y_range = Range1d(0, 180) curdoc().title = "Hello, world!" curdoc().add_root(layout)
from bokeh.io import curdoc from bokeh.layouts import column from bokeh.models import ColumnDataSource, Slider from bokeh.plotting import figure from bokeh.sampledata.sea_surface_temperature import sea_surface_temperature df = sea_surface_temperature.copy() source = ColumnDataSource(data=df) plot = figure(x_axis_type="datetime", y_range=(0, 25), y_axis_label="Temperature (Celsius)", title="Sea Surface Temperature at 43.18, -70.43") plot.line("time", "temperature", source=source) def callback(attr, old, new): if new == 0: data = df else: data = df.rolling("{0}D".format(new)).mean() source.data = ColumnDataSource(data=data).data slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days") slider.on_change("value", callback) doc = curdoc() doc.add_root(column(slider, plot))
callback = CustomJS(args=dict(source=source), code=""" var B = box.value var data = source.data; var A = amp.value; var k = freq.value; var phi = phase.value; var B = offset.value; var x = data['x'] var y = data['y'] for (var i = 0; i < x.length; i++) { y[i] = B + A*Math.sin(k*x[i]+phi); } source.change.emit(); """) amp_slider = Slider(start=0.1, end=10, value=1, step=.1, title="Amplitude", callback=callback) callback.args["amp"] = amp_slider freq_slider = Slider(start=0.1, end=10, value=1, step=.1, title="Frequency", callback=callback) callback.args["freq"] = freq_slider phase_slider = Slider(start=0, end=6.4, value=0, step=.1, title="Phase", callback=callback) callback.args["phase"] = phase_slider offset_slider = Slider(start=-5, end=5, value=0, step=.1, title="Offset", callback=callback) callback.args["offset"] = offset_slider checkbox_group = CheckboxGroup(
plot_width=450, plot_height=250) n.line('g', 'z', source=s2) s1.callback = CustomJS(args=dict(s2=s2), code=""" var d2 = s2.data; s2.data['z']=d2[cb_obj.selected['1d'].indices] console.log(d2['z']) s2.trigger('change'); console.log('Tap event occured at x-position: ' + cb_obj.selected['1d'].indices) """) #Creating a slider slider = Slider(start=0, end=14400, value=0, step=1, title="Time slider in seconds") def update(s1=s1, slider=slider, window=None): data = s1.data v = cb_obj.value data['rate'] = data[v] s1.trigger('change') slider.js_on_change('value', CustomJS.from_py_func(update)) g1 = (column( p, widgetbox(slider),
def animate_update(): year = slider.value + 1 if year > years[-1]: year = years[0] slider.value = year def slider_update(attrname, old, new): year = slider.value label.text = str(year) source.data = data[year] slider = Slider(start=years[0], end=years[-1], value=years[0], step=1, title="Year") slider.on_change('value', slider_update) callback_id = None def animate(): global callback_id if button.label == '► Play': button.label = '❚❚ Pause' callback_id = curdoc().add_periodic_callback(animate_update, 200) else: button.label = '► Play' curdoc().remove_periodic_callback(callback_id)
datasets_names = ['Noisy Circles', 'Noisy Moons', 'Blobs', 'No Structure'] algorithm_select = Select(value='MiniBatchKMeans', title='Select algorithm:', width=200, options=clustering_algorithms) dataset_select = Select(value='Noisy Circles', title='Select dataset:', width=200, options=datasets_names) samples_slider = Slider(title="Number of samples", value=1500.0, start=1000.0, end=3000.0, step=100, width=400) clusters_slider = Slider(title="Number of clusters", value=2.0, start=2.0, end=10.0, step=1, width=400) # set up callbacks def update_algorithm_or_clusters(attrname, old, new): global X
import pandas as pd import numpy as np from bokeh.io import curdoc from bokeh.plotting import Figure, output_file, show from bokeh.models import ColumnDataSource, Slider from bokeh.layouts import column COUNT = 10 df = pd.DataFrame({"x": np.random.rand(COUNT), "y": np.random.rand(COUNT), "radius": 0.05}) source = ColumnDataSource(df) fig = Figure() fig.circle(source=source, x="x", y="y", fill_color="red", line_color="black", radius="radius") slider = Slider(start=1, end=10, step=0.1, value=5) def update_size(attrname, old, new): source.data["radius"] = [slider.value / 100.0] * COUNT slider.on_change("value", update_size) curdoc().add_root(column(fig, slider))
import numpy as np from bokeh.layouts import row, column from bokeh.models import CustomJS, Slider from bokeh.plotting import figure, output_file, show, ColumnDataSource x = np.linspace(0, 10, 500) y = np.sin(x) source = ColumnDataSource(data=dict(x=x, y=y)) plot = figure(y_range=(-10, 10), plot_width=400, plot_height=400) plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6) amp_slider = Slider(start=0.1, end=10, value=1, step=.1, title="Amplitude") freq_slider = Slider(start=0.1, end=10, value=1, step=.1, title="Frequency") phase_slider = Slider(start=0, end=6.4, value=0, step=.1, title="Phase") offset_slider = Slider(start=-5, end=5, value=0, step=.1, title="Offset") callback = CustomJS(args=dict(source=source, amp=amp_slider, freq=freq_slider, phase=phase_slider, offset=offset_slider), code=""" const data = source.data; const A = amp.value; const k = freq.value; const phi = phase.value; const B = offset.value; const x = data['x'] const y = data['y'] for (var i = 0; i < x.length; i++) { y[i] = B + A*Math.sin(k*x[i]+phi);
from bokeh.plotting import figure import numpy as np doc = curdoc() x = np.linspace(0, 2, 1000) y = 1 - (x - 1)**2 source = ColumnDataSource(data=dict(x=x, y=y)) p = figure(title="initial title") p.circle(x=1, y=list(range(0, 11))) p.line('x', 'y', color="orange", source=source) slider = Slider(start=0, end=10, step=0.1, value=1) def scb(attr, old, new): source.data['y'] = new * y slider.on_change('value', scb) combine = Button(label="hold combine") combine.on_event(ButtonClick, lambda event: doc.hold("combine")) collect = Button(label="hold collect") collect.on_event(ButtonClick, lambda event: doc.hold("collect")) unhold = Button(label="unhold")
speed_circles = fig.circle(source=speed_source, x="x", y="y", radius="r", fill_color="blue", fill_alpha=.3, line_alpha=0, hover_alpha=1, hover_color="yellow", legend="Speeding") drunk_circles = fig.circle(source=drunk_source, x="x", y="y", radius="r", fill_color="red", fill_alpha=.3, line_alpha=0, hover_alpha=1, hover_color="yellow", legend="Drunk") dot_tooltips = [("Date", "@MONTH/@DAY/@YEAR"), ("Fatalities", "@FATALS"), ("Drunk", "@DRUNK_DR"), ("Speeding", "@SP"), ("Weather", "@WEATHER")] fig.add_tools(HoverTool(renderers=[other_circles, speed_circles, drunk_circles], tooltips=dot_tooltips)) button_group = CheckboxButtonGroup( labels=["Other", "Speeding", "Drunk"], active=[0, 1, 2], width=200) toggle = Toggle(label="Sort by Hour", button_type="default") slider = Slider(title="Hour (Military Time)", start=0, end=23, value=0, step=1) empty_dict = dict( x=np.array([]), y=np.array([]), r=np.array([]), MONTH=np.array([]), DAY=np.array([]), YEAR=np.array([]), FATALS=np.array([]), DRUNK_DR=np.array([]), SP=np.array([]), WEATHER=np.array([]) ) def update_hour(attrname, old, new):
p_CCmax_hover_callback = CustomJS(args=CJSargs, code=hover_JScode) p_CCmax_hover = HoverTool(tooltips=tooltips, callback=p_CCmax_hover_callback, renderers=[r_CCmax_square]) p_CCmax.add_tools(p_CCmax_hover) p_CCpeak_hover_callback = CustomJS(args=CJSargs, code=hover_JScode) p_CCpeak_hover = HoverTool(tooltips=tooltips, callback=p_CCpeak_hover_callback, renderers=[r_CCpeak_square]) p_CCpeak.add_tools(p_CCpeak_hover) Slider_watershed = Slider( start=0, end=100, value=0, step=0.5, title="watershed", width=config_main['plot_config']['tab_XCorr']['widgetbox_wdth'], callback_policy='mouseup') # This data source is just used to communicate / trigger the real callback Slider_watershed.on_change('value', Slider_watershed_update) Slider_threshold = Slider( start=0, end=100, value=0, step=1, title="threshold", width=config_main['plot_config']['tab_XCorr']['widgetbox_wdth'], callback_policy='mouseup')
def create_html(self): self.reduce() temp = datetime.now() filename = temp.strftime("%y_%m_%d__%H_%M_%S_") + "{:0>6}".format(temp.microsecond) + ".html" output_file(self.directory_to_save + filename) current_position = ColumnDataSource(data={'num':[0]}) flags = ColumnDataSource(data={'flag':[{'is_playing': False}]}) text = ColumnDataSource(data=dict(score=['Score ' + self.all_bodies['score'][0]])) current_polyg = ColumnDataSource(data=self.all_bodies['rects_timesteps'][0]) all_polyg = ColumnDataSource(data=self.all_bodies) current_circles = ColumnDataSource(data=self.all_bodies['circles_timesteps'][0]) slider_callback = Callback( args=dict( current=current_polyg, current_circles=current_circles, all_polyg=all_polyg, text=text, flags=flags, current_position=current_position ), code=""" var num = cb_obj.get('value'); current_position.get('data')['num'][0] = num; var flags_data = flags.get('data'); flags_data['flag']['is_playing'] = false; flags.trigger('change'); current_position.trigger('change'); """ + self.js_code) slider = Slider(start=0, end=len(self.all_bodies['rects_timesteps']) - 1, value=0, step=1, title="Iteration number", callback=slider_callback) slider_id = '' + str(slider.vm_serialize()['id']) p = figure( plot_width=int(self.width), plot_height=int(self.height), x_range=(0, int(self.model_size['x'])), y_range=(0, int(self.model_size['y'])), title="Watch Here" ) button_callback = Callback( args=dict( current=current_polyg, current_circles=current_circles, all_polyg=all_polyg, text=text, flags=flags, current_position=current_position ), code=""" console.log("Start"); var flags_data = flags.get('data'); var num = current_position.get('data')['num'][0] var slider_id = '""" + slider_id + """' var amount_of_iterations = """ + str(len(self.all_bodies['rects_timesteps'])) + """; if (!flags_data['flag']['is_playing']) { flags_data['flag']['is_playing'] = true intervalID = setInterval(function () { var flags_data = flags.get('data'); is_playing = flags_data['flag']['is_playing'] if (is_playing) { """ + self.js_code + """ Bokeh.$('div #' + slider_id).val(Math.floor(num)); Bokeh.$('div #' + slider_id + ' :first-child').css('left', num / (amount_of_iterations - 1) * 100 + '%') num += 1 } if (num > (amount_of_iterations - 1) || !is_playing) { current_position.get('data')['num'][0] = num current_position.trigger('change') flags_data['flag']['is_playing'] = is_playing = false window.clearInterval(intervalID); console.log("Finally") } }, Math.floor(1000.0 / """ + str(self.start_settings.model_settings.hz / 10.0) + """ / """ + str((float(self.max_iteration) / self.len_before_redunction)) + """)); } else { flags_data['flag']['is_playing'] = false } flags.trigger('change') return false; """) button = Button(label="Play", type="success", callback=button_callback) ground = points_to_dictionary(self.start_settings.ground_settings.points, self.local_zero_point) p.line(ground['x'], ground['y']) p.patches('xs', 'ys', color='color', source=current_polyg) p.circle('x', 'y', radius='radius', color='color', source=current_circles) p.text(1, int(self.model_size['y']) - 3, text='score', alpha=5, text_font_size="15pt", text_baseline="middle", text_align="left", source=text) self.layout = vform(button, slider, p)
def plot_carto_single(self, data, frente, palette, name_file="test.html", low=0, high=100): """ :param data: df loaded by data_load :param frente: string, name of "partido" lowercase: diff, mas, cc, creemos, fpv, panbol :param palette: ej: P_GRAD_CC :param name_file: default:test :param low: cmap low limit: default: -80 :param high: cmap high limit: defauilt: +80. :return: df """ if frente == "diff": low = self.C_BAR_LOW high = self.C_BAR_HIGH frente = "d_mas_cc" bokeh.plotting.output_file(self.FILE_OUT + '_' + frente + '_' + name_file) cart_init_val = self.CART_SLIDER_INIT # add slider data['x'] = data['LON'] * (1 - cart_init_val) + data['X'] * cart_init_val data['y'] = data['LAT'] * (1 - cart_init_val) + data['Y'] * cart_init_val cm = linear_cmap(frente, palette=palette, low=low, high=high) data['mas'] = data['MAS'] / data['VV'] * 100 data['cc'] = data['CC'] / data['VV'] * 100 data['pdc'] = data['PDC'] / data['VV'] * 100 #data['creemos'] = data['CREEMOS'] / data['VV'] * 100 #data['fpv'] = data['FPV'] / data['VV'] * 100 #data['panbol'] = data['PANBOL'] / data['VV'] * 100 data['ad_mas_cc'] = data['d_mas_cc'].abs() data['mas_o_cc'] = 'n' data.loc[data['d_mas_cc'] >= 0, 'mas_o_cc'] = 'MAS' data.loc[data['d_mas_cc'] < 0, 'mas_o_cc'] = 'CC' source_master = ColumnDataSource(data) source_red_map = ColumnDataSource({'gx': [], 'gy': []}) la, lo = ebu.get_la_lo_bolivia() source_bol = ColumnDataSource({'la': la, 'lo': lo}) # source_red_car = ColumnDataSource({'lo': [], 'la': []}) # JS CODE code_draw_red_map = """ const data = {'gx': [], 'gy': []} const indices = cb_data.index.indices for (var i = 0; i < indices.length; i++ ) { data['gx'].push(source_master.data.GX[indices[i]]) data['gy'].push(source_master.data.GY[indices[i]]) } source_red_map.data = data """ code_draw_red_car = """ const data = {'lo': [], 'la': []} const indices = cb_data.index.indices for (var i = 0; i < indices.length; i++) { data['lo'].push(source_master.data.x[indices[i]]) data['la'].push(source_master.data.y[indices[i]]) } source_red_car.data = data """ code_merged = """ const data_map = {'lo': [], 'la': []} const data_car = {'gx': [], 'gy': []} const indices = cb_data.index.indices for (var i = 0; i < indices.length; i++) { data_map['lo'].push(source_master.data.x[indices[i]]) data_map['la'].push(source_master.data.y[indices[i]]) data_car['gx'].push(source_master.data.GX[indices[i]]) data_car['gy'].push(source_master.data.GY[indices[i]]) } source_red_car.data = data_car source_red_map.data = data_map """ code_slider = """ var data = source.data; var f = cb_obj.value var x = data['x'] var y = data['y'] var Y = data['Y'] var X = data['X'] var lat = data['LAT'] var lon = data['LON'] for (var i = 0; i < x.length; i++) { y[i] = (1-f)*lat[i] + f*Y[i] x[i] = (1-f)*lon[i] + f*X[i] } source.change.emit(); """ # FIGURES pw = self.FIG_WIDTH cart_fig = Figure(plot_width=pw, plot_height=pw, output_backend="webgl") map_fig = Figure( plot_width=pw, plot_height=pw, x_axis_type='mercator', y_axis_type='mercator', output_backend="webgl", ) cart_fig.background_fill_color = "grey" cart_fig.background_fill_alpha = .5 # cb_fig = bokeh.plotting.Figure(plot_height=pw,plot_width=) # cb_fig.toolbar.logo = None # cb_fig.toolbar_location = None # SCATTER # noinspection PyUnresolvedReferences # add tiles tile_provider = bokeh.tile_providers.get_provider( bokeh.tile_providers.Vendors.CARTODBPOSITRON) map_fig.add_tile(tile_provider) # scatter in map map_fig.scatter('GX', 'GY', source=source_master, size='r2', color=cm) # todo if we wont use map then we nee to delete the source # cart_fig.line('lo', 'la', source=source_bol, color='black') cart_fig.scatter('x', 'y', source=source_master, radius='r', color=cm) red_scat_map = map_fig.circle_cross( 'gx', 'gy', source=source_red_map, # color='red', fill_color=None, # line_color='green', size=20, line_color="white", line_width=4) red_scat_map = map_fig.circle_cross( 'gx', 'gy', source=source_red_map, # color='red', fill_color=None, # line_color='green', size=20, line_color="red", line_width=1) # red_scat_car = cart_fig.scatter('lo', 'la', # source=source_red_car, color='green') # add a hover tool that sets the link data for a hovered circle # callbacks callback_red_map = CustomJS( args={ 'source_master': source_master, 'source_red_map': source_red_map, # 'source_red_car':source_red_car }, code=code_draw_red_map) # code = code_merged) # callback_red_car = CustomJS( # args={'source_master': source_master, 'source_red_car': source_red_car}, # code=code_draw_red_car) # tools hover_cart = bokeh.models.HoverTool( tooltips=self.TOOL_TIP_DIC[frente], callback=callback_red_map, # renderers = [red_scat_car] ) cart_fig.add_tools(hover_cart, ) hover_map = bokeh.models.HoverTool( tooltips=self.TOOL_TIP_DIC[frente], # callback=callback_red_car, # renderers = [red_scat_map] ) map_fig.add_tools(hover_map, ) # slider callback_slider = CustomJS(args=dict(source=source_master), code=code_slider) slider = Slider(start=0, end=1, value=cart_init_val, step=.02, title="carto") slider.js_on_change('value', callback_slider) # COLOR BAR ml = {int(i): str(np.abs(i)) for i in np.arange(-80, 81, 20)} cb = bokeh.models.ColorBar( color_mapper=cm['transform'], width=int(.9 * self.FIG_WIDTH), location=(0, 0), # title="DEN (N/km^2)", # title=(BAR_TITLE), # margin=0,padding=0, title_standoff=10, # ticker=bokeh.models.LogTicker(), orientation='horizontal', major_label_overrides=ml) cart_fig.add_layout(cb, 'above') # cb.title_text_align = 'left' cart_fig.title.text = self.BAR_TITLE_DIC[frente] cart_fig.title.align = 'center' # layout = row(column(slider, cart_f),map_f) layout = bokeh.layouts.gridplot([[slider, None], [cart_fig, map_fig]], merge_tools=False) # layout = bokeh.layouts.column([slider, cart_fig]) cart_fig.x_range.start = self.CXS cart_fig.x_range.end = self.CXE cart_fig.y_range.start = self.CYS cart_fig.y_range.end = self.CYE _ll = ebu.lola_to_cart(lo=[self.MXS, self.MXE], la=[self.MYS, self.MYE]) map_fig.x_range.start = _ll[0][0] map_fig.x_range.end = _ll[0][1] map_fig.y_range.start = _ll[1][0] map_fig.y_range.end = _ll[1][1] cart_fig.xaxis.major_tick_line_color = None # turn off x-axis major ticks cart_fig.xaxis.minor_tick_line_color = None # turn off x-axis minor ticks cart_fig.yaxis.major_tick_line_color = None # turn off y-axis major ticks cart_fig.yaxis.minor_tick_line_color = None cart_fig.xaxis.major_label_text_font_size = '0pt' # turn off x-axis tick labels cart_fig.yaxis.major_label_text_font_size = '0pt' # turn off y-axis tick labels bokeh.plotting.show(layout) return data
Attach the callback to the 'value' property of slider. This can be done using on_change() and passing in 'value' and update_plot. Make a row layout of widgetbox(slider) and plot and add it to the current document. ''' # Import the necessary modules from bokeh.layouts import widgetbox, row from bokeh.models import Slider # Define the callback function: update_plot def update_plot(attr, old, new): # set the `yr` name to `slider.value` and `source.data = new_data` yr = slider.value new_data = { 'x' : data.loc[yr].fertility, 'y' : data.loc[yr].life, 'country' : data.loc[yr].Country, 'pop' : (data.loc[yr].population / 20000000) + 2, 'region' : data.loc[yr].region, } source.data = new_data # Make a slider object: slider slider = Slider(start=1970, end=2010, step=1, value=1970, title='Year') # Attach the callback to the 'value' property of slider slider.on_change('value',update_plot) # Make a row layout of widgetbox(slider) and plot and add it to the current document layout = row(widgetbox(slider), plot) curdoc().add_root(layout)
w, h = image.shape source = ColumnDataSource(data=dict(image=[image])) p = figure(x_range=(0, w), y_range=(0, h)) p.image('image', x=0, y=0, dw=w, dh=h, palette=gray(256), source=source) @njit def blur(outimage, image, amt): for i in range(amt, w - amt): for j in range(amt, h - amt): px = 0. for iw in range(-amt // 2, amt // 2): for jh in range(-amt // 2, amt // 2): px += image[i + iw, j + jh] outimage[i, j] = px / (amt * amt) def update(attr, old, new): out = image.copy() blur(out, image, 2 * new + 1) source.data.update(image=[out]) slider = Slider(title="Blur Factor", start=0, end=10, value=0) slider.on_change('value', update) curdoc().add_root(column(p, slider)) curdoc().title = "Image Blur"
plot = renderer.get_plot(hmap) plot.update(0) def animate_update(): year = slider.value + 1 if year > end: year = start slider.value = year def slider_update(attrname, old, new): plot.update(slider.value) slider = Slider(start=start, end=end, value=0, step=1, title="Year") slider.on_change('value', slider_update) def animate(): if button.label == '► Play': button.label = '❚❚ Pause' curdoc().add_periodic_callback(animate_update, 200) else: button.label = '► Play' curdoc().remove_periodic_callback(animate_update) button = Button(label='► Play', width=60) button.on_click(animate)
def __init__(self, model, resolution=50, doc=None): """ Initialize parameters. Parameters ---------- model : MetaModelComponent Reference to meta model component resolution : int Value used to calculate the size of contour plot meshgrid doc : Document The bokeh document to build. """ self.prob = Problem() self.resolution = resolution logging.getLogger("bokeh").setLevel(logging.ERROR) # If the surrogate model coming in is structured if isinstance(model, MetaModelUnStructuredComp): self.is_structured_meta_model = False # Create list of input names, check if it has more than one input, then create list # of outputs self.input_names = [name[0] for name in model._surrogate_input_names] if len(self.input_names) < 2: raise ValueError('Must have more than one input value') self.output_names = [name[0] for name in model._surrogate_output_names] # Create reference for untructured component self.meta_model = MetaModelUnStructuredComp( default_surrogate=model.options['default_surrogate']) # If the surrogate model coming in is unstructured elif isinstance(model, MetaModelStructuredComp): self.is_structured_meta_model = True self.input_names = [name for name in model._var_rel_names['input']] if len(self.input_names) < 2: raise ValueError('Must have more than one input value') self.output_names = [name for name in model._var_rel_names['output']] self.meta_model = MetaModelStructuredComp( distributed=model.options['distributed'], extrapolate=model.options['extrapolate'], method=model.options['method'], training_data_gradients=model.options['training_data_gradients'], vec_size=1) # Pair input list names with their respective data self.training_inputs = {} self._setup_empty_prob_comp(model) # Setup dropdown menus for x/y inputs and the output value self.x_input_select = Select(title="X Input:", value=[x for x in self.input_names][0], options=[x for x in self.input_names]) self.x_input_select.on_change('value', self._x_input_update) self.y_input_select = Select(title="Y Input:", value=[x for x in self.input_names][1], options=[x for x in self.input_names]) self.y_input_select.on_change('value', self._y_input_update) self.output_select = Select(title="Output:", value=[x for x in self.output_names][0], options=[x for x in self.output_names]) self.output_select.on_change('value', self._output_value_update) # Create sliders for each input self.slider_dict = {} self.predict_inputs = {} for title, values in self.training_inputs.items(): slider_data = np.linspace(min(values), max(values), self.resolution) self.predict_inputs[title] = slider_data # Calculates the distance between slider ticks slider_step = slider_data[1] - slider_data[0] slider_object = Slider(start=min(values), end=max(values), value=min(values), step=slider_step, title=str(title)) self.slider_dict[title] = slider_object self._slider_attrs() # Length of inputs and outputs self.num_inputs = len(self.input_names) self.num_outputs = len(self.output_names) # Precalculate the problem bounds. limits = np.array([[min(value), max(value)] for value in self.training_inputs.values()]) self.limit_range = limits[:, 1] - limits[:, 0] # Positional indicies self.x_index = 0 self.y_index = 1 self.output_variable = self.output_names.index(self.output_select.value) # Data sources are filled with initial values # Slider Column Data Source self.slider_source = ColumnDataSource(data=self.predict_inputs) # Contour plot Column Data Source self.contour_plot_source = ColumnDataSource(data=dict( z=np.random.rand(self.resolution, self.resolution))) self.contour_training_data_source = ColumnDataSource( data=dict(x=np.repeat(0, self.resolution), y=np.repeat(0, self.resolution))) # Bottom plot Column Data Source self.bottom_plot_source = ColumnDataSource(data=dict( x=np.repeat(0, self.resolution), y=np.repeat(0, self.resolution))) self.bottom_plot_scatter_source = ColumnDataSource(data=dict( bot_slice_x=np.repeat(0, self.resolution), bot_slice_y=np.repeat(0, self.resolution))) # Right plot Column Data Source self.right_plot_source = ColumnDataSource(data=dict( x=np.repeat(0, self.resolution), y=np.repeat(0, self.resolution))) self.right_plot_scatter_source = ColumnDataSource(data=dict( right_slice_x=np.repeat(0, self.resolution), right_slice_y=np.repeat(0, self.resolution))) # Text input to change the distance of reach when searching for nearest data points self.scatter_distance = TextInput(value="0.1", title="Scatter Distance") self.scatter_distance.on_change('value', self._scatter_input) self.dist_range = float(self.scatter_distance.value) # Grouping all of the sliders and dropdowns into one column sliders = [value for value in self.slider_dict.values()] sliders.extend( [self.x_input_select, self.y_input_select, self.output_select, self.scatter_distance]) self.sliders_and_selects = row( column(*sliders)) # Layout creation self.doc_layout = row(self._contour_data(), self._right_plot(), self.sliders_and_selects) self.doc_layout2 = row(self._bottom_plot()) if doc is None: doc = curdoc() doc.add_root(self.doc_layout) doc.add_root(self.doc_layout2) doc.title = 'Meta Model Visualization'
return plot def update(attr, old, new): print("hello") print(old) print(new) new_src = make_dataset(yr = int(new)) geo_src.geojson = new_src p = make_plot() controls = WidgetBox(year_select) layout = row(p, controls) curdoc().clear() curdoc().add_root(layout) year_select = Slider(start = 2000, end = 2016, step = 4, value = 2000, title = 'Election Year') year_select.on_change('value', update) geo_src = GeoJSONDataSource(geojson = make_dataset(yr = year_select.value)) #geo_src = make_dataset(yr = year_select.value) #geo_src = GeoJSONDataSource(geojson = src.to_json()) p = make_plot() controls = WidgetBox(year_select) layout = row(p, controls) curdoc().add_root(layout)
''' Add a single slider In the previous exercise, you added a single plot to the "current document" of your application. In this exercise, you'll practice adding a layout to your current document. Your job here is to create a single slider, use it to create a widgetbox layout, and then add this layout to the current document. The slider you create here cannot be used for much, but in the later exercises, you'll use it to update your plots! Instructions 100 XP Import curdoc from bokeh.io, widgetbox from bokeh.layouts, and Slider from bokeh.models. Create a slider called slider by using the Slider() function and specifying the parameters title, start, end, step, and value. Use the slider to create a widgetbox layout called layout. Add the layout to the current document using curdoc().add_root(). It needs to be passed in as an argument to add_root(). ''' SOLUTION # Perform the necessary imports from bokeh.io import curdoc from bokeh.layouts import widgetbox from bokeh.models import Slider # Create a slider: slider slider = Slider(title='my slider', start=0, end=10, step=0.1, value=2) # Create a widgetbox layout: layout layout = widgetbox(slider) # Add the layout to the current document curdoc().add_root(layout)
] p.add_layout(legend) def update(): try: expr = sy.sympify(text.value, dict(x=xs)) except Exception as exception: errbox.text = str(exception) else: errbox.text = "" x, fy, ty = taylor(expr, xs, slider.value, (-2*sy.pi, 2*sy.pi), 200) p.title.text = "Taylor (n=%d) expansion comparison for: %s" % (slider.value, expr) legend.items[0].label = value("%s" % expr) legend.items[1].label = value("taylor(%s)" % expr) source.data = dict(x=x, fy=fy, ty=ty) slider = Slider(start=1, end=20, value=1, step=1, title="Order") slider.on_change('value', lambda attr, old, new: update()) text = TextInput(value=str(expr), title="Expression:") text.on_change('value', lambda attr, old, new: update()) errbox = PreText() update() inputs = column(text, slider, errbox, width=400) curdoc().add_root(column(inputs, p))
def create_interact_ui(doc): # The data source includes metadata for hover-over tooltips lc_source = prepare_lightcurve_datasource(lc) tpf_source = prepare_tpf_datasource(tpf, aperture_mask) # Create the lightcurve figure and its vertical marker fig_lc, vertical_line = make_lightcurve_figure_elements(lc, lc_source, ylim_func=ylim_func) # Create the TPF figure and its stretch slider pedestal = -np.nanmin(tpf.flux) + 1 if scale == 'linear': pedestal = 0 fig_tpf, stretch_slider = make_tpf_figure_elements(tpf, tpf_source, pedestal=pedestal, fiducial_frame=0, vmin=vmin, vmax=vmax, scale=scale, cmap=cmap, tools=tools) # Helper lookup table which maps cadence number onto flux array index. tpf_index_lookup = {cad: idx for idx, cad in enumerate(tpf.cadenceno)} # Interactive slider widgets and buttons to select the cadence number cadence_slider = Slider(start=np.min(tpf.cadenceno), end=np.max(tpf.cadenceno), value=np.min(tpf.cadenceno), step=1, title="Cadence Number", width=490) r_button = Button(label=">", button_type="default", width=30) l_button = Button(label="<", button_type="default", width=30) export_button = Button(label="Save Lightcurve", button_type="success", width=120) message_on_save = Div(text=' ',width=600, height=15) # Callbacks def _create_lightcurve_from_pixels(tpf, selected_pixel_indices, transform_func=transform_func): """Create the lightcurve from the selected pixel index list""" selected_indices = np.array(selected_pixel_indices) selected_mask = np.isin(pixel_index_array, selected_indices) lc_new = tpf.to_lightcurve(aperture_mask=selected_mask) lc_new.meta['aperture_mask'] = selected_mask if transform_func is not None: lc_transformed = transform_func(lc_new) if (len(lc_transformed) != len(lc_new)): warnings.warn('Dropping cadences in `transform_func` is not ' 'yet supported due to fixed time coordinates.' 'Skipping the transformation...', LightkurveWarning) else: lc_new = lc_transformed lc_new.meta['aperture_mask'] = selected_mask return lc_new def update_upon_pixel_selection(attr, old, new): """Callback to take action when pixels are selected.""" # Check if a selection was "re-clicked", then de-select if ((sorted(old) == sorted(new)) & (new != [])): # Trigger recursion tpf_source.selected.indices = new[1:] if new != []: lc_new = _create_lightcurve_from_pixels(tpf, new, transform_func=transform_func) lc_source.data['flux'] = lc_new.flux if ylim_func is None: ylims = get_lightcurve_y_limits(lc_source) else: ylims = ylim_func(lc_new) fig_lc.y_range.start = ylims[0] fig_lc.y_range.end = ylims[1] else: lc_source.data['flux'] = lc.flux * 0.0 fig_lc.y_range.start = -1 fig_lc.y_range.end = 1 message_on_save.text = " " export_button.button_type = "success" def update_upon_cadence_change(attr, old, new): """Callback to take action when cadence slider changes""" if new in tpf.cadenceno: frameno = tpf_index_lookup[new] fig_tpf.select('tpfimg')[0].data_source.data['image'] = \ [tpf.flux[frameno, :, :] + pedestal] vertical_line.update(location=tpf.time[frameno]) else: fig_tpf.select('tpfimg')[0].data_source.data['image'] = \ [tpf.flux[0, :, :] * np.NaN] lc_source.selected.indices = [] def go_right_by_one(): """Step forward in time by a single cadence""" existing_value = cadence_slider.value if existing_value < np.max(tpf.cadenceno): cadence_slider.value = existing_value + 1 def go_left_by_one(): """Step back in time by a single cadence""" existing_value = cadence_slider.value if existing_value > np.min(tpf.cadenceno): cadence_slider.value = existing_value - 1 def save_lightcurve(): """Save the lightcurve as a fits file with mask as HDU extension""" if tpf_source.selected.indices != []: lc_new = _create_lightcurve_from_pixels(tpf, tpf_source.selected.indices, transform_func=transform_func) lc_new.to_fits(exported_filename, overwrite=True, flux_column_name='SAP_FLUX', aperture_mask=lc_new.meta['aperture_mask'].astype(np.int), SOURCE='lightkurve interact', NOTE='custom mask', MASKNPIX=np.nansum(lc_new.meta['aperture_mask'])) if message_on_save.text == " ": text = '<font color="black"><i>Saved file {} </i></font>' message_on_save.text = text.format(exported_filename) export_button.button_type = "success" else: text = '<font color="gray"><i>Saved file {} </i></font>' message_on_save.text = text.format(exported_filename) else: text = '<font color="gray"><i>No pixels selected, no mask saved</i></font>' export_button.button_type = "warning" message_on_save.text = text def jump_to_lightcurve_position(attr, old, new): if new != []: cadence_slider.value = lc.cadenceno[new[0]] # Map changes to callbacks r_button.on_click(go_right_by_one) l_button.on_click(go_left_by_one) tpf_source.selected.on_change('indices', update_upon_pixel_selection) lc_source.selected.on_change('indices', jump_to_lightcurve_position) export_button.on_click(save_lightcurve) cadence_slider.on_change('value', update_upon_cadence_change) # Layout all of the plots sp1, sp2, sp3, sp4 = (Spacer(width=15), Spacer(width=30), Spacer(width=80), Spacer(width=60)) widgets_and_figures = layout([fig_lc, fig_tpf], [l_button, sp1, r_button, sp2, cadence_slider, sp3, stretch_slider], [export_button, sp4, message_on_save]) doc.add_root(widgets_and_figures)
# create another new plot and add a renderer right = figure(tools=TOOLS, plot_width=300, plot_height=300, title=None) right.circle('x', 'y1', source=source) p = gridplot([[left, right]]) show(p) # Linked properties - Link values of Bokeh model properties together, so they # remain synchronzed, using js_link. output_file("JS_link.html") plot = figure(plot_width=400, plot_height=400) r = plot.circle([1,2,3,4,5], [3,2,5,6,4], radius=0.2, alpha=0.5) slider = Slider(start=0.1, end=2, step=0.01, value=0.2) # method js_link(attr, other, other_attr) # @brief Link 2 Bokeh model properties using JavaScript. # @details This is a convenience method that simplifies adding a CustomJS # callback to update 1 Bokeh model property whenever another changes value. # Parameters * attr(str) - The name of a Bokeh property on this model # * other (Model) - A Bokeh model to link to self.attr # * other_attr(str) - The property on other to link together. slider.js_link('value', r.glyph, 'radius') show(column(plot, slider))
'continent': gapminder.loc[yr].continent, 'population': gapminder.loc[yr].population } source.data = new_data #assign new_data to source.data xrange_start = min(source.data['x']) print(xrange_start) plot.x_range.start = xrange_start #set the range of all axes plot.x_range.end = max(source.data['x']) plot.y_range.start = min(source.data['y']) plot.y_range.end = max(source.data['y']) plot.title.text = 'Gapminder data for {0}'.format( yr) #add title to plot with selected year in it slider = Slider(start=1952, end=2007, step=5, value=1952, title='Year') #create a slider widget slider.on_change( 'value', update_plot) #attach the callback to the 'value' property of slider x_select = Select( #create a dropdown menu (i.e. a Select widget) for the x data: x_select options=['fertility', 'lifeExp', 'infant_mortality_rate', 'gdpPercap'], value='fertility', #(this is the start value) title='x-axis data') x_select.on_change( 'value', update_plot ) #attach the update_plot callback to the 'value' property of x_select y_select = Select( #create a dropdown menu (i.e. a Select widget) for the y data: y_select
lines''' ] def xs(cat): return [(cat, -0.3), (cat, -0.1), (cat, 0.1), (cat, 0.3)] def ys(cat): return [cat] * 4 renderers = {} i = 0 for a in aligns: for b in baselines: r = p.text(xs(a), ys(b), texts, text_align=a, text_baseline=b, text_font_size="14px", text_line_height=1.2) renderers["r" + str(i)] = r i += 1 slider = Slider(title="Text Angle", start=0, end=45, step=1, value=0) slider.js_on_change('value', CustomJS(args=renderers, code=""" var rs = [r0, r1, r2 , r3, r4, r5, r6, r7, r8]; for (var i = 0; i < 9; i++) { rs[i].glyph.angle = {value: cb_obj.value, units: "deg"} } """)) output_file("text.html") show(column(p, slider))
def create_plot(data, xcol, ycol, ccol, plt_name): xval = copy(data[:, xcol]) n = len(xval) yval = copy(data[:, ycol]) cval = copy(data[:, ccol]) colors, colorbar = set_colors(cval, plt_name) datasrc = ColumnDataSource( data=dict(x=xval, y=yval, z=cval, colors=colors)) # color_mapper = LinearColorMapper(palette="Viridis256", low=min(cval), high=max(cval)) # colorbar = ColorBar(color_mapper=color_mapper, ticker=BasicTicker(),label_standoff=12, border_line_color=None, location=(0,0)) s2 = ColumnDataSource(data=dict(xs=[], ys=[])) source = ColumnDataSource({'xs': [], 'ys': [], 'wd': [], 'ht': []}) jscode = """ var data = source.get('data'); var start = range.get('start'); var end = range.get('end'); data['%s'] = [start + (end - start) / 2]; data['%s'] = [end - start]; source.trigger('change'); """ initial_circle = Circle(x='x', y='y') selected_circle = Circle(fill_alpha=1, fill_color="firebrick", size=20) nonselected_circle = Circle(fill_alpha=0.4, fill_color='colors', line_color=None) title = " " TOOLS = "crosshair,pan,wheel_zoom,box_zoom,reset,box_select,lasso_select,tap,save" #TOOLS="pan,wheel_zoom,box_select,lasso_select,reset" # The main Plot of tab 1 p1 = figure(title=title, tools=TOOLS, active_scroll="wheel_zoom", height=500, width=500, toolbar_location="above") # p1.toolbar.active_scroll=None p1.circle('x', 'y', source=datasrc, size=5, fill_color='colors', fill_alpha=0.6, line_color=None, name="mycircle") p1.add_layout(colorbar, 'left') p1.x_range.callback = CustomJS(args=dict(source=source, range=p1.x_range), code=jscode % ('xs', 'wd')) p1.y_range.callback = CustomJS(args=dict(source=source, range=p1.y_range), code=jscode % ('ys', 'ht')) renderer = p1.select(name="mycircle") renderer.selection_glyph = selected_circle renderer.nonselection_glyph = nonselected_circle p1.xgrid.grid_line_color = None p1.ygrid.grid_line_color = None p1.xaxis[0].ticker = FixedTicker(ticks=[]) p1.yaxis[0].ticker = FixedTicker(ticks=[]) p1.outline_line_width = 0 p1.outline_line_color = "white" p1.xaxis.axis_line_width = 0 p1.xaxis.axis_line_color = "white" p1.yaxis.axis_line_width = 0 p1.yaxis.axis_line_color = "white" # The overview plot p2 = figure(tools='', height=250, width=250) p2.xgrid.grid_line_color = None p2.ygrid.grid_line_color = None p2.xaxis[0].ticker = FixedTicker(ticks=[]) p2.yaxis[0].ticker = FixedTicker(ticks=[]) p2.circle('x', 'y', source=datasrc, size=5, fill_color=colors, fill_alpha=0.8, line_color=None, name='mycircle') renderer = p2.select(name="mycircle") renderer.selection_glyph = selected_circle renderer.nonselection_glyph = nonselected_circle p2.outline_line_width = 0 p2.outline_line_alpha = 0.3 p2.outline_line_color = "white" p2.xaxis.axis_line_width = 0 p2.xaxis.axis_line_color = "white" p2.yaxis.axis_line_width = 0 p2.yaxis.axis_line_color = "white" rect = Rect(x='xs', y='ys', width='wd', height='ht', fill_alpha=0.1, line_color='black', fill_color='black') p2.add_glyph(source, rect) callback = CustomJS(code=""" var inds = cb_obj.get('selected')['1d'].indices[0]; var str = "" + inds; var pad = "0000"; var indx = pad.substring(0, pad.length - str.length) + str; var settings= "connect 1.0 1.2 (carbon) (hydrogen) SINGLE CREATE ; connect 1.0 1.2 (nitrogen) (hydrogen) SINGLE CREATE ; connect 1.0 4.2 (carbon) (nitrogen) SINGLE CREATE ; connect 3.0 5 (phosphorus) (iodine) SINGLE CREATE ; set perspectiveDepth OFF " var file= "javascript:Jmol.script(jmolApplet0," + "'load plot-server/static/xyz/set."+ indx+ ".xyz ;" + settings + "')" ; location.href=file; """) # def slider_callback2(src=datasrc,source=s2, window=None): # data = source.data # xval=src.data['x'] # yval=src.data['y'] # ind = cb_obj.value # NOQA # data['xs']=[xval[ind]] # data['ys']=[yval[ind]] # source.trigger('change'); taptool = p1.select(type=TapTool) taptool.callback = callback # taptool.js_on_change('value', callback=CustomJS.from_py_func(slider_callback2)) slider_callback = CustomJS(code=""" var inds = cb_obj.value; var str = "" + inds; var pad = "0000"; var indx = pad.substring(0, pad.length - str.length) + str; var settings= "connect 1.0 1.2 (carbon) (hydrogen) SINGLE CREATE ; connect 1.0 1.2 (nitrogen) (hydrogen) SINGLE CREATE ; connect 1.0 4.2 (carbon) (nitrogen) SINGLE CREATE ; connect 3.0 5 (phosphorus) (iodine) SINGLE CREATE ; set perspectiveDepth OFF " var file= "javascript:Jmol.script(jmolApplet1," + "'load plot-server/static/xyz/set."+ indx+ ".xyz ;" + settings + "')" ; location.href=file; """) # slider = Slider(start=0, end=2600, value=0, step=1, title="selected", callback=CustomJS.from_py_func(slider_callback2)) slider = Slider(start=0, end=n - 1, value=0, step=1, title="Frame:", width=800) # slider.js_on_change('value', CustomJS.from_py_func(slider_callback2)) slider.js_on_change('value', slider_callback) # draw selected point on slider change # p1.circle('xs', 'ys', source=s2, fill_alpha=1, fill_color="firebrick", size=10,name="mycircle") return p1, p2, slider
def slider(): x = np.linspace(0, 10, 100) y = np.sin(x) source = ColumnDataSource(data=dict(x=x, y=y)) plot = figure( y_range=(-10, 10), tools='', toolbar_location=None, title="Sliders example") plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6) amp_slider = Slider(start=0.1, end=10, value=1, step=.1, title="Amplitude") freq_slider = Slider(start=0.1, end=10, value=1, step=.1, title="Frequency") phase_slider = Slider(start=0, end=6.4, value=0, step=.1, title="Phase") offset_slider = Slider(start=-5, end=5, value=0, step=.1, title="Offset") callback = CustomJS(args=dict(source=source, amp=amp_slider, freq=freq_slider, phase=phase_slider, offset=offset_slider), code=""" const data = source.data; const A = amp.value; const k = freq.value; const phi = phase.value; const B = offset.value; const x = data['x'] const y = data['y'] for (var i = 0; i < x.length; i++) { y[i] = B + A*Math.sin(k*x[i]+phi); } source.change.emit(); """) amp_slider.js_on_change('value', callback) freq_slider.js_on_change('value', callback) phase_slider.js_on_change('value', callback) offset_slider.js_on_change('value', callback) widgets = column(amp_slider, freq_slider, phase_slider, offset_slider) return [widgets, plot]
def modify_doc(cls): TOOLS = "pan,wheel_zoom,box_zoom,reset,save" season = Season() seasons_1990_on = season.seasons_1990_on data_dict = seasons_1990_on.to_dict('list') source = ColumnDataSource(data=data_dict) slider = Slider(title="Year", start=1990, end=2017, step=1, value=2006) menu_options_list = ["ALL"] + seasons_1990_on["Tm"].unique().tolist() team_menu = Select(options=menu_options_list, value="ALL", title="Team") columns = list(seasons_1990_on.columns) x_axis_menu = Select(options=columns, value="3PA", title="X Axis") y_axis_menu = Select(options=columns, value="3P", title="Y Axis") palette = season.get_palette() color_mapper = CategoricalColorMapper( factors=seasons_1990_on["Tm"].unique().tolist(), palette=palette) TOOLS = "pan,wheel_zoom,box_zoom,reset,save" p1 = figure(x_axis_label="3 Points Attempted", y_axis_label="3 Points Made", tools=TOOLS) ################### p1.circle( "X", "Y", source=source, alpha=0.8, nonselection_alpha=0.1, ) p1.legend.location = "bottom_right" #################### #################### ####################### cls.add_tooltips(p1) column1 = column(widgetbox(team_menu), widgetbox(slider), widgetbox(x_axis_menu), widgetbox(y_axis_menu)) layout = row(column1, p1) args = { 'source': source, 'data_dict': data_dict, 'team_menu': team_menu, 'slider': slider, 'x_axis_menu': x_axis_menu, 'y_axis_menu': y_axis_menu } callback = CustomJS(args=args, code=""" data_copy = JSON.parse(JSON.stringify(data_dict)) console.log(data_copy, "<-- Here is data copy"); if (team_menu.value === "ALL") { console.log("What's up. I am ALL"); } source.change.emit(); """) x_axis_menu.js_on_change('value', callback) resources = INLINE.render() script, div = components({'p': layout}) return {'script': script, 'div': div, 'resources': resources} def callback(attr, old, new): if menu.value == "ALL": new_df = seasons_1990_on[seasons_1990_on['Year'] == slider.value] new_x = new_df[x_axis_menu.value] new_y = new_df[y_axis_menu.value] else: new_df = seasons_1990_on[ (seasons_1990_on['Year'] == slider.value) & (seasons_1990_on['Tm'] == menu.value)] new_x = new_df[x_axis_menu.value] new_y = new_df[y_axis_menu.value] source.data['X'] = new_x source.data['Y'] = new_y new_df['X'] = new_x new_df['Y'] = new_y tooltips = [("Players", "@Player"), (x_axis_menu.value, "@{}".format(x_axis_menu.value))( y_axis_menu.value, "@{}".format(y_axis_menu.value))] source.data = new_df cls.add_tooltips(plot=p1, tooltips=tooltips) print("Here is x", new_x) print("Here is y", new_y) print("Here is y name", new_y.name) p1.xaxis.axis_label = new_x.name p1.yaxis.axis_label = new_y.name slider.on_change("value", callback) menu.on_change("value", callback) x_axis_menu.on_change("value", callback) y_axis_menu.on_change("value", callback)
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6, color='black') # set up static line and annotations plot.line(x, y, line_width=5, color='blue', line_alpha=0.3) mytext = Label(x=50, y=70, text='Km = 10 (μM), Vmax = 100 (μM/s)', text_color="blue", text_alpha=0.5) plot.add_layout(mytext) # set up java script callback function to make plot interactive vmax_slider = Slider(start=0.1, end=200, value=100, step=1, title="Vmax (μM/s)") km_slider = Slider(start=1, end=100, value=10, step=1, title="Km (μM)") callback = CustomJS(args=dict(source=source, vmax=vmax_slider, km=km_slider), code=""" const data = source.data; const VMAX = vmax.value; const KM = km.value; const x = data['x'] const y = data['y'] for (var i = 0; i < x.length; i++) { y[i] = (VMAX*x[i])/(KM+x[i]); } source.change.emit();
def plot_with_bokeh(): beta = 0.8 gamma = 0.1 sigma = 0.5 mu = 0.0 nu = 0.0 y0 = [10, 1, 0, 0] t_span = [0, 30] # days sol = solve_seir_model(beta, gamma, sigma, mu, nu, y0, t_span) x = sol.t y_s, y_e, y_i, y_r = sol.y source = ColumnDataSource(data=dict(x=x, y_s=y_s, y_e=y_e, y_i=y_i, y_r=y_r,)) p = figure( plot_width=800, plot_height=600, x_axis_label="Days", y_axis_label="Population", ) p.line( "x", "y_s", source=source, line_width=3, color="orange", legend_label="Susceptible", ) p.line( "x", "y_e", source=source, line_width=3, color="dodgerblue", legend_label="Exposed", ) p.line( "x", "y_i", source=source, line_width=3, color="orangered", legend_label="Infected", ) p.line( "x", "y_r", source=source, line_width=3, color="seagreen", legend_label="Resistant", ) slider_beta = Slider(start=0.0, end=1, value=0.8, step=0.1, title="\u03B2",) slider_gamma = Slider(start=0.0, end=1, value=0.1, step=0.1, title="\u03B3") slider_sigma = Slider(start=0.0, end=1, value=0.5, step=0.1, title="\u03C3") slider_mu = Slider(start=0.0, end=1, value=0.0, step=0.1, title="\u03BC") slider_nu = Slider(start=0.0, end=1, value=0.0, step=0.1, title="\u03BD") slider_s = Slider(start=0, end=100, value=10, step=1, title="N(Susceptible)") slider_e = Slider(start=0, end=100, value=1, step=1, title="N(Exposed)") slider_i = Slider(start=0, end=100, value=0, step=1, title="N(Infected)") slider_r = Slider(start=0, end=100, value=0, step=1, title="N(Recovered)") slider_t = Slider(start=0, end=100, value=30, step=1, title="Duration (days)") def callback_beta(attr, old, new): sol = solve_seir_model(new, gamma, sigma, mu, nu, y0, t_span) source.data["x"] = sol.t source.data["y_s"] = sol.y[0] source.data["y_e"] = sol.y[1] source.data["y_i"] = sol.y[2] source.data["y_r"] = sol.y[3] def callback_gamma(attr, old, new): sol = solve_seir_model(beta, new, sigma, mu, nu, y0, t_span) source.data["x"] = sol.t source.data["y_s"] = sol.y[0] source.data["y_e"] = sol.y[1] source.data["y_i"] = sol.y[2] source.data["y_r"] = sol.y[3] def callback_sigma(attr, old, new): sol = solve_seir_model(beta, gamma, new, mu, nu, y0, t_span) source.data["x"] = sol.t source.data["y_s"] = sol.y[0] source.data["y_e"] = sol.y[1] source.data["y_i"] = sol.y[2] source.data["y_r"] = sol.y[3] def callback_mu(attr, old, new): sol = solve_seir_model(beta, gamma, sigma, new, nu, y0, t_span) source.data["x"] = sol.t source.data["y_s"] = sol.y[0] source.data["y_e"] = sol.y[1] source.data["y_i"] = sol.y[2] source.data["y_r"] = sol.y[3] def callback_nu(attr, old, new): sol = solve_seir_model(beta, gamma, sigma, mu, new, y0, t_span) source.data["x"] = sol.t source.data["y_s"] = sol.y[0] source.data["y_e"] = sol.y[1] source.data["y_i"] = sol.y[2] source.data["y_r"] = sol.y[3] def callback_s(attr, old, new): y0[0] = new sol = solve_seir_model(beta, gamma, sigma, mu, nu, y0, t_span) source.data["x"] = sol.t source.data["y_s"] = sol.y[0] source.data["y_e"] = sol.y[1] source.data["y_i"] = sol.y[2] source.data["y_r"] = sol.y[3] def callback_e(attr, old, new): y0[1] = new sol = solve_seir_model(beta, gamma, sigma, mu, nu, y0, t_span) source.data["x"] = sol.t source.data["y_s"] = sol.y[0] source.data["y_e"] = sol.y[1] source.data["y_i"] = sol.y[2] source.data["y_r"] = sol.y[3] def callback_i(attr, old, new): y0[2] = new sol = solve_seir_model(beta, gamma, sigma, mu, nu, y0, t_span) source.data["x"] = sol.t source.data["y_s"] = sol.y[0] source.data["y_e"] = sol.y[1] source.data["y_i"] = sol.y[2] source.data["y_r"] = sol.y[3] def callback_r(attr, old, new): y0[3] = new sol = solve_seir_model(beta, gamma, sigma, mu, nu, y0, t_span) source.data["x"] = sol.t source.data["y_s"] = sol.y[0] source.data["y_e"] = sol.y[1] source.data["y_i"] = sol.y[2] source.data["y_r"] = sol.y[3] def callback_t(attr, old, new): t_span[1] = new sol = solve_seir_model(beta, gamma, sigma, mu, nu, y0, t_span) source.data["x"] = sol.t source.data["y_s"] = sol.y[0] source.data["y_e"] = sol.y[1] source.data["y_i"] = sol.y[2] source.data["y_r"] = sol.y[3] slider_beta.on_change("value", callback_beta) slider_gamma.on_change("value", callback_gamma) slider_sigma.on_change("value", callback_sigma) slider_mu.on_change("value", callback_mu) slider_nu.on_change("value", callback_nu) slider_s.on_change("value", callback_s) slider_e.on_change("value", callback_e) slider_i.on_change("value", callback_i) slider_r.on_change("value", callback_r) slider_t.on_change("value", callback_t) # draw_plot() sliders_params = column( slider_beta, slider_gamma, slider_sigma, slider_mu, slider_nu ) sliders_inits = column(slider_s, slider_e, slider_i, slider_r, slider_t) layout = column(p, row(sliders_params, sliders_inits),) curdoc().add_root(layout)
decimation = int(current_window_size / decimation_factor) if decimation > 1: t = np.linspace(0.0, current_window_size / sample_rate, current_window_size / decimation) * 1e3 # in ms else: t = np.linspace(0.0, current_window_size / sample_rate, current_window_size) * 1e3 # in ms timeI_line.data_source.data['x'] = t timeQ_line.data_source.data['x'] = t process_samples() # reprocess since we changed the window size # position slider position_slider = Slider(start=0, end=(total_samples - current_window_size), value=0, step=100, title="Start Sample") #FIXME end is not correct position_slider.on_change('value', position_callback) # center_freq TextInput window_size_input = TextInput(value=str(current_window_size), title="Window Size") # FIXME add limits window_size_input.on_change('value', window_size_callback) # add the widgets to the document curdoc().add_root( widgetbox(position_slider, window_size_input )) # widgetbox() makes them a bit tighter grouped than column() # assemble the plots the way we like to, and add to document
# Define the callback function: update_plot def update_plot(attr, old, new): # set the `yr` name to `slider.value` and `source.data = new_data` yr = slider.value new_data = { 'x' : data.loc[yr].fertility, 'y' : data.loc[yr].life, 'country' : data.loc[yr].Country, 'pop' : (data.loc[yr].population / 20000000) + 2, 'region' : data.loc[yr].region, } source.data = new_data # Make a slider object: slider slider = Slider(start=1970,end=2010,step=1,value=1970,title="Year") # Attach the callback to the 'value' property of slider slider.on_change("value",update_plot) # Make a row layout of widgetbox(slider) and plot and add it to the current document layout = row(widgetbox(slider), plot) curdoc().add_root(layout) -------------------------------------------------- # Exercise_5 # Define the callback function: update_plot def update_plot(attr, old, new): # Assign the value of the slider: yr yr = slider.value # Set new_data
from bokeh.plotting import figure import numpy as np doc = curdoc() x = np.linspace(0, 2, 1000) y = 1 - (x-1)**2 source = ColumnDataSource(data=dict(x=x, y=y)) p = figure(title="initial title") p.circle(x=1, y=list(range(0, 11))) p.line('x', 'y', color="orange", source=source) slider = Slider(start=0, end=10, step=0.1, value=1) def scb(attr, old, new): source.data['y'] = new * y slider.on_change('value', scb) combine = Button(label="hold combine") combine.on_event(ButtonClick, lambda event: doc.hold("combine")) collect = Button(label="hold collect") collect.on_event(ButtonClick, lambda event: doc.hold("collect")) unhold = Button(label="unhold") unhold.on_event(ButtonClick, lambda event: doc.unhold()) doc.add_root(column(p, slider, combine, collect, unhold))
# p.String in the JS implementation. Where the JS type system is not yet # as rich, you can use p.Any as a "wildcard" property type. @define { text: [ p.String ] slider: [ p.Any ] } """ class Custom(LayoutDOM): __implementation__ = CODE text = String(default="Custom text") slider = Instance(Slider) from bokeh.io import show from bokeh.layouts import column from bokeh.models import Slider slider = Slider(start=0, end=10, step=0.1, value=0, title="value") custom = Custom(text="Special Slider Display", slider=slider) layout = column(slider, custom) show(layout)
h = h_slider.value k = k_slider.value updata_analytical_solution() update_mesh(h, k) # initialize data source plot_data_num = ColumnDataSource(data=dict(x=[], u=[])) plot_data_ana = ColumnDataSource(data=dict(x=[],u=[])) mesh_data = ColumnDataSource(data=dict()) pde_specs = ColumnDataSource(data=dict(h=[], k=[])) ana_sol = ColumnDataSource(data=dict()) # initialize controls # slider for going though time time_slider = Slider(title="time", name='time', value=pde_settings.t_init, start=pde_settings.t_min, end=pde_settings.t_max, step=pde_settings.t_step) time_slider.on_change('value', time_change) # slider controlling spatial stepsize of the solver h_slider = Slider(title="spatial meshwidth", name='spatial meshwidth', value=pde_settings.h_init, start=pde_settings.h_min, end=pde_settings.h_max, step=pde_settings.h_step) h_slider.on_change('value', mesh_change) # slider controlling spatial stepsize of the solver k_slider = Slider(title="temporal meshwidth", name='temporal meshwidth', value=pde_settings.k_init, start=pde_settings.k_min, end=pde_settings.k_max, step=pde_settings.k_step) k_slider.on_change('value', mesh_change) # radiobuttons controlling pde type pde_type = RadioButtonGroup(labels=['Heat', 'Wave'], active=0) pde_type.on_change('active', pde_type_change) # radiobuttons controlling solver type solver_type = RadioButtonGroup(labels=['Explicit', 'Implicit'], active=0) solver_type.on_change('active', mesh_change)
source_convolution = ColumnDataSource(data=dict(x=[], y=[])) source_xmarker = ColumnDataSource(data=dict(x=[], y=[])) source_overlay = ColumnDataSource(data=dict(x=[], y=[], y_neg=[], y_pos=[])) # initialize properties update_is_enabled = True # initialize controls # dropdown menu for sample functions function_type = Dropdown(label="choose a sample function pair or enter one below", menu=convolution_settings.sample_function_names) function_type.on_click(function_pair_input_change) # slider controlling the evaluated x value of the convolved function x_value_input = Slider(title="x value", name='x value', value=convolution_settings.x_value_init, start=convolution_settings.x_value_min, end=convolution_settings.x_value_max, step=convolution_settings.x_value_step) x_value_input.on_change('value', input_change) # text input for the first function to be convolved function1_input = TextInput(value=convolution_settings.function1_input_init, title="my first function:") function1_input.on_change('value', input_change) # text input for the second function to be convolved function2_input = TextInput(value=convolution_settings.function1_input_init, title="my second function:") function2_input.on_change('value', input_change) # initialize plot toolset = "crosshair,pan,reset,resize,save,wheel_zoom" # Generate a figure container plot = Figure(plot_height=400, plot_width=400, tools=toolset, title="Convolution of two functions", x_range=[convolution_settings.x_min_view, convolution_settings.x_max_view],
source = ColumnDataSource(data={'t': t, 'i': ib, 'uc': uc2, 'usupp': ub}) p=figure(plot_width=600, plot_height=400, title='Current in RLC circuit') p.line('t', 'i', source=source) p.xaxis.axis_label='Time [s]' p.yaxis.axis_label='Current [A]' m=figure(plot_width=600, plot_height=400, title='Voltages') m.line('t', 'usupp', source=source, legend='Line voltage', color='orange') m.line('t', 'uc', source=source, legend='Capacitor voltage', color='green') m.xaxis.axis_label='Time [s]' m.yaxis.axis_label='Voltage[V]' m.legend.location = "bottom_left" # widgets Slider_C = Slider(start=0.0001, end=0.01, value=0.01, step=.00001, title="Capacitance [F]") Slider_R = Slider(start=1, end=50, value=5, step=1, title="Resistance [Ohm]") Slider_L = Slider(start=0.001, end=1, value=0.1, step=0.001, title="Inductance [H]") #Slider_Uo = Slider(start=10e3, end=100e3, value=20e3, step=10e3, title="Charging voltage [V]") layout = row(widgetbox(Slider_C, Slider_R, Slider_L), column(p,m)) def callback(attr, old, new): new_C = Slider_C.value new_R = Slider_R.value new_L = Slider_L.value ib, uc2, ub = calRLCcir(R=new_R, L=new_L, C=new_C, alpha=0) source.data = {'t': t, 'i': ib, 'uc': uc2, 'usupp': ub} Slider_C.on_change('value', callback) Slider_R.on_change('value', callback)
def plotfits(dirname): session.modifeid = True session['pathname'] = app.config['UPLOAD_FOLDER']+'/'+dirname+'/' session['stats'] = {} session['date'] = {} # pegar a data para converter em juliana e inserir nas análises with open(session['pathname']+'data.json') as f: dirdata = json.load(f) r = dirdata['r'] session['r'] = r celestial = False # Faz logo algumas estatísticas da imagem for fil in BANDAS: for fname in dirdata[fil]: img, header = fits.getdata(session['pathname']+fname, header=True) session['stats'][fil+':'+fname] = sigma_clipped_stats(img,sigma=3.0) if not celestial: celestial = WCS(header).has_celestial session['wcs'] = session['pathname']+fname session['date'][fil+':'+fname] = Time(header['DATE-OBS']).jd # a data de observação de cada imagem # Abrindo coordenadas se salvas try: cordata = pd.read_excel(session['pathname']+'data.xlsx') # Dados que serão usados para fazer computação e visualizar os pontos source = ColumnDataSource(cordata) print('Coordenadas carregadas.') except FileNotFoundError: print('Não há coordenadas salvas em %s' % session['pathname']) # Dados que serão usados para fazer computação e visualizar os pontos source = ColumnDataSource(dict( ra=[], dec=[], x=[], y=[], flux = [], j = [], k = [], tipo=[], # se é obj, src ou sky banda=[], # o filtro da imagem e arquivo sid=[], # id da estrela copiada colors=[], # para colorir de acordo o tipo de objeto )) # Constrói a tabaela de table que poderá ser usada para designar as posições do objeto, estrela e céu tabela = DataTable(source=source,columns=[ TableColumn(field='x',title='x'), TableColumn(field='y',title='y'), TableColumn(field='ra',title='ra'), TableColumn(field='dec',title='dec'), TableColumn(field='j',title='j'), TableColumn(field='k',title='k'), TableColumn(field='flux',title='flux'), TableColumn(field='tipo',title='tipo'), TableColumn(field='banda',title='banda'), TableColumn(field='sid',title='sid') ], editable=True) P = [] # lista de gráficos para o plot Nimg = [] # lista de imagens normalizadas para o contraste for fil in BANDAS: for fname in dirdata[fil]: img = fits.getdata(session['pathname']+fname) stretch = HistEqStretch(img) # Histograma, melhor função para granular a imagem h,w = img.shape # número de linhas e colunas da matriz da imagem nimg = stretch(normal(img)).tolist() p = figure(plot_width=700, active_scroll='wheel_zoom') p.image(image=[nimg], x=0, y=0, dw=w, dh=h, palette='Greys256', level="image") p.x_range.range_padding = p.y_range.range_padding = 0 p.grid.grid_line_width = 0 view = CDSView(source=source,filters=[GroupFilter(column_name='banda', group=fil+':'+fname)]) c = p.circle('x','y', source=source, view=view, color='colors', fill_color=None, radius=r, line_width=2) cd = p.circle_dot('x','y', source=source, view=view, color='colors', size=2) tool = PointDrawTool(renderers=[c,cd],empty_value='na') p.add_tools(tool) p.toolbar.active_tap = tool p.toolbar.active_inspect = None tab = Panel(child=p, title=fil+':'+fname) P.append(tab) Nimg.append(nimg) graficos = Tabs(tabs=P) graficos.js_on_change('active', CustomJS(code=''' tabs_onchange(cb_obj); ''')) contrast = Slider(start=-1, end=6, value=1, step=0.05, title="Contraste") contrast.js_on_change('value',CustomJS(args = dict(tabs=graficos.tabs, im=Nimg), code = ''' contrast_onchange(cb_obj,tabs,im); ''')) # Selecionar o tipo de fonte luminosa: obj, src ou sky radio_title = Paragraph(text='Escolha o tipo:') LABELS = ['obj','src','sky'] radio_group = RadioGroup(labels=LABELS, active=0) # Evento de mudança da tabela de table, para inserir table padrão nas colunas inalteradas source.js_on_change('data', CustomJS(args=dict(radio=radio_group, graficos=graficos), code=''' source_onchange(cb_obj, radio, graficos); ''')) # Muda o raio da abertura fotométrica spinner = Spinner(title="Raio", low=1, high=40, step=0.5, value=r, width=80) spinner.js_on_change('value', CustomJS(args=dict(source=source, tabs=graficos.tabs), code=''' radius_onchange(cb_obj,source,tabs); ''')) # Coluna de requisição text1 = Div(text='<b>Instruções:</b><p>1. Digite a chave do Astrometry.net') apikey_input = TextInput(title='Apikey do Astrometry.net', placeholder='digite a chave aqui') text2 = Div(text='''<p>2. Selecione qual imagem será usada como referência para o astrometry.net e para o cálculo das coordenadas celestes</p>''') seletor = Select(title='Escolha a imagem de referência', options=[*session['stats'].keys()]) text3 = Div(text='3. Clique abaixo pra requisitar a correção WCS') send_astrometry = Toggle(label='Solução de placa do astrometry.net', disabled=celestial) send_astrometry.js_on_click(CustomJS(args=dict(key=apikey_input, source=source, selected=seletor), code=''' send_astrometry(cb_obj,key,source,selected); ''')) # o Botão de salvar irá enviar um json para o servidor que irá ler e fazer os procedimentos posteriores text4 = Div(text='4. Salve a tabela de table clicando em salvar.') salvar = Button(label='Salvar tabela', button_type="success") salvar.js_on_click(CustomJS(args=dict(source=source), code=''' salvar_onclick(source); ''')) reset = Button(label='Limpar', button_type='success') reset.js_on_click(CustomJS(args=dict(source=source), code=''' reset_onclick(source); ''')) copiar = Button(label='Copiar coordenadas', button_type='success') copiar.js_on_click(CustomJS(args=dict(source=source, ref=seletor, active=graficos), code=''' add_data(source,ref,active); ''')) div, script = components(row(column(contrast,spinner,radio_title,radio_group),\ column(row(reset,copiar,salvar), graficos, tabela, sizing_mode='stretch_both'), column(text1,apikey_input,text2,seletor,text3,send_astrometry,text4))) return render_template('plot.html', the_div=div, the_script=script,filename=dirdata['name'])
#Plotting part source = ColumnDataSource(data={'t': t, 'ia': ia, 'iadc': iadc, 'iau': iau}) plot = Figure(plot_width=800, plot_height=400, title = "Influence of a voltage closing angle on the current in a R-L circuit") plot.title.text_font_size = '12pt' plot.xaxis.axis_label="Time [s]" plot.xaxis.axis_label_text_font_size = '10pt' plot.yaxis.axis_label="Current [A]" plot.yaxis.axis_label_text_font_size = '10pt' plot.line('t', 'ia', source=source, line_width=3, line_alpha=0.6, legend="Circuit current") plot.line('t', 'iadc', source=source, line_width=2, line_alpha=0.6, color="orange", legend="DC component") plot.line('t', 'iau', source=source, line_width=2, line_alpha=0.6, color="green", legend="AC component") # slider slider = Slider(start=0, end=phi, value=0, step=.1, title="Voltage closing angle [rad]", name="slider") #callback part def callback(attr, old, new): new_alpha = slider.value #Current response ia = [(sqrt(2)*u/(sqrt(R**2+XL**2))*(sin(omega*k+new_alpha-phi)-sin(new_alpha-phi)*exp(-R/L*k))) for k in t] #DC component of the current iadc = [(sqrt(2)*u/(sqrt(R**2+XL**2))*-sin(new_alpha-phi)*(exp(-R/L*k))) for k in t] #AC steady state current iau = [(sqrt(2)*u/(sqrt(R**2+XL**2))*sin(omega*k+new_alpha-phi)) for k in t] # source data update
def bkapp(self, doc): basePath = self.basePath npyPath = self.npyPath covMapDict = self.covMapDict self.logger.debug('basePath: ' + str(basePath)) self.logger.debug('npyPath: ' + str(npyPath)) self.logger.debug('covMapDict: ' + str(covMapDict)) # Retrieving Data #----------------------------------------------------------------- # Loading in data curPath = os.getcwd() # Loading distance difference matrices self.logger.info('Reading npy matrices from: ' + str(npyPath)) npyNameList = [npyFile for npyFile in os.listdir(npyPath) \ if (npyFile[-3:] == 'npy') \ and ('Minus' in npyFile) \ and ('Scaled' not in npyFile)] self.logger.debug('npyNameList: ' + str(npyNameList)) npyList = [None] * len(npyNameList) for i, npyName in enumerate(npyNameList): npyList[i] = np.load(os.path.join(npyPath, npyName)) self.logger.debug('npyList: ' + str(npyList)) # Loading and defining dictionaries to map to and fro residue pairs to # the corresponding submatrices invCovMapDict = {str(value): key for key, value in covMapDict.items()} # Loading Covariance Matrix and helper class to split submatrices self.logger.info('Loading CovarianceMatrix.npy') covarianceMatrix = np.load(os.path.join(basePath, \ 'CovarianceMatrix.npy')) self.covSize = covarianceMatrix.shape[0] self.logger.info('Loaded CovarianceMatrix.npy') cSubmatrix = CovSubmatrix() #----------------------------------------------------------------- # Interactive Plot Tools TOOLS = 'hover,save,pan,box_zoom,reset,wheel_zoom' # Defining color values vmin = -5 vmax = 5 # New Color Map Bokeh blueRedColors = [ '#FF0000', '#FF1111', '#FF2222', '#FF3333', '#FF4444', '#FF5555', '#FF6666', '#FF7777', '#FF8888', '#FF9999', '#FFAAAA', '#FFBBBB', '#FFCCCC', '#FFDDDD', '#FFEEEE', '#FFFFFF', '#EEEEFF', '#DDDDFF', '#CCCCFF', '#BBBBFF', '#AAAAFF', '#9999FF', '#8888FF', '#7777FF', '#6666FF', '#5555FF', '#4444FF', '#3333FF', '#2222FF', '#1111FF', '#0000FF' ] # Creating list axesXMax = npyList[0].shape[0] if int(self.scale) != int(npyList[0].shape[0]): axesXMax = self.scale axesYMax = npyList[0].shape[1] if int(self.scale) != int(npyList[0].shape[1]): axesYMax = self.scale xyPairList = [None] * axesXMax * axesYMax for i in range(0, axesXMax): for j in range(0, axesYMax): xyPairList[i + j * axesXMax] = (i + 1, j + 1) self.logger.debug('xyPairList: ' + str(xyPairList)) self.logger.debug('type: xyPairList: ' + str(type(xyPairList))) # Reshaping source values in order to shift indices from starting # with 0 to starting with 1 xVals = np.transpose(xyPairList)[0] yVals = np.transpose(xyPairList)[1] covVals = npyList[0].flatten() self.logger.debug('npyList: ' + str(npyList)) self.logger.debug('covVals: ' + str(covVals)) # Checks to see if the specified scale matches axesLength = int(np.sqrt(len(covVals))) self.indexDict = None self.scaledRangeDict = None if axesLength != int(self.scale): axesLength = self.scale newMatrix, self.indexDict = self.rescaleMatrix(covVals, self.scale) covVals = newMatrix.flatten() # Creating a dictionary mapping the new indices to # strings describing the ranges of the original indices if self.indexDict is not None: self.scaledRangeDict = self.serializeIndexDict(self.indexDict) # Saving the scaled index mapping to file indexDictFilepath = os.path.join(basePath, 'scaledIndexMap.npy') np.save(indexDictFilepath, self.indexDict, allow_pickle=True) self.logger.info('Saving the scaled index mapping to: ' \ + str(indexDictFilepath)) self.logger.debug('scaledRangeDict: ' + str(self.scaledRangeDict)) # Defining fields to be displayed in hover tooltips source = ColumnDataSource( data={ 'x': xVals.flatten(), 'y': yVals.flatten(), 'covValues': covVals.flatten() }) tooltipList = [('xCoord', '@x'), ('yCoord', '@y'), ('Magnitude', '@covValues')] # Defining color map color_mapper = LinearColorMapper(palette=blueRedColors, low=vmin, high=vmax) color_bar = ColorBar(color_mapper=color_mapper, label_standoff=12, border_line_color=None, location=(0,0), ticker=BasicTicker(\ desired_num_ticks=len(blueRedColors))) # Plotting self.logger.info('Determining axis scaling.') if self.scaledRangeDict is not None: plotLabel = FactorRange( factors=[i for i in self.scaledRangeDict.values()], bounds=(0.5, len(self.scaledRangeDict.keys()) + 0.5), factor_padding=0.0, range_padding_units="percent", range_padding=0) else: plotLabel = FactorRange( factors=[str(int(i+1)) \ for i in range(axesLength)], bounds=(0.5, axesLength + 0.5)) self.logger.info('Creating initial figure') # Primary display for directly interacting with the matrices plot = figure(x_range=plotLabel, y_range=plotLabel, tools=TOOLS, toolbar_location='below', tooltips=tooltipList) plot.add_tools(EnhanceTool()) plot.xaxis.major_label_orientation = math.pi / 2 self.logger.info('Creating initial primary plot') plot.rect(x='x', y='y', width=1, height=1, source=source, fill_color={ 'field': 'covValues', 'transform': color_mapper }, line_color=None) plot.title = Title(text='Distance Difference Matrix: ' \ + npyNameList[0], \ align='center') plot.add_layout(color_bar, 'right') # Secondary display for interacting with queued covariance submatrices plot2 = figure(x_range=plotLabel, y_range=plotLabel, tools=TOOLS, toolbar_location='below', tooltips=tooltipList) plot2.add_tools(EnhanceTool()) plot2.xaxis.major_label_orientation = math.pi / 2 source2 = ColumnDataSource( data={ 'x': xVals.flatten(), 'y': yVals.flatten(), 'covValues': [0 for i in covVals.flatten()] }) self.logger.info('Creating initial secondary plot') plot2.rect(x='x', y='y', width=1, height=1, source=source2, fill_color={ 'field': 'covValues', 'transform': color_mapper }, line_color=None) plot2.title = Title(text='Queued Covariance Submatrices', align='center') plot2.add_layout(color_bar, 'right') # Creating a dictionary of distance difference matrices based off of # order they are loaded in self.logger.debug('Creating distance difference matrix mapping') matrixDict = {} for i, npy in enumerate(npyList): if i not in matrixDict.keys(): matrixDict[str(i)] = npyList[i].flatten() # Python Callbacks # ------------------------------------------------------------------ # Takes a flattened matrix and updates the plot to its values def patchMatrixValues(newMatrix, source=source): if (int(self.scale) \ != int(math.ceil(math.sqrt(newMatrix.shape[0])))): newMatrix, indexDict = self.rescaleMatrix( newMatrix, self.scale) newMatrix = newMatrix.flatten() patch_id = [i for i in range(len(source.data['covValues']))] patch = newMatrix source.patch({'covValues': list(zip(patch_id, patch))}) # Slider Callback # Changes the distance difference matrix displayed based off of the index # that the slider is set to def sliderCallback(attr, old, new): plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] f = str(new) covValues = source.data['covValues'] axesLength = math.sqrt(len(covValues)) patchMatrixValues(matrixDict[f]) plot.title.text = 'Distance Difference Matrix: ' + npyNameList[new] # Click callback for moving from distance difference matrices to # covariance submatrices def clickCallback(event): plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] start_time = time.time() axesLength = math.sqrt(len(source.data['covValues'])) xCoord = math.floor(event.x - 0.5) yCoord = math.floor(event.y - 0.5) # Only accessing covariance submatrix if the click is not along # the diagonal if ((xCoord != yCoord) and (xCoord >= 0) and (xCoord < axesLength + 1) and (yCoord >= 0) and (yCoord < axesLength + 1)): # Handles coordinates "mirrored" across the diagonal if (xCoord > yCoord): temp = xCoord xCoord = yCoord yCoord = temp coordString = '(' + str(xCoord) + ', ' + str(yCoord) + ')' # Handles submatrix access for non-scaled indices subMatrix = None if self.indexDict is None: covIndex = invCovMapDict[coordString] resPairString = '[' + coordString + ']' subMatrix = cSubmatrix.generateSubmatrix( covarianceMatrix, covMapDict, residuePairList=resPairString, allResidues=False, baseDirectory=None).flatten() self.logger.debug('Submatrix for x=' + str(xCoord) \ + ', y=' + str(yCoord) + ': ' \ + str(subMatrix)) # Handles submatrix access for scaled/mapped indices/ranges else: resPairString = '' for xIndex in self.indexDict[xCoord]: for yIndex in self.indexDict[yCoord]: if len(resPairString) > 0: resPairString += ',' resPairString += '(' + str(xIndex) \ + ', ' + str(yIndex) + ')' resPairString = '[' + resPairString + ']' if self.queueState == False: subMatrixList = cSubmatrix.generateSubmatrix( covarianceMatrix, covMapDict, residuePairList=resPairString, allResidues=False, baseDirectory=None, scale=self.scale) subMatrixArray = np.array(subMatrixList) # Multiple submatrices case, takes the average of # given submatrices if len(subMatrixArray.shape) >= 3: subMatrix = np.average(subMatrixArray, axis=0) else: subMatrix = subMatrixList else: self.logger.debug('Appending ' + str(resPairString) \ + ' to queueList') self.queueList.append([ int(xCoord + 1), int(yCoord + 1), str(resPairString) ]) toQueueDiv.text += ' (' + str(xCoord+1) + ','\ + str(yCoord+1)+'),' if self.queueState == False: patchMatrixValues(subMatrix) # Changing plot title name to reflect the covariance pair # with which the covariance submatrix is plotted in respect to xCoord += 1 yCoord += 1 displayString = '(' + str(xCoord) + ', ' + str( yCoord) + ')' plot.title.text = 'Covariance Submatrix: Residue Pair: ' \ + displayString # TODO: When speed comparisons are done, remove the time printouts print('Time to compute submatrix: ' + str(time.time() - start_time)) # Distance Difference Matrix Display Callback # Shows current distance difference matrix if not already shown def ddCallback(event): plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] f = str(slider.value) patchMatrixValues(matrixDict[f]) plot.title.text = 'Distance Difference Matrix: ' \ + npyNameList[int(f)] # Reset Button Callback # Resets display to the 0th index distance difference matrix def resetCallback(event): plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] slider.value = 0 f = str(slider.value) patchMatrixValues(matrixDict[f]) plot.title.text = 'Distance Difference Matrix: ' \ + npyNameList[0] # Forward Button Callback # Moves DD Index forward by 1 and displays DD matrix def forwardCallback(event): plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] if slider.value < len(matrixDict.keys()) - 1: slider.value = slider.value + 1 f = str(slider.value) patchMatrixValues(matrixDict[f]) plot.title.text = 'Distance Difference Matrix: ' \ + npyNameList[int(f)] # Backward Button Callback # Moves DD Index backward by 1 and displays DD matrix def backwardCallback(event): plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] if slider.value > 0: slider.value = slider.value - 1 f = str(slider.value) patchMatrixValues(matrixDict[f]) plot.title.text = 'Distance Difference Matrix: ' + npyNameList[ int(f)] # Forward Queue Callback # Moves down the queue to display the next covariance submatrix def forwardQCallback(event): plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] if ((self.curQueue is None) and (len(self.queueMatrices) == 0)): return elif ((self.curQueue is None) and (len(self.queueMatrices) >= 0)): self.curQueue = 0 patchMatrixValues(self.queueMatrices[self.curQueue], source2) plot2.title.text = 'Queued Covariance Submatrices: '\ + 'Residue Pair: ' \ + self.queueNameList[self.curQueue] indexDiv.text = 'Index: ' + str(self.curQueue) elif (self.curQueue >= len(self.queueMatrices)): return elif (self.curQueue < (len(self.queueMatrices) - 1)): self.curQueue += 1 print('Acessing curQueue: ' + str(self.curQueue)) print('len(self.queueMatrices): ' + str(len(self.queueMatrices))) patchMatrixValues(self.queueMatrices[self.curQueue], source2) plot2.title.text = 'Queued Covariance Submatrices: '\ + 'Residue Pair: ' \ + self.queueNameList[self.curQueue] indexDiv.text = 'Index: ' + str(self.curQueue) # Backward Queue Callback # Moves up the queue to display the previous covariance submatrix def backwardQCallback(event): plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] plot.x_range.factors = [ str(i) for i in self.scaledRangeDict.values() ] if ((self.curQueue is None) and (len(self.queueMatrices) == 0)): return elif ((self.curQueue is None) and (len(self.queueMatrices) >= 0)): self.curQueue = 0 patchMatrixValues(self.queueMatrices[self.curQueue], source2) plot2.title.text = 'Queued Covariance Submatrices: '\ + 'Residue Pair: ' \ + self.queueNameList[self.curQueue] indexDiv.text = 'Index: ' + str(self.curQueue) elif (self.curQueue >= len(self.queueMatrices)): return elif (self.curQueue > 0): self.curQueue -= 1 self.logger.debug('Accessing curQueue: ' + str(self.curQueue)) self.logger.debug('len(self.queueMatrices): ' \ + str(len(self.queueMatrices))) patchMatrixValues(self.queueMatrices[self.curQueue], source2) plot2.title.text = 'Queued Covariance Submatrices: '\ + 'Residue Pair: ' \ + self.queueNameList[self.curQueue] indexDiv.text = 'Index: ' + str(self.curQueue) # Queue Button Callback # Toggles queueing mode for residue pairs/ranges def queueCallback(event): # Turning on queuing if self.queueState == False: self.queueState = True toQueueDiv.text = 'Queued Covariance Submatrices:' statusDiv.text = 'Status: Queuing residue pairs' # Turning off queuing and then patching the covariance submatrices # to secondary plot else: self.queueState = False qList = self.queueList self.queueList = [] # TODO: Bokeh doesn't update display until after loop runs statusDiv.text = 'Status: Computing covariance submatrices' for matrixPak in qList: xCoord = int(matrixPak[0]) yCoord = int(matrixPak[1]) resPairString = str(matrixPak[2]) subMatrixArray = np.array( cSubmatrix.generateSubmatrix( covarianceMatrix, covMapDict, residuePairList=resPairString, allResidues=False, baseDirectory=None, scale=self.scale)) # Multiple submatrices case, takes the average of # given submatrices if len(subMatrixArray.shape) >= 3: subMatrix = np.average(subMatrixArray, axis=0) else: subMatrix = subMatrixList self.queueMatrices.append(subMatrix) patchMatrixValues(subMatrix, source2) # Changing plot title name to reflect the covariance pair # with which the covariance submatrix is plotted in respect # to xCoord += 1 yCoord += 1 displayString = '(' + str(xCoord) + ', ' + str( yCoord) + ')' self.queueNameList.append(displayString) plot2.title.text = 'Queued Covariance Submatrix: ' \ + 'Residue Pair: ' \ + displayString computedDiv.text = 'Computed Submatrices: ' \ + str(sorted(set(self.queueNameList))) totalNumberDiv.text = '/' + str(len(self.queueMatrices)) statusDiv.text = 'Status: Submatrix computation complete. Idling' # "Enhances" the selected region by taking the range of residues and # redisplays the plot so it shows only this range of residues at the # given resolution def zoomSelectCallback(event, matrixType="dd"): geometry = event.geometry f = str(slider.value) # Retrieving the boundaries of the rectangular selection # The -0.5 offset accounts for the offset of each square from # the original axis x0 = math.floor(geometry['x0'] - 0.5) x1 = math.floor(geometry['x1'] - 0.5) y0 = math.floor(geometry['y0'] - 0.5) y1 = math.floor(geometry['y1'] - 0.5) # Retrieving the boundaries of the current matrix # (in terms of currently displayed coordinates) sourceDF = source.to_df() xi = min(sourceDF['x']) xf = max(sourceDF['x']) yi = min(sourceDF['y']) yf = max(sourceDF['y']) width = x1 - x0 height = y1 - y0 # Use these values to get information about what scale # the matrix is and is going to be # self.scale # self.covSize -> need to find size for distance difference # matrices and make a separate case for them? # Also need to figure out how to deal with asymmetric boundaries # where width/height are not equal # binSize - the number of units in a given bin axesSize = int(math.sqrt(len(list(matrixDict.values())[0]))) if ((matrixType == "dd") or (matrixType is None)): matrix = matrixDict[str(slider.value)].reshape( axesSize, axesSize) elif (matrixType == "covMatrix"): indexDiv = int(self.curQueue) matrix = self.queueMatrices[indexDiv].reshape( axesSize, axesSize) binSize = int(math.ceil(axesSize / self.scale)) if ((x0 + max(width, height)) <= axesSize / binSize): xUpperBound = x0 + max(width, height) xLowerBound = x0 else: if ((x1 - max(width, height)) >= 0): xUpperBound = x1 xLowerBound = x1 - max(width, height) else: xUpperBound = int(axesSize / binSize) xLowerBound = int(axesSize / binSize - x1) if ((y0 + max(width, height)) <= axesSize / binSize): yUpperBound = y0 + max(width, height) yLowerBound = y0 else: if ((y1 - max(width, height)) >= 0): yUpperBound = y1 yLowerBound = y1 - max(width, height) else: yUpperBound = int(axesSize / binSize) yLowerBound = int(axesSize / binSize - y1) if ((xUpperBound - xLowerBound) > (yUpperBound - yLowerBound)): yUpperBound = xUpperBound yLowerBound = xLowerBound if ((xUpperBound - xLowerBound) < (yUpperBound - yLowerBound)): xUpperBound = yUpperBound xLowerBound = yLowerBound zoomedMatrix = matrix[xLowerBound * binSize:xUpperBound * binSize, yLowerBound * binSize:yUpperBound * binSize] # Modifying axes labels to reflect the zoomedMatrix # Parsing the boundaries to determine the raw index range xIndexMax = int(self.scaledRangeDict[xUpperBound].split('-')[1]) xIndexMin = int(self.scaledRangeDict[xLowerBound].split('-')[0]) yIndexMax = int(self.scaledRangeDict[yUpperBound].split('-')[1]) yIndexMin = int(self.scaledRangeDict[yLowerBound].split('-')[0]) # Partitioning the elements into self.scale number of bins numElements = xIndexMax - xIndexMin xIndexDict = self.partitionIndices(numElements, self.scale, offset=xIndexMin) yIndexDict = self.partitionIndices(numElements, self.scale, offset=yIndexMin) xRangeDict = self.serializeIndexDict(xIndexDict) yRangeDict = self.serializeIndexDict(yIndexDict) plot.x_range.factors = [i for i in xRangeDict.values()] plot.y_range.factors = [i for i in yRangeDict.values()] zoomedMatrix = zoomedMatrix.flatten() patchMatrixValues(zoomedMatrix, source) # ------------------------------------------------------------------ # Creating buttons and linking them to their corresponding callbacks # Buttons to navigate distance difference matrices buttonBack = Button(label="Back", button_type="success") buttonBack.on_event(ButtonClick, backwardCallback) buttonDD = Button(label="Show Distance Difference", button_type="success") buttonDD.on_event(ButtonClick, ddCallback) buttonForward = Button(label="Forward", button_type="success") buttonForward.on_event(ButtonClick, forwardCallback) buttonBar = row(buttonBack, buttonDD, buttonForward) buttonReset = Button(label="Reset", button_type="success") buttonReset.on_event(ButtonClick, resetCallback) # Slider to also navigate distance difference matrices slider = Slider(start=0, end=len(npyList) - 1, value=0, step=1, title="index") slider.on_change('value', sliderCallback) # Zoom button for distance difference matrices/non-queued # covariance submatrices plot.on_event(SelectionGeometry, zoomSelectCallback) plot2.on_event(SelectionGeometry, zoomSelectCallback) # Creating a layout from plot elements self.queueList = [] self.queueState = False self.curQueue = None self.queueMatrices = [] self.queueNameList = [] plot.on_event('tap', clickCallback) # Queue Buttons queueButton = Button(label="Queue", button_type="success") queueButton.on_event(ButtonClick, queueCallback) qBar = row(queueButton) # Buttons to navigate queued covariance submatrices qButtonBack = Button(label="Back", button_type="success") qButtonBack.on_event(ButtonClick, backwardQCallback) qButtonForward = Button(label="Forward", button_type="success") qButtonForward.on_event(ButtonClick, forwardQCallback) qNavBar = row(qButtonBack, qButtonForward) # Div Widgets to show which submatrix is displayed indexDiv = Div(text="""Index: N/A""", \ width=70, height=25) totalNumberDiv = Div(text="""/0""",\ width=100, height=25) indexDivBar = row(indexDiv, totalNumberDiv) # Div Widget to show which residue pairs are queued toQueueDiv = Div(text="""Queued Covariance Submatrices:""", \ width=600, height=50) # Div Widget to show which residue pairs are computed computedDiv = Div(text="""Computed Submatrices:""", \ width=600, height=50) # Div Widget to show statusDiv = Div(text="""Status: Nothing Queued""", \ width=600, height=25) testTitle = Title(text='Test Title', align='center') layout = row( column(plot, qBar, buttonBar, slider, buttonReset), column(plot2, qNavBar, statusDiv, indexDivBar, toQueueDiv, computedDiv)) # Adding the plot to the server's document server_doc = doc server_doc.add_root(layout) server_doc.title = "Distance Difference App"
full = ColumnDataSource(data={'snr': snr, 'dist': dist}) # Selected data based on snr_cut index = np.array(snr) > float(args['snr_cut']) selected_snr = np.array(snr)[index] selected_dist = np.array(dist)[index] selected = ColumnDataSource(data={'snr': selected_snr, 'dist': selected_dist}) # Configure Bokeh widgets # SNR slider snr_slider = Slider(start=0, end=500, value=float(args['snr_cut']), step=1, title="SNR") # Scatter plot x_axis_label = data['matchedDataset']['snr']['label'] y_axis_label = "{} [{}]".format(data['matchedDataset']['dist']['label'], data['matchedDataset']['dist']['unit']) plot = figure(y_range=(0, 500), y_axis_location='left', x_axis_label=x_axis_label, x_axis_type='log', y_axis_label=y_axis_label) scatter = plot.circle('snr', 'dist', size=5, fill_alpha=0.2, source=full, color='lightgray', line_color=None)
def create_hbar(area, plot_data, y_variables=data.model_vars, y_definition=data.label_def_ordered, y_extra_info=data.label_extra_ordered, div_name="myplot"): values = plot_data.to_numpy() values = values[0] all_data = ColumnDataSource(data=dict({ 'variables': y_variables, 'values': values, 'definition': y_definition, 'variables_extra': y_extra_info })) tooltips = """ <div style="width:200px;"> <div> <span style="font-size: 15px; color:blue">Variable:</span> <span style="font-size: 12px;">@variables_extra</span> </div> <div> <span style="font-size: 15px; color:blue">Percentage:</span> <span style="font-size: 12px;">@values{1.1} %</span> </div> <div> <span style="font-size: 15px; color:blue">Explanation:</span> <span style="font-size: 12px;">@definition</span> </div> </div> """ TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom" plot = figure( plot_height=600, plot_width=800, x_axis_label='Percentage', #y_axis_label = , x_range=(0, 100), y_range=y_variables, tools=TOOLS, tooltips=tooltips) # plot.hbar(left='values', y='variables', right=1, height=0.9, fill_color='red', line_color='black', fill_alpha = 0.75, # hover_fill_alpha = 1.0, hover_fill_color = 'navy', source=all_data) plot.scatter(x='values', y='variables', source=all_data) plot.title.text = "Relevant statistics about " + area part_rent_slider = Slider(start=0, end=100, value=plot_data.loc[:, 'WPARTHUUR_P'].iloc[0], step=1, title="Private rental") corp_rent_slider = Slider(start=0, end=100, value=plot_data.loc[:, 'WCORHUUR_P'].iloc[0], step=1, title="Housing corporation rental") high_rent_slider = Slider(start=0, end=100, value=plot_data.loc[:, 'WHUURHOOG_P'].iloc[0], step=1, title="High rent (> 971 euro)") middle_rent_slider = Slider(start=0, end=100, value=plot_data.loc[:, 'WHUURMIDDEN_P'].iloc[0], step=1, title="Middle high rent (711 - 971 euro)") low_rent_slider = Slider(start=0, end=100, value=plot_data.loc[:, 'WHUURTSLG_P'].iloc[0], step=1, title="Low rent (< 711 euro)") living_space_040 = Slider(start=0, end=100, value=plot_data.loc[:, 'WOPP0040_P'].iloc[0], step=1, title="Living space of 0-40 m2") living_space_4060 = Slider(start=0, end=100, value=plot_data.loc[:, 'WOPP4060_P'].iloc[0], step=1, title="Living space of 40-60 m2") living_space_6080 = Slider(start=0, end=100, value=plot_data.loc[:, 'WOPP6080_P'].iloc[0], step=1, title="Living space of 60-80 m2") living_space_80100 = Slider(start=0, end=100, value=plot_data.loc[:, 'WOPP80100_P'].iloc[0], step=1, title="Living space of 80-100 m2") living_space_100 = Slider(start=0, end=100, value=plot_data.loc[:, 'WOPP100PLUS_P'].iloc[0], step=1, title="Living space of > 100 m2") all_sliders = [ part_rent_slider, corp_rent_slider, high_rent_slider, middle_rent_slider, low_rent_slider, living_space_100, living_space_80100, living_space_6080, living_space_4060, living_space_040 ] callback = CustomJS(args=dict(source=all_data), code=""" var data = source.data; var values = data["values"]; var value = cb_obj.value; var var_text = cb_obj.title; var variable; var value_idx; updatePlot(value, var_text); socket.on('plot_update', function(msg) { value = msg.new_value; variable = msg.variable; value_idx = msg.index; values[value_idx] = value; data.values = values; source.data = data; source.change.emit(); window.onmouseup = function() { updateModel(value, variable); } }); """) for slider in all_sliders: slider.js_on_change('value', callback) layout = row(plot, column(*all_sliders), width=800) plot_json = json_item(layout, div_name) return plot_json
def xrayvis_app(doc): def load_wav_cb(attr, old, new): '''Handle selection of audio file to be loaded.''' if new == '': return global wavname global snd spkr, fname = os.path.split(new) wavname = get_cached_fname( fname, f'https://linguistics.berkeley.edu/phonapps/xray_microbeam_database/{spkr}', spkr) # wavname = new if not wavname.endswith('.wav'): return snd = parselmouth.Sound(wavname) srcdf = pd.DataFrame( dict( seconds=snd.ts().astype(np.float32), ch0=snd.values[0, :].astype(np.float32), )) #! TODO: do file caching phdf = allphdf.loc[allphdf.wavpath == new, :].copy() phdf['t1'] = phdf['t1'].astype(np.float32) wddf = allwddf.loc[allwddf.wavpath == new, :].copy() wddf['t1'] = wddf['t1'].astype(np.float32) uttdiv.text = '<b>Utterance:</b> ' + ' '.join( wddf.word.str.replace('sp', '')).strip() phwddf = pd.merge_asof(phdf[['t1', 'phone']], wddf[['t1', 'word']], on='t1', suffixes=['_ph', '_wd']) # TODO: separate t1_ph and t1_wd columns srcdf = pd.merge_asof(srcdf, phwddf, left_on='seconds', right_on='t1') srcdf[['phone', 'word']] = srcdf[['phone', 'word']].fillna('') srcdf = srcdf.drop('t1', axis='columns') dfs['srcdf'] = srcdf source.data = srcdf tngsource.data = {'x': [], 'y': []} othsource.data = {'x': [], 'y': []} timesource.data = {k: [] for k in timesource.data.keys()} lasttngtimesource.data = {'x': [], 'y': []} lastothtimesource.data = {'x': [], 'y': []} playvisbtn.channels = channels playvisbtn.disabled = False playselbtn.channels = channels playselbtn.disabled = False playvisbtn.fs = snd.sampling_frequency playvisbtn.start = snd.start_time playvisbtn.end = snd.end_time playselbtn.fs = snd.sampling_frequency playselbtn.start = 0.0 playselbtn.end = 0.0 selbox.left = 0.0 selbox.right = 0.0 selbox.visible = False cursor.location = 0.0 cursor.visible = False ch0.visible = True update_sgram() load_artic() set_limits(0.0, srcdf['seconds'].max()) def load_artic(): '''Load articulation data.''' trace.title.text = 'Static trace' traj.title.text = 'Trajectories' tngfile = os.path.splitext(wavname)[0] + '.txy' palfile = os.path.join(os.path.dirname(wavname), 'PAL.DAT') phafile = os.path.join(os.path.dirname(wavname), 'PHA.DAT') tngdf = pd.read_csv(tngfile, sep='\t', names=[ 'sec', 'ULx', 'ULy', 'LLx', 'LLy', 'T1x', 'T1y', 'T2x', 'T2y', 'T3x', 'T3y', 'T4x', 'T4y', 'MIx', 'MIy', 'MMx', 'MMy' ]) # Convert to seconds tngdf['sec'] = tngdf['sec'] / 1e6 tngdf = tngdf.set_index(['sec']) # Convert to mm tngdf[[ 'ULx', 'ULy', 'LLx', 'LLy', 'T1x', 'T1y', 'T2x', 'T2y', 'T3x', 'T3y', 'T4x', 'T4y', 'MIx', 'MIy', 'MMx', 'MMy' ]] = tngdf[[ 'ULx', 'ULy', 'LLx', 'LLy', 'T1x', 'T1y', 'T2x', 'T2y', 'T3x', 'T3y', 'T4x', 'T4y', 'MIx', 'MIy', 'MMx', 'MMy' ]] * 1e-3 # Find global x/y max/min in this recording to set axis limits. # Exclude bad values (1000000 in data file; 1000 mm in scaled dataframe). cmpdf = tngdf[tngdf < badval] xmax = np.max( np.max( cmpdf[['ULx', 'LLx', 'T1x', 'T2x', 'T3x', 'T4x', 'MIx', 'MMx']])) xmin = np.min( np.min( cmpdf[['ULx', 'LLx', 'T1x', 'T2x', 'T3x', 'T4x', 'MIx', 'MMx']])) ymax = np.max( np.max( cmpdf[['ULy', 'LLy', 'T1y', 'T2y', 'T3y', 'T4y', 'MIy', 'MMy']])) ymin = np.min( np.min( cmpdf[['ULy', 'LLy', 'T1y', 'T2y', 'T3y', 'T4y', 'MIy', 'MMy']])) paldf = pd.read_csv(palfile, sep='\s+', header=None, names=['x', 'y']) paldf = paldf * 1e-3 palsource.data = {'x': paldf['x'], 'y': paldf['y']} phadf = pd.read_csv(phafile, sep='\s+', header=None, names=['x', 'y']) phadf = phadf * 1e-3 phasource.data = {'x': phadf['x'], 'y': phadf['y']} xmin = np.min([xmin, np.min(paldf['x']), np.min(phadf['x'])]) xmax = np.max([xmax, np.max(paldf['x']), np.max(phadf['x'])]) ymin = np.min([ymin, np.min(paldf['y']), np.min(phadf['y'])]) ymax = np.max([ymax, np.max(paldf['y']), np.max(phadf['y'])]) xsz = xmax - xmin ysz = ymax - ymin xrng = [xmin - (xsz * 0.05), xmax + (xsz * 0.05)] yrng = [ymin - (ysz * 0.05), ymax + (ysz * 0.05)] dfs['tngdf'] = tngdf dfs['paldf'] = paldf dfs['phadf'] = phadf def update_sgram(): '''Update spectrogram based on current values.''' if snd.end_time < 15: sgrams[0] = snd2specgram(snd, 0.005) specsource.data = dict( sgram0=[sgrams[0].values.astype(np.float32)]) spec0img.glyph.dw = sgrams[0].x_grid().max() spec0img.glyph.dh = sgrams[0].y_grid().max() spec0cmap.low = _low_thresh() spec0.visible = True else: specsource.data = dict(sgram0=[]) spec0.visible = False def update_trace(): '''Update the static trace at the cursor time.''' trace.title.text = f'Static trace ({cursor.location:0.4f})' tidx = dfs['tngdf'].index.get_loc(cursor.location, method='nearest') row = dfs['tngdf'].iloc[tidx] tngsource.data = { 'x': [row.T1x, row.T2x, row.T3x, row.T4x], 'y': [row.T1y, row.T2y, row.T3y, row.T4y] } othsource.data = { 'x': [row.ULx, row.LLx, row.MIx, row.MMx], 'y': [row.ULy, row.LLy, row.MIy, row.MMy] } def update_traj(): '''Update the trajectories during the selected time range.''' traj.title.text = f'Trajectories ({selbox.left:0.4f} - {selbox.right:0.4f})' seldf = dfs['tngdf'].loc[(dfs['tngdf'].index >= selbox.left) & (dfs['tngdf'].index <= selbox.right)] dfs['seldf'] = seldf pts = ('T1x', 'T1y', 'T2x', 'T2y', 'T3x', 'T3y', 'T4x', 'T4y', 'ULx', 'ULy', 'LLx', 'LLy', 'MIx', 'MIy', 'MMx', 'MMy') # Create a list of line segments for each tracked element. newdata = { pt: list(np.squeeze(np.dstack((seldf[pt].iloc[:-1], seldf[pt].iloc[1:])))) \ for pt in pts } newdata['color'] = np.arange(1, len(seldf)) newdata['sec'] = seldf.index[1:] timesource.data = newdata anim_slider.start = seldf.index[0] anim_slider.end = seldf.index[-1] anim_slider.step = np.diff(newdata['sec']).mean() anim_slider.value = anim_slider.end anim_slider.disabled = False anim_btn.disabled = False lastrow = seldf.iloc[-1] lasttngtimesource.data = { 'x': [lastrow.T1x, lastrow.T2x, lastrow.T3x, lastrow.T4x], 'y': [lastrow.T1y, lastrow.T2y, lastrow.T3y, lastrow.T4y] } lastothtimesource.data = { 'x': [lastrow.ULx, lastrow.LLx, lastrow.MIx, lastrow.MMx], 'y': [lastrow.ULy, lastrow.LLy, lastrow.MIy, lastrow.MMy] } # TODO: this is a workaround until we can set x_range, y_range directly # See https://github.com/bokeh/bokeh/issues/4014 def set_limits(xstart, xend): '''Set axis limits.''' ch0.x_range.start = xstart ch0.x_range.end = xend ch0.axis[0].bounds = (xstart, xend) def update_select_widgets(clicked_x=None): '''Update widgets based on current selection. Use the clicked_x param to designate the cursor location if this function is called as the result of a Tap event. If clicked_x is None, then use the existing cursor location to set the center of the selection.''' mode = selmodebtn.labels[selmodebtn.active] if clicked_x is None and cursor.visible: x_loc = cursor.location elif clicked_x is not None: x_loc = clicked_x else: return if mode == '200ms': start = x_loc - 0.100 end = x_loc + 0.100 cursor.location = x_loc else: # 'word' or 'phone' idx = np.abs(source.data['seconds'] - x_loc).argmin() # TODO: clean up the redundancy fld = {'word': 'word', 'phone': 'phone'}[mode] label = source.data[fld][idx] indexes = nonzero_groups(source.data[fld] == label, include_any=idx) secs = source.data['seconds'][indexes] start = secs.min() end = secs.max() cursor.location = secs.mean() playselbtn.start = start playselbtn.end = end selbox.left = start selbox.right = end selbox.visible = True cursor.visible = True def spkr_select_cb(attr, old, new): '''Respond to changes in speaker multiselect.''' try: spkrs = demo[ (demo.sex.isin(sex_select.value) \ & demo.dialect_base_state.isin(state_select.value) \ & (demo.dialect_base_city.isin(city_select.value))) ].subject.unique() new_opts = [''] + [(f.value, f.label) for f in fileoptsdf[ fileoptsdf.speaker.isin(spkrs)].itertuples()] fselect.options = new_opts fselect.value = '' except NameError as e: pass # Values not set yet, so ignore def cursor_cb(e): '''Handle cursor mouse click in the waveform.''' update_select_widgets(clicked_x=e.x) update_trace() update_traj() def x_range_cb(attr, old, new): '''Handle change of x range in waveform/spectrogram.''' if attr == 'start': playvisbtn.start = new elif attr == 'end': playvisbtn.end = new def selection_cb(e): '''Handle data range selection event.''' #! TODO: handle situation in which selection is too short, i.e. len(seldf) <= 1 cursor.location = (e.geometry['x0'] + e.geometry['x1']) / 2 cursor.visible = True playselbtn.start = e.geometry['x0'] playselbtn.end = e.geometry['x1'] selbox.left = e.geometry['x0'] selbox.right = e.geometry['x1'] selbox.visible = True update_trace() update_traj() def selmode_cb(attr, old, new): '''Handle change in click selection value.''' update_select_widgets(clicked_x=None) def anim_cb(attr, old, new): '''Handle change in the animation slider.''' idx = np.argmin(np.abs(timesource.data['sec'] - new)) n = len(timesource.data['color']) active = np.arange(n - idx, n + 1) timesource.data['color'] = np.pad(active, (0, n - len(active)), constant_values=0) anim_cmap = LinearColorMapper(palette=r_Greys256, low=1, high=n + 1, low_color='white') for tag, palette in (('anim_tng', r_Reds9), ('anim_oth', r_Greens9)): for a in find(traj.references(), {'tags': tag}): a.line_color = linear_cmap('color', palette, low=1, high=n + 1, low_color='white') lasttngtimesource.data = { 'x': [ timesource.data[pt][idx][1] for pt in ('T1x', 'T2x', 'T3x', 'T4x') ], 'y': [ timesource.data[pt][idx][1] for pt in ('T1y', 'T2y', 'T3y', 'T4y') ] } lastothtimesource.data = { 'x': [ timesource.data[pt][idx][1] for pt in ('ULx', 'LLx', 'MIx', 'MMx') ], 'y': [ timesource.data[pt][idx][1] for pt in ('ULy', 'LLy', 'MIy', 'MMy') ] } def anim_btn_cb(): '''Handle click of anim_btn animate trajectories of selected audio.''' values = np.linspace(anim_slider.start, anim_slider.end, len(timesource.data['T1x'])) for v in values: anim_slider.value = v def low_thresh_cb(attr, old, new): '''Handle change in threshold slider to fade out low spectrogram values.''' params['low_thresh_power'] = new lt = _low_thresh() spec0cmap.low = lt def _low_thresh(): return sgrams[0].values.min() \ + sgrams[0].values.std()**params['low_thresh_power'] step = None rate = orig_rate = None # dfs = {} xrng = [] yrng = [] width = 1000 height = 200 cutoff = 50 order = 3 tngcolor = 'DarkRed' othcolor = 'Indigo' fselect = Select(options=[], value='') fselect.on_change('value', load_wav_cb) sex_select = MultiSelect(options=[('F', 'female'), ('M', 'male')], value=['F', 'M']) state_select = MultiSelect( options=list(demo.dialect_base_state.cat.categories), value=list(demo.dialect_base_state.cat.categories)) city_select = MultiSelect( options=list(demo.dialect_base_city.cat.categories), value=list(demo.dialect_base_city.cat.categories)) sex_select.on_change('value', spkr_select_cb) state_select.on_change('value', spkr_select_cb) city_select.on_change('value', spkr_select_cb) spkr_select_cb('', '', '') source = ColumnDataSource(data=dict(seconds=[], ch0=[])) channels = ['ch0'] playvisbtn = AudioButton(label='Play visible signal', source=source, channels=channels, width=120, disabled=True) playselbtn = AudioButton(label='Play selected signal', source=source, channels=channels, width=120, disabled=True) selmodebtn = RadioButtonGroup(labels=['200ms', 'word', 'phone'], active=1) selmodebtn.on_change('active', selmode_cb) # Instantiate and share specific select/zoom tools so that # highlighting is synchronized on all plots. boxsel = BoxSelectTool(dimensions='width') spboxsel = BoxSelectTool(dimensions='width') boxzoom = BoxZoomTool(dimensions='width') zoomin = ZoomInTool(dimensions='width') zoomout = ZoomOutTool(dimensions='width') crosshair = CrosshairTool(dimensions='height') shared_tools = [ 'xpan', boxzoom, boxsel, crosshair, zoomin, zoomout, 'reset' ] uttdiv = Div(text='') figargs = dict(tools=shared_tools, ) cursor = Span(dimension='height', line_color='red', line_dash='dashed', line_width=1) wavspec_height = 280 ch0 = figure(name='ch0', tooltips=[('time', '$x{0.0000}'), ('word', '@word'), ('phone', '@phone')], height=wavspec_height, **figargs) ch0.toolbar.logo = None ch0.line(x='seconds', y='ch0', source=source, nonselection_line_alpha=0.6) # Link pan, zoom events for plots with x_range. ch0.x_range.on_change('start', x_range_cb) ch0.x_range.on_change('end', x_range_cb) ch0.on_event(SelectionGeometry, selection_cb) ch0.on_event(Tap, cursor_cb) ch0.add_layout(cursor) wavtab = Panel(child=ch0, title='Waveform') selbox = BoxAnnotation(name='selbox', left=None, right=None, fill_color='green', fill_alpha=0.1, line_color='green', line_width=1.5, line_dash='dashed', visible=False) ch0.add_layout(selbox) sgrams = [np.ones((1, 1))] specsource = ColumnDataSource(data=dict(sgram0=[sgrams[0]])) spec0 = figure( name='spec0', x_range=ch0.x_range, # Keep times synchronized tooltips=[("time", "$x{0.0000}"), ("freq", "$y{0.0000}"), ("value", "@sgram0{0.000000}")], height=wavspec_height, **figargs) spec0.toolbar.logo = None spec0.x_range.on_change('start', x_range_cb) spec0.x_range.on_change('end', x_range_cb) spec0.on_event(SelectionGeometry, selection_cb) spec0.on_event(Tap, cursor_cb) spec0.add_layout(cursor) spec0.x_range.range_padding = spec0.y_range.range_padding = 0 spec0cmap = LogColorMapper(palette=r_Greys256, low_color=params['low_thresh_color']) low_thresh_slider = Slider(start=1.0, end=12.0, step=0.03125, value=params['low_thresh_power'], title='Spectrogram threshold') low_thresh_slider.on_change('value', low_thresh_cb) spec0img = spec0.image(image='sgram0', x=0, y=0, color_mapper=spec0cmap, level='image', source=specsource) spec0.grid.grid_line_width = 0.0 spec0.add_layout(selbox) sgramtab = Panel(child=spec0, title='Spectrogram') tngsource = ColumnDataSource(data={'x': [], 'y': []}) othsource = ColumnDataSource(data={'x': [], 'y': []}) timesource = ColumnDataSource({ 'T1x': [], 'T1y': [], 'T2x': [], 'T2y': [], 'T3x': [], 'T3y': [], 'T4x': [], 'T4y': [], 'ULx': [], 'ULy': [], 'LLx': [], 'LLy': [], 'MIx': [], 'MIy': [], 'MMx': [], 'MMy': [], 'color': [], 'sec': [] }) lasttngtimesource = ColumnDataSource(data={'x': [], 'y': []}) lastothtimesource = ColumnDataSource(data={'x': [], 'y': []}) palsource = ColumnDataSource(pd.DataFrame({'x': [], 'y': []})) phasource = ColumnDataSource(pd.DataFrame({'x': [], 'y': []})) trace = figure(width=500, height=300, title='Static trace', x_range=(-100.0, 25.0), y_range=(-37.650, 37.650), tools=[], tags=['xray', 'static_fig']) trace.toolbar.logo = None trace.circle('x', 'y', source=tngsource, size=3, color=tngcolor, tags=['update_xray']) trace.circle('x', 'y', source=othsource, size=3, color=othcolor, tags=['update_xray']) trace.line('x', 'y', source=tngsource, color=tngcolor, tags=['update_xray']) trace.line('x', 'y', source=palsource, color='black') trace.line('x', 'y', source=phasource, color='black') traj = figure(width=500, height=300, title='Trajectories', x_range=(-100.0, 25.0), y_range=(-37.650, 37.650), tools=[], tags=['xray', 'trajectory_fig']) traj.toolbar.logo = None traj.multi_line('T1x', 'T1y', source=timesource, tags=['anim_tng']) traj.multi_line('T2x', 'T2y', source=timesource, tags=['anim_tng']) traj.multi_line('T3x', 'T3y', source=timesource, tags=['anim_tng']) traj.multi_line('T4x', 'T4y', source=timesource, tags=['anim_tng']) traj.multi_line('ULx', 'ULy', source=timesource, tags=['anim_oth']) traj.multi_line('LLx', 'LLy', source=timesource, tags=['anim_oth']) traj.multi_line('MIx', 'MIy', source=timesource, tags=['anim_oth']) traj.multi_line('MMx', 'MMy', source=timesource, tags=['anim_oth']) traj.circle('x', 'y', source=lasttngtimesource, color=tngcolor) traj.circle('x', 'y', source=lastothtimesource, color=othcolor) traj.line('x', 'y', source=lasttngtimesource, color='lightgray') traj.line('x', 'y', source=palsource, color='black') traj.line('x', 'y', source=phasource, color='black') anim_slider = Slider(start=0, end=100, step=1, value=0, width=240, format='0.000f', title='Selected trajectory', orientation='horizontal', disabled=True) anim_slider.on_change('value', anim_cb) anim_btn = Button(label='Animate', width=120, disabled=True) anim_btn.on_click(anim_btn_cb) audtabs = Tabs(tabs=[wavtab, sgramtab]) mainLayout = column( row(sex_select, state_select, city_select), row(fselect), row( column(uttdiv, audtabs), column( #! row(anim_slider, anim_btn), column(Div(text='Click selection mode:'), selmodebtn, low_thresh_slider), row(playvisbtn, playselbtn))), row(trace, traj), name='mainLayout') doc.add_root(mainLayout) return doc
ss) sample_cds = recompute_histogram(current_sample_ar, sample_cds) pop_cds = recompute_histogram(samples_ar, pop_cds) ######################################################### ### Main ### #Initial values of the data samples_ar, current_sample_ar = create_pop_samples( number_of_samples, Population_Range, sample_size) #Plot data structures sample_cds = ColumnDataSource(dict(xs=[], ys=[])) pop_cds = ColumnDataSource(dict(xs=[], ys=[])) # Set plot values sample_cds = recompute_histogram(current_sample_ar, sample_cds) pop_cds = recompute_histogram(samples_ar, pop_cds) # Set the callback sample_size_slider = Slider(title="Number of Individuals per Sample", value=sample_size, start=1, end=200, step=1) number_of_samples_slider = Slider(title="Number of Sample Draws", value=number_of_samples, start=1, end=2000,step=1) # First arg is the trigger - the variable - value from the Widget sample_size_slider.on_change('value', update_sampling) number_of_samples_slider.on_change('value', update_sampling) s_panel = panel() curdoc().add_root(s_panel) curdoc().title = "Law of Large Numbers Simulation"
plot.add_tools(HoverTool(tooltips="@Country", show_arrow=False, point_policy='follow_mouse')) def animate_update(): year = slider.value + 1 if year > years[-1]: year = years[0] slider.value = year def slider_update(attrname, old, new): year = slider.value label.text = str(year) source.data = data[year] slider = Slider(start=years[0], end=years[-1], value=years[0], step=1, title="Year") slider.on_change('value', slider_update) callback_id = None def animate(): global callback_id if button.label == '► Play': button.label = '❚❚ Pause' callback_id = curdoc().add_periodic_callback(animate_update, 200) else: button.label = '► Play' curdoc().remove_periodic_callback(callback_id) button = Button(label='► Play', width=60) button.on_click(animate)
def family_view_with_slider_and_predictions(pkl_folder_path, predictions_folder_path, ex_num=None): """ View interactively with bokeh a family album of all the triplets and the predictions from all the familyGan.models :param pkl_folder_path: pkl folder path containing all the family triplets :param predictions_folder_path: folder path containing the prediction pkls """ father_img_paths, mother_img_paths, child_img_paths = _save_pkl_images_to_local_path( pkl_folder_path, ex_num=ex_num) n = len(father_img_paths) # the plotting code sources_dict = {} # parent plots family_plots = [] pathes = [father_img_paths, mother_img_paths, child_img_paths] family_plot_num = 3 for i in range(family_plot_num): p = figure(height=300, width=300) img_paths = pathes[i] source = ColumnDataSource(data=dict(url=[img_paths[0]] * n, url_orig=img_paths, x=[1] * n, y=[1] * n, w=[1] * n, h=[1] * n)) image = ImageURL(url="url", x="x", y="y", w="w", h="h", anchor="bottom_left") p.add_glyph(source, glyph=image) _disable_all_for_pictures(p) family_plots.append(p) sources_dict[f"source{i}"] = source # model prediction plots pred_plots = [] all_models_picture_paths, model_names = _save_pred_images_to_local_path( pkl_folder_path, predictions_folder_path, ex_num=ex_num) pred_plot_num = len(model_names) n = len(father_img_paths) for i, model_name in enumerate(model_names): p = figure(height=300, width=300, title=model_name) img_paths = all_models_picture_paths[i] source = ColumnDataSource(data=dict(url=[img_paths[0]] * n, url_orig=img_paths, x=[1] * n, y=[1] * n, w=[1] * n, h=[1] * n)) image = ImageURL(url="url", x="x", y="y", w="w", h="h", anchor="bottom_left") p.add_glyph(source, glyph=image) _disable_all_for_pictures(p) pred_plots.append(p) sources_dict[f"source{family_plot_num+i}"] = source update_source_str = """ var data = source{i}.data; url = data['url'] url_orig = data['url_orig'] console.log(url) console.log(url_orig) for (i = 0; i < url_orig.length; i++) { url[i] = url_orig[f-1] } source{i}.change.emit(); """ # the callback callback = CustomJS(args=sources_dict, code=f""" var f = cb_obj.value; {"".join([update_source_str.replace('{i}', str(i)) for i in range(family_plot_num+pred_plot_num)])} """) slider = Slider(start=1, end=n, value=1, step=1, title="example number") slider.js_on_change('value', callback) column_layout = [slider, row(*family_plots)] curr_row = [] for i in range(len(pred_plots)): curr_row.append(pred_plots[i]) if (i + 1) % 3 == 0: column_layout.append(row(*curr_row.copy())) curr_row = [] if len(curr_row) != 0: column_layout.append(row(*curr_row.copy())) layout = column(*column_layout) # layout = column(slider, row(*family_plots), row(*pred_plots)) show(layout)