def test_callback_property_executes(self, bokeh_model_page): group = CheckboxButtonGroup(labels=LABELS, css_classes=["foo"]) group.callback = CustomJS(code=RECORD("active", "cb_obj.active")) page = bokeh_model_page(group) el = page.driver.find_element_by_css_selector( '.foo .bk-btn:nth-child(3)') el.click() results = page.results assert results['active'] == [2] el = page.driver.find_element_by_css_selector( '.foo .bk-btn:nth-child(1)') el.click() results = page.results assert results['active'] == [0, 2] el = page.driver.find_element_by_css_selector( '.foo .bk-btn:nth-child(3)') el.click() results = page.results assert results['active'] == [0] assert page.has_no_console_errors()
def test_callback_property_executes(self, bokeh_model_page): group = CheckboxButtonGroup(labels=LABELS, css_classes=["foo"]) group.callback = CustomJS(code=RECORD("active", "cb_obj.active")) page = bokeh_model_page(group) el = page.driver.find_element_by_css_selector('.foo .bk-btn:nth-child(3)') el.click() results = page.results assert results['active'] == [2] el = page.driver.find_element_by_css_selector('.foo .bk-btn:nth-child(1)') el.click() results = page.results assert results['active'] == [0, 2] el = page.driver.find_element_by_css_selector('.foo .bk-btn:nth-child(3)') el.click() results = page.results assert results['active'] == [0] assert page.has_no_console_errors()
def run(self, doc: Document, visualisations: typing.Sequence[Visualisation], epoch_batches: int = 100, epoch_batch_size: int = 50, cols: int = 2, title: str = "Experiment"): """Run the experiment. Arguments: doc {Document} -- the bokeh Document visualisations {typing.Sequence[Visualisation]} -- the visualisations to show in real time Keyword Arguments: epoch_batches {int} -- the number of batches of training to perform for each agent (default: {100}) epoch_batch_size {int} -- the number of epochs to train for per training batch (default: {50}) cols {int} -- the number of columns to display the visualisations in (default: {2}) title {str} -- optional title of the web page (default: {"Experiment"}) """ # Determine which metrics need to be calculated. # This will ensure that we do not calculate useless metrics that are not visualised. metrics = set( itertools.chain(*[ visualisation.required_metrics for visualisation in visualisations ])) # Create plots plots, lines = zip(*[ visualisation.setup(self.agent_names, palette=Category10[10]) for visualisation in visualisations ]) # Create a button per agent to toggle their visibility buttons = CheckboxButtonGroup(labels=self.agent_names, active=list(range(len(self.agents)))) buttons.callback = CustomJS(args=dict(buttons=buttons, lines=lines), code="""console.log(buttons); lines.forEach(plot => plot.forEach((line, index) => { line.visible = buttons.active.includes( index); })); """) # Add the title, buttons, and plots doc.title = title doc.add_root(column(buttons, gridplot(plots, ncols=cols))) def run_blocking(): """Method to run the training of each agent that will update the visualisations in real time. This method should run on a separate thread. """ # Compile the agents [agent.compile() for agent in self.agents] # Plot initial point agent_data = [{ **{ k: v[np.newaxis, ...] for (k, v) in agent.problem.evaluate_metrics(metrics=metrics).items( ) }, "epoch": np.array([0]), "run_time": np.array([0]) } for agent in self.agents] for visualisation, plot in zip(visualisations, plots): visualisation.plot(agent_data, plot, doc) # Perform training and continually plot for epoch_batch in range(epoch_batches): start_epoch = epoch_batch * epoch_batch_size + 1 def get_agent_data(): for agent in self.agents: start = time.perf_counter() data = agent.train(epochs=epoch_batch_size, metrics=metrics) end = time.perf_counter() data["epoch"] = np.arange( start_epoch, start_epoch + epoch_batch_size) data["run_time"] = np.repeat( end - start, epoch_batch_size) / epoch_batch_size yield data data = list(get_agent_data()) for visualisation, plot in zip(visualisations, plots): visualisation.plot(data, plot, doc) # Run the experiment in a separate thread thread = Thread(target=run_blocking) thread.start()