Python bokeh.layouts.row() Examples

The following are 20 code examples of bokeh.layouts.row(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module bokeh.layouts , or try the search function .
Example #1
Source File: bk_sliders.py    From parambokeh with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def app(doc):

    x,y = SineWave()
    source = ColumnDataSource(data=dict(x=x, y=y))

    import numpy as np # see TODO below about ranges
    plot = figure(plot_height=400, plot_width=400,
                  tools="crosshair,pan,reset,save,wheel_zoom",
                  x_range=[0, 4*np.pi], y_range=[-2.5, 2.5])
    plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)

    def update_sinewave(sw,**kw):
        x,y = sw()
        source.data = dict(x=x, y=y)
        # TODO couldn't figure out how to update ranges
        #plot.x_range.start,plot.x_range.end=pobj.x_range
        #plot.y_range.start,plot.y_range.end=pobj.y_range
    
    parambokeh.Widgets(SineWave, mode='server', doc=doc, callback=update_sinewave)
    doc.add_root(row(plot, width=800)) 
Example #2
Source File: BokehRenderer.py    From BAC0 with GNU Lesser General Public License v3.0 6 votes vote down vote up
def modify_document(self, doc):

        controller = self.network.notes[0]
        notes_df = pd.DataFrame(self.network.notes[1]).reset_index()
        notes_df.columns = ["index", "notes"]
        notes = ColumnDataSource(notes_df)
        self.columns = [
            TableColumn(field="index", title="Timestamp"),
            TableColumn(field="notes", title="Notes"),
        ]
        self.data_table = DataTable(source=notes, columns=self.columns)
        layout = row([self.data_table])
        doc.add_root(layout)
        doc.title = "Notes for {}".format(controller)
        # doc.add_periodic_callback(self.update_data,100)
        return doc 
Example #3
Source File: rtl_demo_nonflask.py    From pysdr with GNU General Public License v3.0 6 votes vote down vote up
def process_samples(samples, rtlsdr_obj):
    startTime = time.time()
    samples = prefilter.filter(samples) # 0.01s
    PSD = 10.0 * np.log10(np.abs(np.fft.fftshift(np.fft.fft(samples, fft_size)/float(fft_size)))**2) # calcs PSD
    waterfall = shared_buffer['waterfall'] # pull waterfall from buffer
    waterfall[:] = np.roll(waterfall, -1, axis=0) # shifts waterfall 1 row
    waterfall[-1,:] = PSD # fill last row with new fft results
    shared_buffer['waterfall'] = waterfall # you have to copy it back into the manager_list
    shared_buffer['psd'] = PSD # overwrites whatever was in psd buffer, so that the GUI uses the most recent one when it goes to refresh itself
    shared_buffer['i'] = np.real(samples[0:samples_in_time_plots]) # i buffer
    shared_buffer['q'] = np.imag(samples[0:samples_in_time_plots]) # q buffer
    # if the change-gain or change-freq callback function signaled STOP then we need to cancel the async read
    if shared_buffer['stop-signal'] == True:
        sdr.cancel_read_async() # needs to be called from this function, so we use the shared memory to send a signal
    shared_buffer['utilization'] = (time.time() - startTime)/float(samples_per_batch)*sdr.sample_rate # should be below 1.0 to avoid overflows

# Function that runs asynchronous reading from the RTL, and is a blocking function 
Example #4
Source File: usrp_bokeh_demo.py    From pysdr with GNU General Public License v3.0 6 votes vote down vote up
def process_samples(samples):
    startTime = time.time()
    if accumulator.accumulate_samples(samples): # add samples to accumulator (returns True when we have enough)
        samples = accumulator.samples # messy way of doing it but it works
        #samples = prefilter.filter(samples) # uncomment this to add a filter
        PSD = 10.0 * np.log10(np.abs(np.fft.fftshift(np.fft.fft(samples, fft_size)/float(fft_size)))**2) # calcs PSD, crops input to size of fft
        # add row to waterfall
        waterfall = waterfall_plot._input_buffer['waterfall'][0] # pull waterfall from buffer
        waterfall[:] = np.roll(waterfall, -1, axis=0) # shifts waterfall 1 row
        waterfall[-1,:] = PSD # fill last row with new fft results
        # stick everything we want to display into the shared buffer
        waterfall_plot._input_buffer['waterfall'] = [waterfall] # remember to copy it back into the buffer
        fft_plot._input_buffer['y'] = PSD # overwrites whatever was in psd buffer, so that the GUI uses the most recent one when it goes to refresh itself
        time_plot._input_buffer['i'] = np.real(samples[0:samples_in_time_plots]) # i buffer
        time_plot._input_buffer['q'] = np.imag(samples[0:samples_in_time_plots]) # q buffer
        iq_plot._input_buffer['i'] = np.real(samples[0:samples_in_time_plots])
        iq_plot._input_buffer['q'] = np.imag(samples[0:samples_in_time_plots])
        utilization_plot._input_buffer['y'] = [(time.time() - startTime)/float(len(samples))*samp_rate] # should be below 1.0 to avoid overflows
        
###############
# USRP Config #
############### 
Example #5
Source File: rtl_demo_onescript.py    From pysdr with GNU General Public License v3.0 6 votes vote down vote up
def process_samples(samples, rtlsdr_obj):
    startTime = time.time()
    PSD = 10.0 * np.log10(np.abs(np.fft.fftshift(np.fft.fft(samples, fft_size)/float(fft_size)))**2) # calcs PSD
    waterfall = shared_buffer['waterfall'] # pull waterfall from buffer
    waterfall[:] = np.roll(waterfall, -1, axis=0) # shifts waterfall 1 row
    waterfall[-1,:] = PSD # fill last row with new fft results
    shared_buffer['waterfall'] = waterfall # you have to copy it back into the manager_list
    shared_buffer['psd'] = PSD # overwrites whatever was in psd buffer, so that the GUI uses the most recent one when it goes to refresh itself
    shared_buffer['i'] = np.real(samples[0:samples_in_time_plots]) # i buffer
    shared_buffer['q'] = np.imag(samples[0:samples_in_time_plots]) # q buffer
    # if the change-gain or change-freq callback function signaled STOP then we need to cancel the async read
    if shared_buffer['stop-signal'] == True:
        sdr.cancel_read_async() # needs to be called from this function, so we use the shared memory to send a signal
    shared_buffer['utilization'] = (time.time() - startTime)/float(samples_per_batch)*sdr.sample_rate # should be below 1.0 to avoid overflows

# Function that runs asynchronous reading from the RTL, and is a blocking function 
Example #6
Source File: rtl_demo.py    From pysdr with GNU General Public License v3.0 6 votes vote down vote up
def process_samples(samples, rtlsdr_obj):
    startTime = time.time()
    samples = prefilter.filter(samples)
    PSD = 10.0 * np.log10(np.abs(np.fft.fftshift(np.fft.fft(samples, fft_size)/float(fft_size)))**2) # calcs PSD
    waterfall = shared_buffer['waterfall'] # pull waterfall from buffer
    waterfall[:] = np.roll(waterfall, -1, axis=0) # shifts waterfall 1 row
    waterfall[-1,:] = PSD # fill last row with new fft results
    shared_buffer['waterfall'] = waterfall # you have to copy it back into the manager_list
    shared_buffer['psd'] = PSD # overwrites whatever was in psd buffer, so that the GUI uses the most recent one when it goes to refresh itself
    shared_buffer['i'] = np.real(samples[0:samples_in_time_plots]) # i buffer
    shared_buffer['q'] = np.imag(samples[0:samples_in_time_plots]) # q buffer
    # if the change-gain or change-freq callback function signaled STOP then we need to cancel the async read
    if shared_buffer['stop-signal'] == True:
        sdr.cancel_read_async() # needs to be called from this function, so we use the shared memory to send a signal
    shared_buffer['utilization'] = (time.time() - startTime)/float(samples_per_batch)*sdr.sample_rate # should be below 1.0 to avoid overflows

# Function that runs asynchronous reading from the RTL, and is a blocking function 
Example #7
Source File: zmq_demo.py    From pysdr with GNU General Public License v3.0 6 votes vote down vote up
def process_samples():
    # Set up connection to gnuradio or whatever is providing zmq stream of np.complex64 in array form
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    print "Connecting to server"
    socket.connect ("tcp://localhost:%s" % port)
    topicfilter = "" # no idea why, but if i dont provide an empty topic filter then it just does not work, even the simple pyzmq example doesn't work
    socket.setsockopt(zmq.SUBSCRIBE, topicfilter)
    while True: # Run forever
        samples = np.frombuffer(socket.recv(), dtype=np.complex64) # blocking until there's a msg sent by the server
        startTime = time.time()
        PSD = 10.0 * np.log10(np.abs(np.fft.fftshift(np.fft.fft(samples, fft_size)/float(fft_size)))**2) # calcs PSD
        waterfall = shared_buffer['waterfall'] # pull waterfall from buffer
        waterfall[:] = np.roll(waterfall, -1, axis=0) # shifts waterfall 1 row
        waterfall[-1,:] = PSD # fill last row with new fft results
        shared_buffer['waterfall'] = waterfall # you have to copy it back into the manager_list
        shared_buffer['psd'] = PSD # overwrites whatever was in psd buffer, so that the GUI uses the most recent one when it goes to refresh itself
        shared_buffer['i'] = np.real(samples[0:samples_in_time_plots]) # i buffer
        shared_buffer['q'] = np.imag(samples[0:samples_in_time_plots]) # q buffer
        shared_buffer['utilization'] = (time.time() - startTime)/float(len(samples))*sample_rate # should be below 1.0 to avoid overflows

# Start SDR sample recieving/processing as a separate thread 
Example #8
Source File: ui.py    From nlp-architect with Apache License 2.0 5 votes vote down vote up
def _create_header(train_dropdown, inference_dropdown, text_status) -> layouts.Row:
    """Utility function for creating and styling the header row in the UI layout."""

    architect_logo = Div(
        text='<a href="http://nlp_architect.nervanasys.com"> <img border="0" '
        'src="style/nlp_architect.jpg" width="200"></a> by IntelĀ® AI Lab',
        style={
            "margin-left": "500px",
            "margin-top": "20px",
            "font-size": "110%",
            "text-align": "center",
        },
    )
    css_link = Div(
        text="<link rel='stylesheet' type='text/css' href='style/lexicon_manager.css'>",
        style={"font-size": "0%"},
    )

    js_script = Div(text="<input type='file' id='inputOS' hidden='true'>")

    title = Div(
        text="ABSApp",
        style={
            "font-size": "300%",
            "color": "royalblue",
            "font-weight": "bold",
            "margin-left": "500px",
        },
    )

    return row(
        column(
            row(children=[train_dropdown, lexicons_dropdown, inference_dropdown], width=500),
            row(text_status),
        ),
        css_link,
        js_script,
        widgetbox(title, width=900, height=84),
        widgetbox(architect_logo, width=400, height=84),
    ) 
Example #9
Source File: absa_solution.py    From nlp-architect with Apache License 2.0 5 votes vote down vote up
def _create_header(train_dropdown, inference_dropdown, text_status) -> layouts.Row:
    """Utility function for creating and styling the header row in the UI layout."""

    architect_logo = Div(
        text='<a href="http://nlp_architect.nervanasys.com"> <img border="0" '
        'src="style/nlp_architect.jpg" width="200"></a> by IntelĀ® AI Lab',
        style={
            "margin-left": "500px",
            "margin-top": "20px",
            "font-size": "110%",
            "text-align": "center",
        },
    )
    css_link = Div(
        text="<link rel='stylesheet' type='text/css' href='style/lexicon_manager.css'>",
        style={"font-size": "0%"},
    )

    js_script = Div(text="<input type='file' id='inputOS' hidden='true'>")

    title = Div(
        text="ABSApp",
        style={
            "font-size": "300%",
            "color": "royalblue",
            "font-weight": "bold",
            "margin-left": "500px",
        },
    )

    return row(
        column(
            row(children=[train_dropdown, lexicons_dropdown, inference_dropdown], width=500),
            row(text_status),
        ),
        css_link,
        js_script,
        widgetbox(title, width=900, height=84),
        widgetbox(architect_logo, width=400, height=84),
    ) 
Example #10
Source File: line.py    From choochoo with GNU General Public License v2.0 5 votes vote down vote up
def vtile(maps, n):
    return row([column(maps[i::n]) for i in range(n)]) 
Example #11
Source File: line.py    From choochoo with GNU General Public License v2.0 5 votes vote down vote up
def htile(maps, n):
    return column([row(maps[i:i + n]) for i in range(0, len(maps), n)]) 
Example #12
Source File: client_demo.py    From pairstrade-fyp-2019 with MIT License 5 votes vote down vote up
def build_widgets_wb(stock_list, metrics):
    # CODE SECTION: setup buttons, widgetbox name = controls_wb
    WIDGET_WIDTH = 250

    # ========== Select Stocks ============= #
    select_stk_1 = Select(width = WIDGET_WIDTH, title='Select Stock 1:', value = backtest_params["stk_0"], options=stock_list)
    select_stk_2 = Select(width = WIDGET_WIDTH, title='Select Stock 2:', value = backtest_params["stk_1"], options=stock_list)

    # ========== Strategy Type ============= #
    strategy_list = ['kalman', 'distance', 'cointegration', 'reinforcement learning']
    select_strategy = Select(width = WIDGET_WIDTH, title='Select Strategy:', value = backtest_params["strategy_type"], options=strategy_list)

    # ========== set start/end date ============= #
    # date time variables
    MAX_START = datetime.strptime(backtest_params["max_start"], "%Y-%m-%d").date()
    MAX_END = datetime.strptime(backtest_params["max_end"], "%Y-%m-%d").date()
    DEFAULT_START = datetime.strptime(backtest_params["backtest_start"], "%Y-%m-%d").date()
    DEFAULT_END = datetime.strptime(backtest_params["backtest_end"], "%Y-%m-%d").date()
    STEP = 1

    backtest_dates = DateRangeSlider(width = WIDGET_WIDTH, 
                                     start=MAX_START, end=MAX_END, 
                                     value=(DEFAULT_START, DEFAULT_END), 
                                     step=STEP, title="Backtest Date Range:")

    start_bt = Button(label="Backtest", button_type="success", width = WIDGET_WIDTH)

    # controls = column(select_stk_1, select_stk_2, select_strategy, backtest_dates, start_bt)
    controls_wb = widgetbox(select_stk_1, select_stk_2, select_strategy, backtest_dates, start_bt, width=300)

    # CODE SECTION: setup table, widgetbox name = metrics_wb
    master_wb = None
    if metrics is not None:
        metric_source = ColumnDataSource(metrics)
        metric_columns = [
            TableColumn(field="Metrics", title="Metrics"),
            TableColumn(field="Value", title="Performance"),
        ]

        metric_table = DataTable(source=metric_source, columns=metric_columns, width=300)
        master_wb = row(controls_wb, widgetbox(metric_table))
        
    else:
        logging.info("creating controls without table")
        master_wb = row(controls_wb)
    return master_wb, select_stk_1, select_stk_2, select_strategy, backtest_dates, start_bt 
Example #13
Source File: BokehRenderer.py    From BAC0 with GNU Lesser General Public License v3.0 5 votes vote down vote up
def modify_document(self, doc):
        self.network.whois()
        devices_df = self.network.devices
        dev = ColumnDataSource(devices_df)
        columns = [
            TableColumn(field=" Device ID", title="Dev ID"),
            TableColumn(field="Address", title="Address"),
            TableColumn(field="Manufacturer", title="Manuf"),
            TableColumn(field="Name", title="Name"),
        ]
        data_table = DataTable(source=dev, columns=columns)
        layout = row([data_table])
        doc.add_root(layout)
        doc.title = "BACnet devices"
        return doc 
Example #14
Source File: BokehRenderer.py    From BAC0 with GNU Lesser General Public License v3.0 5 votes vote down vote up
def modify_document(self, doc):
        self.network.whois()
        devices_df = self.network.devices
        dev = ColumnDataSource(devices_df)
        columns = [
            TableColumn(field=" Device ID", title="Dev ID"),
            TableColumn(field="Address", title="Address"),
            TableColumn(field="Manufacturer", title="Manuf"),
            TableColumn(field="Name", title="Name"),
        ]
        data_table = DataTable(source=dev, columns=columns)
        layout = row([data_table])
        doc.add_root(layout)
        doc.title = "BACnet devices"
        return doc 
Example #15
Source File: __init__.py    From arviz with Apache License 2.0 5 votes vote down vote up
def show_layout(ax, show=True, force_layout=False):
    """Create a layout and call bokeh show."""
    if show is None:
        show = rcParams["plot.bokeh.show"]
    if show:
        import bokeh.plotting as bkp

        layout = create_layout(ax, force_layout=force_layout)
        bkp.show(layout) 
Example #16
Source File: liveclient.py    From backtrader_plotting with GNU General Public License v3.0 5 votes vote down vote up
def _get_config_panel(self):
        def on_change_checkbox(vals):
            for i, f in enumerate(self._bokeh.figurepages[0].figure_envs):
                if i > 1:
                    continue
                f.figure.visible = i in vals

        self._slider_aspectratio = Slider(value=self._scheme.plotaspectratio, start=0.1, end=10.0, step=0.1)

        button = Button(label="Save", button_type="success")
        button.on_click(self.on_button_save_config)

        r1 = row(children=[Div(text='Aspect Ratio', margin=(15, 10, 0, 10)), self._slider_aspectratio])

        return Panel(child=column(children=[r1, button]), title='Config') 
Example #17
Source File: liveclient.py    From backtrader_plotting with GNU General Public License v3.0 5 votes vote down vote up
def __init__(self, doc: Document, push_fnc, bokeh_fac: callable, push_data_fnc:callable, strategy: bt.Strategy, figurepage_idx: int = 0, lookback: int = 20):
        self._slider_aspectratio = None
        self._push_data_fnc = push_data_fnc
        self._push_fnc = push_fnc
        self._figurepage_idx = figurepage_idx
        self.last_data_index = -1
        self._lookback = lookback
        self._strategy = strategy
        self._current_group = None
        self.document = doc

        self._bokeh_fac = bokeh_fac
        self._bokeh = None

        bokeh = self._bokeh_fac()  # temporary bokeh object to get tradingdomains and scheme
        self._scheme = copy(bokeh.p.scheme)  # preserve original scheme as originally provided by the user

        tradingdomains = bokeh.list_tradingdomains(strategy)
        self._current_group = tradingdomains[0]
        self._select_tradingdomain = Select(value=self._current_group, options=tradingdomains)
        self._select_tradingdomain.on_change('value', self._on_select_group)

        btn_refresh_analyzers = Button(label='Refresh Analyzers', width=100)
        btn_refresh_analyzers.on_click(self._on_click_refresh_analyzers)

        td_label = Div(text="Trading Domain:", margin=(9, 5, 15, 5))
        controls = row(children=[td_label, self._select_tradingdomain, btn_refresh_analyzers])
        self.model = column(children=[controls, Tabs(tabs=[])], sizing_mode=self._scheme.plot_sizing_mode)

        # append meta tab
        meta = Div(text=metadata.get_metadata_div(strategy))
        self._panel_metadata = Panel(child=meta, title="Meta")

        self._refreshmodel() 
Example #18
Source File: __init__.py    From arviz with Apache License 2.0 4 votes vote down vote up
def create_layout(ax, force_layout=False):
    """Transform bokeh array of figures to layout."""
    ax = np.atleast_2d(ax)
    subplot_order = rcParams["plot.bokeh.layout.order"]
    if force_layout:
        from bokeh.layouts import gridplot as layout

        ax = ax.tolist()
        layout_args = {
            "sizing_mode": rcParams["plot.bokeh.layout.sizing_mode"],
            "toolbar_location": rcParams["plot.bokeh.layout.toolbar_location"],
        }
    elif any(item in subplot_order for item in ("row", "column")):
        # check number of rows
        match = re.match(r"(\d*)(row|column)", subplot_order)
        n = int(match.group(1)) if match.group(1) is not None else 1
        subplot_order = match.group(2)
        # set up 1D list of axes
        ax = [item for item in ax.ravel().tolist() if item is not None]
        layout_args = {"sizing_mode": rcParams["plot.bokeh.layout.sizing_mode"]}
        if subplot_order == "row" and n == 1:
            from bokeh.layouts import row as layout
        elif subplot_order == "column" and n == 1:
            from bokeh.layouts import column as layout
        else:
            from bokeh.layouts import layout

        if n != 1:
            ax = np.array(ax + [None for _ in range(int(np.ceil(len(ax) / n)) - len(ax))])
            if subplot_order == "row":
                ax = ax.reshape(n, -1)
            else:
                ax = ax.reshape(-1, n)
            ax = ax.tolist()
    else:
        if subplot_order in ("square", "square_trimmed"):
            ax = [item for item in ax.ravel().tolist() if item is not None]
            n = int(np.ceil(len(ax) ** 0.5))
            ax = ax + [None for _ in range(n ** 2 - len(ax))]
            ax = np.array(ax).reshape(n, n)
        ax = ax.tolist()
        if (subplot_order == "square_trimmed") and any(
            all(item is None for item in row) for row in ax
        ):
            from bokeh.layouts import layout

            ax = [row for row in ax if not all(item is None for item in row)]
            layout_args = {"sizing_mode": rcParams["plot.bokeh.layout.sizing_mode"]}
        else:
            from bokeh.layouts import gridplot as layout

            layout_args = {
                "sizing_mode": rcParams["plot.bokeh.layout.sizing_mode"],
                "toolbar_location": rcParams["plot.bokeh.layout.toolbar_location"],
            }
    # ignore "fixed" sizing_mode without explicit width and height
    if layout_args.get("sizing_mode", "") == "fixed":
        layout_args.pop("sizing_mode")
    return layout(ax, **layout_args) 
Example #19
Source File: view.py    From osspolice with GNU General Public License v3.0 4 votes vote down vote up
def update(self):
        try:
            new_df, new_df_dict = self.safe_get_dataframe(self.source)
            # source changed, but original source doesn't
            row_changed = len(self.source.data['path']) != len(self.original_source.data['path'])
            if row_changed:
                self.logger.debug("source has %s rows, tmp source has %s rows", len(self.source.data['path']), len(self.original_source.data['path']))
                old_df, _ = self.safe_get_dataframe(self.original_source, new_df_dict['myindex'])
            else:
                old_df, _ = self.safe_get_dataframe(self.original_source)

            new_df = new_df.sort_values(by=['myindex'], ascending=[True])
            new_df = new_df.reset_index(drop=True)
            old_df = old_df.sort_values(by=['myindex'], ascending=[True])
            old_df = old_df.reset_index(drop=True)
            assert_frame_equal(old_df, new_df)
            self.logger.debug("nothing changed!")
        except AssertionError:
            # build a mapping between id and myindex.
            id2myindex = {index: row['myindex'] for index, row in old_df.iterrows()}

            # reference link
            # http://stackoverflow.com/questions/17095101/outputting-difference-in-two-pandas-dataframes-side-by-side-highlighting-the-d
            ne_stacked = (old_df != new_df).stack()
            changed = ne_stacked[ne_stacked]
            changed.index.names = ['id', 'col']
            different_locations = np.where(old_df != new_df)
            changed_from = old_df.values[different_locations]
            changed_to = new_df.values[different_locations]
            changed_df = pd.DataFrame({'from': changed_from, 'to': changed_to}, index=changed.index)
            self.logger.debug("update data: %s", changed_df)

            # generate patch dict and redis name, key, value update queries
            patch_dict = {}
            for index, row in changed_df.iterrows():
                row_id, column_id = index
                patch_dict.setdefault(column_id, [])
                myindex = id2myindex[row_id]
                path = old_df['path'].iloc[row_id]
                patch_dict[column_id].append((myindex, row['to']))
                # self.logger.info("updating name %s, key %s, value %s (old value %s)", path, column_id, row['to'], row['from'])
                self.update_redis_data(path, column_id, row['to'])
            self.update_display_data(patch_dict)
            self.logger.info("patch dict is: %s", patch_dict)
        except Exception as e:
            self.logger.error("Unexpected error: %s", str(e))


    ###########################################################
    # Create UI
    ########################################################### 
Example #20
Source File: bokeh_sliders.py    From signaltrain with GNU General Public License v3.0 4 votes vote down vote up
def update_effect(attrname, old, new):
    global effect, model, knob_names, knob_ranges, num_knobs, knob_sliders
    # match the menu option with the right entry in effects_dict
    long_name = effect_select.value
    plot.title.text = f"Trying to setup effect '{long_name}'..."
    shortname = ''
    for key, val in effects_dict.items():
        if val['name'] == long_name:
            shortname = key
            break
    if '' == shortname:
        plot.title.text = f"**ERROR: Effect '{long_name}' not defined**"
        return
    effect = effects_dict[shortname]['effect']
    num_knobs = 0
    if effect is not None:
        knob_names, knob_ranges = effect.knob_names, np.array(effect.knob_ranges)
        num_knobs = len(knob_names)

    # try to read the checkpoint file
    checkpoint_file = effects_dict[shortname]['checkpoint']
    model = setup_model(checkpoint_file, fatal=False)
    if model is  None:
        msg = f"**ERROR: checkpoint file '{checkpoint_file}' not found**"
        print("\n",msg)
        plot.title.text = msg

    # rebuild the entire display  (because knobs have changed)
    knob_sliders = []
    if num_knobs > 0:
        knobs_wc = knob_ranges.mean(axis=1)
        for k in range(num_knobs):
            start, end = knob_ranges[k][0], knob_ranges[k][1]
            mid = knobs_wc[k]
            step = (end-start)/25
            tmp = Slider(title=knob_names[k], value=mid, start=start, end=end, step=step)
            knob_sliders.append(tmp)
        for w in knob_sliders:  # since we now defined new widgets, we need triggers for them
            w.on_change('value', update_data)

    inputs = column([effect_select, input_select]+knob_sliders )
    curdoc().clear()
    curdoc().add_root(row(inputs, plot, width=800))
    curdoc().title = "SignalTrain Demo"

    update_data(attrname, old, new)