def df_items_to_tooltip(df, text_key: str, tool_tip_key: str): """ Turns df into dictionary with rows as lists items and passes specified keys to item text and tooltip respectively. Returns: list of rows with containers with text and tooltips """ df_dict = df.to_dict(orient="records") row_conts = [] for row in df_dict: container = v.Container(children=[ v.Tooltip( bottom=True, v_slots=[{ "name": "activator", "variable": "tooltip", "children": v.Html( tag="t2", v_on="tooltip.on", children=[str(row[text_key])], ), }], children=[str(row[tool_tip_key])], ) ]) row_conts.append(field) return row_conts
def add_tool(self, tool): self.tools[tool.tool_id] = tool icon = Image.from_file(icon_path(tool.icon, icon_format='svg'), width=ICON_WIDTH) button = v.Btn(v_on="tooltip.on", icon=True, children=[icon], value=tool.tool_id) annotated = v.Tooltip( bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': button}], children=[tool.tool_tip]) self.children = list(self.children) + [annotated]
def __init__(self, children, compute_all, label="", append_icon=None, prepend_icon=None, tooltip=""): # _widget for v_model, widget for display if append_icon: self._widget = v.Checkbox( v_on='tooltip.on', append_icon=append_icon, v_model=True) elif prepend_icon: self._widget = v.Checkbox( v_on='tooltip.on', prepend_icon=prepend_icon, v_model=True) else: self._widget = v.Checkbox( v_on='tooltip.on', label=label, v_model=True) self.widget = v.Tooltip(bottom=True, v_slots=[{'name': 'activator', 'variable': 'tooltip', 'children': self._widget}], children=[tooltip]) self._widget.on_event('change', self.handler) self.children = children self.compute_all = compute_all
def __init__(self, label, tooltip, enum_color, clr, init_layer_val, layer_options, compute): self.check = v.Checkbox(v_on='tooltip.on', label=label, v_model=True , color='primary') self.check_widget = v.Tooltip(bottom=True, v_slots=[{'name': 'activator', 'variable': 'tooltip', 'children': self.check}], children=[tooltip]) self.compute = compute self.enum_color = enum_color self.init_layer_val = init_layer_val self.layer_options = layer_options self.dropdown_widget = Dropdown(options=self.layer_options , value=init_layer_val, disabled=False, layout={'width': '90px'} ) self.dropdown_widget.observe(self.compute, names='value') self.dropdown_widget.observing = True self.clr = clr
def init_widgets(self, tag_type): self.all_check = v.Checkbox(v_on='tooltip.on', prepend_icon='fa-globe', label="All", v_model=True, class_='ma-0 mt-1 pa-0') self.all_check_tp = v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': self.all_check }], children=["Select all"]) self.all_check.on_event('change', self.check_all) all_row = [v.Row(children=[self.all_check_tp], class_='ml-7')] tag_rows = [] treenodelabel = v.Html( tag='style', children= [(".vuetify-styles .v-treeview-node__label {" "margin-left: 0px;" "overflow: visible;" "}" ".vuetify-styles .v-input--selection-controls:not(.v-input--hide-details) .v-input__slot {" "margin-bottom: 0px;" "}" ".vuetify-styles .v-treeview-node__root .v-icon.v-icon.v-icon--link {" "margin-bottom: 10px;" "}" ".vuetify-styles .v-treeview-node--leaf {" "margin-left: 0px;" "}" ".vuetify-styles .v-treeview--dense .v-treeview-node__root {" "min-height: 21px;" "}")]) for tag in self.model.curr_trace.tags: if tag.tag_type == tag_type: chk = Checkbox(tag) self.checkboxes.append(chk) chk.widget.on_event('change', self.update_all_checkbox) stats = self.get_stats(tag) btn, tooltip = self.create_zoom_button(tag, stats=stats) statss = self.tag_tooltip(tag, stats).splitlines() tag_row = v.Row(children=[btn, chk.widget], class_='ml-0') items = [{ 'id': 1, 'name': '', 'children': [{ 'id': i + 2, 'name': stat } for i, stat in enumerate(statss)], }] treeview = v.Treeview(items=items, dense=True) tag_rows.append( v.Container(row=False, class_="d-flex justify-start ma-0 pa-0", children=[ v.Col(cols=1, children=[treeview], class_="ma-0 pa-0"), v.Col(cols=12, children=[tag_row], class_="pt-0 pb-0") ])) tag_rows.append(v.Container(row=False, children=[treenodelabel])) return VBox([ v.List(children=(all_row + tag_rows), dense=True, nav=True, max_height="300px", max_width="300px") ])
def create_tools(self): self.tools = [] tool_actions = [] self.tool_actions_map = tool_actions_map = {u"pan/zoom": self.panzoom} tool_actions.append(u"pan/zoom") # self.control_widget.set_title(0, "Main") self._main_widget = widgets.VBox() self._main_widget_1 = widgets.HBox() self._main_widget_2 = widgets.HBox() if 1: # tool_select: self.brush = bqplot.interacts.BrushSelector(x_scale=self.scale_x, y_scale=self.scale_y, color="green") tool_actions_map["select"] = self.brush tool_actions.append("select") self.brush.observe(self.update_brush, ["selected", "selected_x"]) # fig.interaction = brush # callback = self.dataset.signal_selection_changed.connect(lambda dataset: update_image()) # callback = self.dataset.signal_selection_changed.connect(lambda *x: self.update_grid()) # def cleanup(callback=callback): # self.dataset.signal_selection_changed.disconnect(callback=callback) # self._cleanups.append(cleanup) self.button_select_nothing = v.Btn( icon=True, v_on='tooltip.on', children=[v.Icon(children=['delete'])]) self.widget_select_nothing = v.Tooltip( bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': self.button_select_nothing }], children=["Delete selection"]) self.button_reset = widgets.Button(description="", icon="refresh") import copy self.start_limits = copy.deepcopy(self.limits) def reset(*args): self.limits = copy.deepcopy(self.start_limits) with self.scale_y.hold_trait_notifications(): self.scale_y.min, self.scale_y.max = self.limits[1] with self.scale_x.hold_trait_notifications(): self.scale_x.min, self.scale_x.max = self.limits[0] self.plot.update_grid() self.button_reset.on_click(reset) self.button_select_nothing.on_event( 'click', lambda *ignore: self.plot.select_nothing()) self.tools.append(self.button_select_nothing) self.modes_names = "replace and or xor subtract".split() self.modes_labels = "replace and or xor subtract".split() self.button_selection_mode = widgets.Dropdown( description='select', options=self.modes_labels) self.tools.append(self.button_selection_mode) def change_interact(*args): with self.output: # print "change", args name = tool_actions[self.button_action.v_model] self.figure.interaction = tool_actions_map[name] tool_actions = ["pan/zoom", "select"] # tool_actions = [("m", "m"), ("b", "b")] self.button_action = \ v.BtnToggle(v_model=0, mandatory=True, multiple=False, children=[ v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': v.Btn(v_on='tooltip.on', children=[ v.Icon(children=['pan_tool']) ]) }], children=[ "Pan & zoom" ]), v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': v.Btn(v_on='tooltip.on', children=[ v.Icon(children=['crop_free']) ]) }], children=[ "Square selection" ]), ]) self.widget_tool_basic = v.Layout(children=[ v.Layout( pa_1=True, column=False, align_center=True, children=[self.button_action, self.widget_select_nothing]) ]) self.plot.add_control_widget(self.widget_tool_basic) self.button_action.observe(change_interact, "v_model") self.tools.insert(0, self.button_action) self.button_action.value = "pan/zoom" # tool_actions[-1] if len(self.tools) == 1: tools = [] # self._main_widget_1.children += (self.button_reset,) self._main_widget_1.children += (self.button_action, ) self._main_widget_1.children += (self.button_select_nothing, ) # self._main_widget_2.children += (self.button_selection_mode,) self._main_widget.children = [self._main_widget_1, self._main_widget_2] self.control_widget.children += (self._main_widget, ) self._update_grid_counter = 0 # keep track of t self._update_grid_counter_scheduled = 0 # keep track of t
def create_tools(self): self.tools = [] self.tool_actions = [] tool_actions_map = dict() if 1: # tool_select: #### initiaite the 4 types of zoom brushes, which should only highlight axis that are not locked ### self.zoom_brush_full = bqplot.interacts.BrushSelector( x_scale=self.scale_x, y_scale=self.scale_y, color="blue") self.zoom_brush_full.observe(self.update_zoom_brush_full, ["brushing"]) self.zoom_brush_vertical = bqplot.interacts.BrushIntervalSelector( scale=self.scale_y, orientation='vertical', color="blue") self.zoom_brush_vertical.observe(self.update_zoom_brush_vertical, ["brushing"]) self.zoom_brush_horizontal = bqplot.interacts.BrushIntervalSelector( scale=self.scale_x, orientation='horizontal', color="blue") self.zoom_brush_horizontal.observe( self.update_zoom_brush_horizontal, ["brushing"]) self.zoom_brush_none = bqplot.interacts.BrushSelector( x_scale=self.scale_x, y_scale=self.scale_y, color="gray") self.zoom_brush_none.observe(self.update_zoom_brush_none, ["brushing"]) # initiaite measurement tool self.ruler = bqplot.interacts.BrushSelector(x_scale=self.scale_x, y_scale=self.scale_y, color="blue") self.ruler.observe(self.measure_selected_area, ["brushing"]) #### Set the default initial tools #### self.zoom_brush = self.zoom_brush_full self.click_brush = None # use regular mouse self.click_brush_in = None self.click_brush_out = None tool_actions_map[ZOOM_SELECT] = self.zoom_brush tool_actions_map[PAN_ZOOM] = self.panzoom tool_actions_map[CLICK_ZOOM_IN] = self.click_brush_in tool_actions_map[CLICK_ZOOM_OUT] = self.click_brush_out tool_actions_map[RULER] = self.ruler self.tool_actions = [ PAN_ZOOM, ZOOM_SELECT, CLICK_ZOOM_IN, CLICK_ZOOM_OUT, RULER ] self.start_limits = copy.deepcopy(self.limits) def change_interact(*args): with self.output: name = self.tool_actions[self.interaction_tooltips.v_model] self.figure.interaction = tool_actions_map[name] if name == RULER: self.plot.model.legend.openMeasurementPanel() self.interaction_tooltips = \ v.BtnToggle(v_model=0, mandatory=True, multiple=False, children=[ v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': v.Btn(v_on='tooltip.on', children=[ v.Icon(children=['pan_tool']) ]) }], children=[PAN_ZOOM]), v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': v.Btn(v_on='tooltip.on', children=[ v.Icon(children=['crop']) ]) }], children=[ZOOM_SELECT]), v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': v.Btn(v_on='tooltip.on', children=[ v.Icon( children=['mdi-magnify-plus-cursor']) ]) }], children=[CLICK_ZOOM_IN]), v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': v.Btn(v_on='tooltip.on', children=[ v.Icon( children=['mdi-magnify-minus-cursor']) ]) }], children=[CLICK_ZOOM_OUT]), v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': v.Btn(v_on='tooltip.on', children=[ v.Icon(children=['mdi-ruler']) ]) }], children=[RULER]) # ruler ]) self.interaction_tooltips.observe(change_interact, "v_model") def reset(*args): (x1, x2), (y1, y2) = self.start_limits self.zoom_sel(x1, x2, y1, y2, smart_zoom=True) with self.zoom_brush.hold_trait_notifications(): self.zoom_brush.selected_x = None self.zoom_brush.selected_y = None self.zoom_brush.selected = None self.screenshot_btn = v.Btn( v_on='tooltip.on', icon=True, children=[v.Icon(children=['mdi-camera'])]) self.screenshot_tooltip = v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': self.screenshot_btn }], children=[SCREENSHOT]) @debounced(0.5) def screenshot(): def peer(a): print(type(a).__name__) print(type(a).__module__) print(dir(a)) #display(self.pil_image_test) # print(self.core_image.value) #peer(self.figure) #self.figure.save_png("test.png") #display(IPyImage("test.png")) #display(self.core.image) clear_output(wait=True) self.plot.model.plot.show() display(IPyImage(self.core_image.value)) self.screenshot_btn.on_event('click', lambda *ignore: screenshot()) self.reset_btn = v.Btn(v_on='tooltip.on', icon=True, children=[v.Icon(children=['refresh'])]) self.reset_btn.on_event('click', lambda *ignore: reset()) self.reset_tooltip = v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': self.reset_btn }], children=[RESET_ZOOM]) self.undo_btn = v.Btn(v_on='tooltip.on', icon=True, disabled=True, children=[v.Icon(children=['undo'])]) self.undo_tooltip = v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': self.undo_btn }], children=[UNDO]) self.redo_btn = v.Btn(v_on='tooltip.on', icon=True, disabled=True, children=[v.Icon(children=['redo'])]) self.redo_tooltip = v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': self.redo_btn }], children=[REDO]) @debounced(0.5) def undo_redo(*args): self.curr_action = args[0] (x1, x2), (y1, y2) = args[1][-1] with self.scale_x.hold_trait_notifications(): with self.scale_y.hold_trait_notifications(): self.scale_x.min, self.scale_x.max = x1, x2 self.scale_y.min, self.scale_y.max = y1, y2 self.undo_btn.on_event( 'click', lambda *ignore: undo_redo(Action.undo, self.undo_actions)) self.redo_btn.on_event( 'click', lambda *ignore: undo_redo(Action.redo, self.redo_actions)) control_lyt = widgets.Layout(width='100px') self.control_x = widgets.Checkbox(value=False, description='Lock X Axis', indent=False, layout=control_lyt) self.control_y = widgets.Checkbox(value=False, description='Lock Y Axis', indent=False, layout=control_lyt) def axis_lock_update(checkbox): ####### Only allows one checkbox to be locked at a time ###### if checkbox['owner'].description == self.control_x.description: if self.control_y.value: self.control_y.value = False if checkbox['owner'].description == self.control_y.description: if self.control_x.value: self.control_x.value = False ############################################################## # When a axis checkbox is locked. # Updates the panzoom tool to lock eithier the x or y axis. # Also updates the zoombrush tool to use relevant zoom brush if self.control_x.value: if self.control_y.value: self.panzoom = bqplot.PanZoom() self.zoom_brush = self.zoom_brush_none else: self.panzoom = bqplot.PanZoom( scales={'y': [self.scale_y]}) self.zoom_brush = self.zoom_brush_vertical else: if self.control_y.value: self.panzoom = bqplot.PanZoom( scales={'x': [self.scale_x]}) self.zoom_brush = self.zoom_brush_horizontal else: self.panzoom = bqplot.PanZoom(scales={ 'x': [self.scale_x], 'y': [self.scale_y] }) self.zoom_brush = self.zoom_brush_full tool_actions_map[PAN_ZOOM] = self.panzoom tool_actions_map[ZOOM_SELECT] = self.zoom_brush # Update immediately if in PAN_ZOOM mode name = self.tool_actions[self.interaction_tooltips.v_model] if name == PAN_ZOOM: self.figure.interaction = self.panzoom elif name == ZOOM_SELECT: self.figure.interaction = self.zoom_brush self.control_x.observe(axis_lock_update) self.control_y.observe(axis_lock_update) self.axis_controls = widgets.VBox([self.control_x, self.control_y]) self.tooltips = v.Row(children=[ self.axis_controls, self.interaction_tooltips, self.reset_tooltip, self.undo_tooltip, self.redo_tooltip, self.screenshot_tooltip ], align='center', justify='center') self.plot.add_to_toolbar(self.tooltips)
def init_widgets(self): # Primary checkboxes read_hit = ChildCheckbox(self.compute_all, READ_HIT, 1) write_hit = ChildCheckbox(self.compute_all, WRITE_HIT, 2) read_capmiss = ChildCheckbox(self.compute_all, READ_MISS, 4) write_capmiss = ChildCheckbox(self.compute_all, WRITE_MISS, 5) read_compmiss = ChildCheckbox(self.compute_all, COMP_R_MISS, 6) write_compmiss = ChildCheckbox(self.compute_all, COMP_W_MISS, 8) chks = [read_hit, write_hit, read_capmiss, write_capmiss, read_compmiss, write_compmiss] self.checkboxes = chks # Parent checkboxes self.all_check = ParentCheckbox(chks, self.compute_all, label = 'All', tooltip="Show All") self.read_check = ParentCheckbox([read_hit, read_capmiss, read_compmiss], self.compute_all, label='Reads', tooltip="Reads") self.write_check = ParentCheckbox([write_hit, write_capmiss, write_compmiss], self.compute_all, label='Writes', tooltip="Writes") self.hit_check = ParentCheckbox([read_hit, write_hit], self.compute_all, label='Hits', tooltip="Hits") self.capmiss_check = ParentCheckbox([read_capmiss, write_capmiss], self.compute_all, label='Capacity Misses', tooltip="Capacity Misses") self.compmiss_check = ParentCheckbox([read_compmiss, write_compmiss], self.compute_all, label='Compuls Misses', tooltip="Compulsory Misses") self.parentcheckboxes = [self.all_check, self.read_check, self.write_check, self.hit_check, self.capmiss_check, self.compmiss_check] def parentbox(check): return HBox([check.widget], layout=Layout(align_items="center", overflow="hidden", justify_content="center")) def clr_picker(clr, cache=False): if cache: clr_picker = ColorPicker(concise=True, value=to_hex(self.colormap[clr][0:3]), disabled=False, layout=Layout(width="30px")) else: clr_picker = ColorPicker(concise=True, value=to_hex(self.colormap[clr][0:3]), disabled=False, layout=Layout(width="25px", margin="0 0 0 8px")) clr_picker.observing = True def handle_color_picker(change): self.colormap[clr] = to_rgba(change.new, 1) self.model.plot.colormap = ListedColormap(self.colormap) self.model.plot.backend.plot._update_image() clr_picker.observe(handle_color_picker, names='value') self.colorpickers[clr] = clr_picker return clr_picker def primbox(check): return HBox([check.widget, clr_picker(check.clr)], layout=Layout(justify_content="center",align_items="center",overflow="hidden")) # Wrap parent boxes in ipywidget alls = parentbox(self.all_check) read = parentbox(self.read_check) write = parentbox(self.write_check) hits = parentbox(self.hit_check) capmisses = parentbox(self.capmiss_check) compmisses = parentbox(self.compmiss_check) # Add pseudo grid and wrap primary boxes in ipywidget gridbox = HBox([GridBox([alls, vdiv, read, vdiv, write, hdiv, hdiv, hdiv, hdiv, hdiv, hits, vdiv, primbox(read_hit), lvdiv, primbox(write_hit), hdiv, hdiv, lhdiv, lhdiv, lhdiv, capmisses, vdiv, primbox(read_capmiss), lvdiv, primbox(write_capmiss), hdiv, hdiv, lhdiv, lhdiv, lhdiv, compmisses, vdiv, primbox(read_compmiss), lvdiv, primbox(write_compmiss)], layout=Layout(grid_template_rows="50px 2px 50px 2px 50px 2px 50px", grid_template_columns="100px 5px 100px 5px 100px"))], layout=Layout(padding="0 0 0 14px")) cache_icon = v.Icon(children=['fa-database'], v_on='tooltip.on') cache_icon_tp = v.Tooltip(bottom=True, v_slots=[{'name': 'activator', 'variable': 'tooltip', 'children': cache_icon}], children=["Cache"]) cache_clrpkr = clr_picker(3, cache=True) reset_clrs = v.Btn(v_on='tooltip.on', icon=True, children=[v.Icon(children=['refresh'])]) reset_clrs.on_event('click', self.reset_colormap) reset_clrs_tp = v.Tooltip(bottom=True, v_slots=[{'name': 'activator', 'variable': 'tooltip', 'children': reset_clrs}], children=["Reset all colors"]) cache_row = HBox([cache_icon_tp, cache_clrpkr, reset_clrs_tp], layout=Layout(padding="0 20px 20px 20px", align_items="center", justify_content="space-between")) cache_row return VBox([gridbox, cache_row])
def create_tools(self): self.tools = [] tool_actions = [] tool_actions_map = dict() if 1: # tool_select: self.zoom_brush = bqplot.interacts.BrushSelector( x_scale=self.scale_x, y_scale=self.scale_y, color="blue") self.zoom_brush.observe(self.update_zoom_brush, ["brushing"]) self.click_brush = None # use regular mouse tool_actions_map[ZOOM_SELECT] = self.zoom_brush tool_actions_map[PAN_ZOOM] = self.panzoom tool_actions_map[CLICK_ZOOM] = self.click_brush tool_actions = [PAN_ZOOM, ZOOM_SELECT, CLICK_ZOOM] self.start_limits = copy.deepcopy(self.limits) def change_interact(*args): with self.output: name = tool_actions[self.interaction_tooltips.v_model] self.figure.interaction = tool_actions_map[name] self.interaction_tooltips = \ v.BtnToggle(v_model=0, mandatory=True, multiple=False, children=[ v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': v.Btn(v_on='tooltip.on', children=[ v.Icon(children=['pan_tool']) ]) }], children=[PAN_ZOOM]), v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': v.Btn(v_on='tooltip.on', children=[ v.Icon(children=['crop']) ]) }], children=[ZOOM_SELECT]), v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': v.Btn(v_on='tooltip.on', children=[ v.Icon(children=['mdi-mouse']) ]) }], children=[CLICK_ZOOM]) ]) self.interaction_tooltips.observe(change_interact, "v_model") def reset(*args): (x1, x2), (y1, y2) = self.start_limits self.zoom_sel(x1, x2, y1, y2, smart_zoom=True) with self.zoom_brush.hold_trait_notifications(): self.zoom_brush.selected_x = None self.zoom_brush.selected_y = None self.reset_btn = v.Btn(v_on='tooltip.on', icon=True, children=[v.Icon(children=['refresh'])]) self.reset_btn.on_event('click', lambda *ignore: reset()) self.reset_tooltip = v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': self.reset_btn }], children=[RESET_ZOOM]) self.undo_btn = v.Btn(v_on='tooltip.on', icon=True, disabled=True, children=[v.Icon(children=['undo'])]) self.undo_tooltip = v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': self.undo_btn }], children=[UNDO]) self.redo_btn = v.Btn(v_on='tooltip.on', icon=True, disabled=True, children=[v.Icon(children=['redo'])]) self.redo_tooltip = v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': self.redo_btn }], children=[REDO]) @debounced(0.5) def undo_redo(*args): self.curr_action = args[0] (x1, x2), (y1, y2) = args[1][-1] with self.scale_x.hold_trait_notifications(): with self.scale_y.hold_trait_notifications(): self.scale_x.min, self.scale_x.max = x1, x2 self.scale_y.min, self.scale_y.max = y1, y2 self.undo_btn.on_event( 'click', lambda *ignore: undo_redo(Action.undo, self.undo_actions)) self.redo_btn.on_event( 'click', lambda *ignore: undo_redo(Action.redo, self.redo_actions)) control_lyt = widgets.Layout(width='40px') self.panzoom_x = control_x = widgets.Checkbox(value=True, description='X', indent=False, layout=control_lyt) self.panzoom_y = control_y = widgets.Checkbox(value=True, description='Y', indent=False, layout=control_lyt) def update_panzoom(checkbox): if control_x.value: if control_y.value: self.panzoom = bqplot.PanZoom(scales={ 'x': [self.scale_x], 'y': [self.scale_y] }) else: self.panzoom = bqplot.PanZoom( scales={'x': [self.scale_x]}) else: if control_y.value: self.panzoom = bqplot.PanZoom( scales={'y': [self.scale_y]}) else: self.panzoom = bqplot.PanZoom() tool_actions_map[PAN_ZOOM] = self.panzoom # Update immediately if in PAN_ZOOM mode name = tool_actions[self.interaction_tooltips.v_model] if name == PAN_ZOOM: self.figure.interaction = self.panzoom self.panzoom_x.observe(update_panzoom) self.panzoom_y.observe(update_panzoom) self.panzoom_controls = widgets.VBox( [self.panzoom_x, self.panzoom_y]) self.tooltips = v.Row(children=[ self.panzoom_controls, self.interaction_tooltips, self.reset_tooltip, self.undo_tooltip, self.redo_tooltip ], align='center', justify='center') self.plot.add_to_toolbar(self.tooltips)