bokeh.models.Slider

Here are the examples of the python api bokeh.models.Slider taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

25 Examples 7

3 View Source File : config.py
License : GNU General Public License v3.0
Project Creator : happydasch

    def _create_lookback_config(self):
        title = Paragraph(
            text='Lookback period',
            css_classes=['config-title'])
        self.sld_lookback = Slider(
            title='Period for data to plot',
            value=self._client.lookback,
            start=1, end=200, step=1)
        return column([title, self.sld_lookback], sizing_mode='stretch_width')

    def _apply_lookback_config(self):

3 View Source File : feature.py
License : MIT License
Project Creator : phurwicz

    def _setup_search_widgets(self):
        """
        ???+ note "Create similarity search widgets."
        """
        self.search_sim = TextInput(
            title=f"{self.__class__.PRIMARY_FEATURE} similarity search (enter URL)".capitalize(),
            width_policy="fit",
            height_policy="fit",
        )
        self.search_threshold = Slider(
            start=0.0,
            end=1.0,
            value=0.9,
            # fewer steps allowed because refreshing search result can be expensive
            step=0.1,
            title="Similarity threshold",
        )

    def _search_watch_widgets(self):

3 View Source File : test_callbacks.py
License : MIT License
Project Creator : rthorst

def test_js_callback():
    slider = Slider()

    cb = CustomJS(code="foo();", args=dict(x=slider))
    assert 'foo()' in cb.code
    assert cb.args['x'] is slider

    cb = CustomJS(code="foo();", args=dict(x=3))
    assert 'foo()' in cb.code
    assert cb.args['x'] == 3

    with raises(AttributeError):  # kwargs not supported
        CustomJS(code="foo();", x=slider)


def test_py_callback():

3 View Source File : test_formatters.py
License : MIT License
Project Creator : rthorst

def test_functickformatter_from_py_func_with_args():

    slider = Slider()

    def convert_to_minutes(x=slider):
        return tick * 60 # noqa

    formatter = FuncTickFormatter.from_py_func(convert_to_minutes)
    js_code = pscript.py2js(convert_to_minutes, 'formatter')

    function_wrapper = formatter.code.replace(js_code, '')

    assert function_wrapper == "return formatter(x);\n"
    assert formatter.args['x'] is slider

def test_functickformatter_bad_pyfunc_formats():

0 View Source File : visualiser.py
License : BSD 3-Clause "New" or "Revised" License
Project Creator : alexjonesphd

def explore(model, display='combined'):
    """ Allows a user to explore the model outputs using Bokeh, using sliders to adjust predicted shape and texture variables.
    This function will NOT run outside of a Jupyter Notebook.

    Parameters
    ----------
    model : an instance of the Modeller class on which .fit() has been called.

    display : a string specifying the kind of data the user would like to see. Accepts 'texture' to just show texture changes or 'shape'
              to visualise landmark deformation. The default argument visualises both shape and texture changing simultaneously.
    """

    # Set up the notebook output
    output_notebook()

    def make_document(doc):
        """ Internal function to create the document for visualisation. Hidden from users who need only call outer function with a fitted model.
        """

        # Use the model to predict an average representationof  data, using the mean value of each predictor
        centred_predict = model.master_data_frame.mean().to_dict()
        _, final_im, shape, texture_im = model.predict(**centred_predict)

        # Call the image tidy function to change RGB texture to RGBA
        final_im = _image_tidy(final_im)
        texture = _image_tidy(texture_im)

        # Set up the plot for the shape coordinates ###############################
        # Define a column data source
        shape_source = ColumnDataSource( {'x': shape[:,0], 'y': shape[:,1]} )

        # Instantiate plot object for shape coordinates
        shape_plot = figure(title = 'Predicted Shape', y_range = (900, 0), x_range = (0, 900))
        shape_plot.cross('x', 'y', size = 10, source = shape_source)

        # Define hover tool and add to plot
        hover = HoverTool( tooltips = [('x', '@x'), ('y', '@y')] )
        shape_plot.add_tools(hover)
        ###########################################################################

        # Set up a column data source for the actual warped face ##################
        # Define a column data source
        warp_source = ColumnDataSource( {'image': [final_im]} )

        # Instantiate plot object for warped image - add a constant extra few pixels to make sure image is not squashed to window
        warp_image_plot = figure(title = 'Predicted Face', y_range = (0, model.image_dims[0]+150), x_range = (0, model.image_dims[1]+150))
        warp_image_plot.image_rgba(image = 'image', x=0, y=0, dw=model.image_dims[1], dh=model.image_dims[0], source=warp_source)

        # Set up a column data source for the texture-only face ###################
        # Define a column data source
        texture_source = ColumnDataSource( { 'image': [texture] } )

        # Instantiate plot object for shape-free face
        image_plot = figure(title = 'Predicted Texture', y_range = (0, model.image_dims[0]+150), x_range = (0, model.image_dims[1]+150) )
        image_plot.image_rgba( image = 'image', x=0, y=0, dw=model.image_dims[1], dh=model.image_dims[0], source=texture_source)
        ###########################################################################

        # Define the internal callback function to update objects interactively
        def callback(attr, old, new):
            """ Bokeh callback for updating glyphs
            """

            # Iterate over the traits, get their title and their value and store in the dictionary
            predictor_dict = {}
            for slide in sliders:
                predictor_dict[ slide.title ] = slide.value

            # Use this dictionary to feed to the model's predict method, generating new ouput to show
            _, final_im, shape, texture = model.predict(**predictor_dict)

            # Fix the images for show
            final_im = _image_tidy(final_im)
            texture = _image_tidy(texture)

            # Update data sources with the new information
            shape_source.data = {'x':shape[:,0], 'y':shape[:,1]}
            warp_source.data = {'image':[final_im]}
            texture_source.data = {'image':[texture]}

        ###########################################################################
        # Set up sliders to alter properties
        sliders = []
        for trait in model.trait_list:

            #  Get the middle and far end points by applying mean, min, and max, and rounding to zero
            avg, mini, maxi = model.master_data_frame[trait].apply(['mean', 'min', 'max']).round()

            slider = Slider(title = trait, start = mini, end = maxi, step = 1, value = avg)
            slider.on_change('value', callback)
            sliders.append(slider)

        ###########################################################################
        # Set layout according to specification of user, extract from dictionary
        layout_dict = {'combined':warp_image_plot, 'texture':image_plot, 'shape':shape_plot}

        layout = row([widgetbox(sliders), layout_dict[display]])

        # Update and add to curdoc
        doc.add_root(layout)

    # Initialise server with the make_document function defined above
    show(make_document)

0 View Source File : plotting.py
License : BSD 3-Clause "New" or "Revised" License
Project Creator : FeatureLabs

def dendrogram(D, figargs=None):
    '''Creates a dendrogram plot.
    This plot can show full structure of a given dendrogram.

    Args:
        D (henchman.selection.Dendrogram): An initialized dendrogram object

    Examples:
        >>> from henchman.selection import Dendrogram
        >>> from henchman.plotting import show
        >>> import henchman.plotting as hplot
        >>> D = Dendrogram(X)
        >>> plot = hplot.dendrogram(D)
        >>> show(plot)
    '''
    if figargs is None:
        return lambda figargs: dendrogram(D, figargs=figargs)
    G = nx.Graph()

    vertices_source = ColumnDataSource(
        pd.DataFrame({'index': D.columns.keys(),
                      'desc': list(D.columns.values())}))
    edges_source = ColumnDataSource(
        pd.DataFrame(D.edges[0]).rename(
            columns={1: 'end', 0: 'start'}))
    step_source = ColumnDataSource(
        pd.DataFrame({'step': [0],
                      'thresh': [D.threshlist[0]],
                      'components': [len(D.graphs[0])]}))

    G.add_nodes_from([str(x) for x in vertices_source.data['index']])
    G.add_edges_from(zip(
        [str(x) for x in edges_source.data['start']],
        [str(x) for x in edges_source.data['end']]))

    graph_renderer = from_networkx(G, nx.circular_layout,
                                   scale=1, center=(0, 0))

    graph_renderer.node_renderer.data_source = vertices_source
    graph_renderer.node_renderer.view = CDSView(source=vertices_source)
    graph_renderer.edge_renderer.data_source = edges_source
    graph_renderer.edge_renderer.view = CDSView(source=edges_source)

    plot = Plot(plot_width=400, plot_height=400,
                x_range=Range1d(-1.1, 1.1),
                y_range=Range1d(-1.1, 1.1))
    plot.title.text = "Feature Connectivity"
    graph_renderer.node_renderer.glyph = Circle(
        size=5, fill_color=Spectral4[0])
    graph_renderer.node_renderer.selection_glyph = Circle(
        size=15, fill_color=Spectral4[2])
    graph_renderer.edge_renderer.data_source = edges_source
    graph_renderer.edge_renderer.glyph = MultiLine(line_color="#CCCCCC",
                                                   line_alpha=0.6,
                                                   line_width=.5)
    graph_renderer.edge_renderer.selection_glyph = MultiLine(
        line_color=Spectral4[2],
        line_width=3)
    graph_renderer.node_renderer.hover_glyph = Circle(
        size=5,
        fill_color=Spectral4[1])
    graph_renderer.selection_policy = NodesAndLinkedEdges()
    graph_renderer.inspection_policy = NodesAndLinkedEdges()

    plot.renderers.append(graph_renderer)

    plot.add_tools(
        HoverTool(tooltips=[("feature", "@desc"),
                            ("index", "@index"), ]),
        TapTool(),
        BoxZoomTool(),
        SaveTool(),
        ResetTool())

    plot = _modify_plot(plot, figargs)

    if figargs['static']:
        return plot

    def modify_doc(doc, D, figargs):
        data_table = DataTable(source=step_source,
                               columns=[TableColumn(field='step',
                                                    title='Step'),
                                        TableColumn(field='thresh',
                                                    title='Thresh'),
                                        TableColumn(field='components',
                                                    title='Components')],
                               height=50, width=400)

        def callback(attr, old, new):
            try:
                edges = D.edges[slider.value]
                edges_source.data = ColumnDataSource(
                    pd.DataFrame(edges).rename(columns={1: 'end',
                                                        0: 'start'})).data
                step_source.data = ColumnDataSource(
                    {'step': [slider.value],
                     'thresh': [D.threshlist[slider.value]],
                     'components': [len(D.graphs[slider.value])]}).data
            except Exception as e:
                print(e)

        slider = Slider(start=0,
                        end=(len(D.edges) - 1),
                        value=0,
                        step=1,
                        title="Step")
        slider.on_change('value', callback)

        doc.add_root(column(slider, data_table, plot))
    return lambda doc: modify_doc(doc, D, figargs)


def f1(X, y, model, n_precs=1000, n_splits=1, figargs=None):

0 View Source File : plotting.py
License : BSD 3-Clause "New" or "Revised" License
Project Creator : FeatureLabs

def _piechart_widgets(col, sort, mergepast, drop_n, callback):
    if sort:
        active = [0]
    else:
        active = []
    sorted_button = CheckboxGroup(
        labels=["Sorted"], active=active)
    sorted_button.on_change('active', callback)

    merge_slider = Slider(start=1, end=col.nunique(),
                          value=mergepast or col.nunique(), step=1,
                          title="Merge Slider")
    merge_slider.on_change('value', callback)
    drop_slider = Slider(start=0, end=col.nunique(),
                         value=drop_n or 0, step=1,
                         title="Drop Slider")
    drop_slider.on_change('value', callback)
    return sorted_button, merge_slider, drop_slider


# Timeseries Utilities #


def _make_timeseries_source(col_1, col_2, col_max=None, col_min=None, n_bins=10, aggregate='mean'):

0 View Source File : plotting.py
License : BSD 3-Clause "New" or "Revised" License
Project Creator : FeatureLabs

def _timeseries_widgets(col_1, col_2, col_max, col_min, n_bins, aggregate, callback):
    col_1_time = pd.to_datetime(col_1)
    if col_max is None:
        col_max = col_1_time.max()
    if col_min is None:
        col_min = col_1_time.min()

    slider = Slider(start=1, end=100,
                    value=n_bins, step=1,
                    title="Bins")
    slider.on_change('value', callback)

    range_select = DateRangeSlider(start=col_1_time.min(),
                                   end=col_1_time.max(),
                                   value=(col_min,
                                          col_max),
                                   step=1, title='Range', format='%R %F')
    range_select.on_change('value', callback)
    dropdown = Dropdown(value=aggregate, label=aggregate,
                        button_type="default",
                        menu=[('mean', 'mean'),
                              ('count', 'count'),
                              ('sum', 'sum'),
                              ('max', 'max'),
                              ('min', 'min')])
    dropdown.on_change('value', callback)
    return slider, range_select, dropdown

# Histogram Utilities #


def _make_histogram_source(col, y, n_bins, col_max, col_min, normalized):

0 View Source File : plotting.py
License : BSD 3-Clause "New" or "Revised" License
Project Creator : FeatureLabs

def _histogram_widgets(col, y, n_bins, col_max, col_min, callback):
    if col_max is None:
        col_max = col.max()
    if col_min is None:
        col_min = col.min()

    slider = Slider(start=1, end=100, value=n_bins, step=1, title="Bins")
    slider.on_change('value', callback)

    range_select = RangeSlider(start=col.min(),
                               end=col.max(),
                               value=(col_min, col_max),
                               step=5, title='Histogram Range')
    range_select.on_change('value', callback)
    return slider, range_select


# Scatter Utilities #

def _make_scatter_source(col_1, col_2, cat=None, label=None, aggregate='last'):

0 View Source File : figures.py
License : GNU General Public License v3.0
Project Creator : gotzl

def getLapSlider(ds, p0, r0, hover0, view):
    # Enable selection update with slider
    slider = Slider(start=0, end=len(ds.data['dist_lap']),value=0, step=50)

    # React on changes of the selection in the datasource. Display tooltips at the position of the selected point.
    code = """
    let ind = slider.value;
    let x = source.data.dist_lap[ind];
    let y = source.data.speedkmh[ind];

    function get_view(views, id) {
        for (const [key, value] of views.entries()) {
            if (key.id === id) {
                return value;
            }
        }
    }

    let fig_view = get_view(Bokeh.index["tabs"]._child_views, view);

    if (view === "trackmap") 
        fig_view = get_view(fig_view.child_views[0]
                    .child_views[1]
                    ._child_views, figure.id);

    if (view === "lapsdelta") {
        var lapsdelta_view = fig_view.child_views;
        fig_view = get_view(lapsdelta_view[lapsdelta_view.length-1]._child_views, figure.id);
    }

    let hover_view = get_view(fig_view.tool_views, hovertool.id);
    let renderer_view = get_view(fig_view.renderer_views, renderer.id);
    let xs = renderer_view.xscale.compute(x);
    let ys = renderer_view.yscale.compute(y);
    hover_view._inspect(xs, ys);
    source.selected.indices = [ind]; // this triggers c0/c1/cr selected glyph
    """
    callback = CustomJS(args=dict(hovertool=hover0,
                                  source=ds,
                                  figure=p0,
                                  view=view,
                                  slider=slider,
                                  renderer=r0), code=code)
    slider.js_on_change('value', callback)
    return slider


def getLapControls(ds, slider):

0 View Source File : config.py
License : GNU General Public License v3.0
Project Creator : happydasch

    def _create_aspectratio_config(self):
        self.sld_obs_ar = None
        self.sld_data_ar = None
        self.sld_vol_ar = None
        self.sld_ind_ar = None
        title = Paragraph(
            text='Aspect Ratios',
            css_classes=['config-title'])
        self.sld_obs_ar = Slider(
            title='Observer Aspect Ratio',
            value=self.scheme.obs_aspectratio,
            start=0.1, end=20.0, step=0.1)
        self.sld_data_ar = Slider(
            title='Data Aspect Ratio',
            value=self.scheme.data_aspectratio,
            start=0.1, end=20.0, step=0.1)
        self.sld_vol_ar = Slider(
            title='Volume Aspect Ratio',
            value=self.scheme.vol_aspectratio,
            start=0.1, end=20.0, step=0.1)
        self.sld_ind_ar = Slider(
            title='Indicator Aspect Ratio',
            value=self.scheme.ind_aspectratio,
            start=0.1, end=20.0, step=0.1)
        return column([title,
                       self.sld_obs_ar,
                       self.sld_data_ar,
                       self.sld_vol_ar,
                       self.sld_ind_ar])

    def _apply_aspectratio_config(self):

0 View Source File : test_links.py
License : BSD 3-Clause "New" or "Revised" License
Project Creator : holoviz

def test_bkwidget_hvplot_links(document, comm):
    from bokeh.models import Slider
    bokeh_widget = Slider(value=5, start=1, end=10, step=1e-1)
    points1 = hv.Points([1, 2, 3])

    Link(bokeh_widget, points1, properties={'value': 'glyph.size'})

    row = Row(points1, bokeh_widget)
    model = row.get_root(document, comm=comm)
    hv_views = row.select(HoloViews)

    assert len(hv_views) == 1
    slider = bokeh_widget
    scatter = hv_views[0]._plots[model.ref['id']][0].handles['glyph']

    link_customjs = slider.js_property_callbacks['change:value'][-1]
    assert link_customjs.args['source'] is slider
    assert link_customjs.args['target'] is scatter

    code = """
    var value = source['value'];
    value = value;
    value = value;
    try {
      var property = target.properties['size'];
      if (property !== undefined) { property.validate(value); }
    } catch(err) {
      console.log('WARNING: Could not set size on target, raised error: ' + err);
      return;
    }
    try {
      target['size'] = value;
    } catch(err) {
      console.log(err)
    }
    """
    assert link_customjs.code == code


def test_bkwidget_bkplot_links(document, comm):

0 View Source File : test_links.py
License : BSD 3-Clause "New" or "Revised" License
Project Creator : holoviz

def test_bkwidget_bkplot_links(document, comm):
    from bokeh.models import Slider
    bokeh_widget = Slider(value=5, start=1, end=10, step=1e-1)
    bokeh_fig = figure()
    scatter = bokeh_fig.scatter([1, 2, 3], [1, 2, 3])

    Link(bokeh_widget, scatter, properties={'value': 'glyph.size'})

    row = Row(bokeh_fig, bokeh_widget)
    row.get_root(document, comm=comm)

    slider = bokeh_widget

    link_customjs = slider.js_property_callbacks['change:value'][-1]
    assert link_customjs.args['source'] is slider
    assert link_customjs.args['target'] is scatter.glyph

    code = """
    var value = source['value'];
    value = value;
    value = value;
    try {
      var property = target.properties['size'];
      if (property !== undefined) { property.validate(value); }
    } catch(err) {
      console.log('WARNING: Could not set size on target, raised error: ' + err);
      return;
    }
    try {
      target['size'] = value;
    } catch(err) {
      console.log(err)
    }
    """
    assert link_customjs.code == code


def test_widget_bkplot_link(document, comm):

def tax_rate(plot_dict, data):  # noqa: U100
    def make_dataset(sel_year, tax_rate_dict_full):
        dataset = tax_rate_dict_full[sel_year]

        return ColumnDataSource(dataset)

    def setup_plot(src):
        p = figure(plot_width=800, plot_height=400, y_range=(-0.01, 0.5),)

        taxplot_dict = {
            "tax_rate": {"label": "Average Tax Rate", "color": "blue"},
            "overall_tax_rate": {
                "label": "Average Tax Rate incl. Soli",
                "color": "black",
            },
            "marginal_rate": {"label": "Marginal Tax Rate", "color": "red"},
            "overall_marginal_rate": {
                "label": "Marginal Tax Rate incl. Soli",
                "color": "green",
            },
        }

        for yvar in taxplot_dict.keys():
            p.line(
                x="income",
                y=yvar,
                source=src,
                line_width=2,
                line_color=taxplot_dict[yvar]["color"],
                legend_label=taxplot_dict[yvar]["label"],
            )

        plot = plotstyle(p, plot_dict)

        return plot

    def update_plot(attr, old, new):  # noqa: U100
        sel_year = year_selection.value
        new_src = make_dataset(sel_year, tax_rate_dict_full)

        src.data.update(new_src.data)

    tax_rate_dict_full = data

    year_selection = Slider(start=2002, end=2021, value=2021, step=1, title="Year")
    year_selection.on_change("value", update_plot)

    src = make_dataset(2021, tax_rate_dict_full)

    p = setup_plot(src)
    description = Div(text=plot_dict["description"], width=800,)

    layout = column(description, year_selection, p)

    tab = Panel(child=layout, title="Tax rate per taxable income")

    return tab

def wohngeld(plot_dict, data):
    def make_dataset(sel_year, hh_size, wg_dict):
        dataset = wg_dict[sel_year][hh_size]

        heatmap_source = pd.DataFrame(
            dataset.stack(), columns=["Wohngeld"]
        ).reset_index()
        heatmap_source.columns = ["Miete", "Einkommen", "Wohngeld"]

        return ColumnDataSource(heatmap_source)

    def update_plot(attr, old, new):  # noqa: U100
        sel_year = [1992, 2001, 2009, 2016, 2020, 2021][year_selection.active]
        hh_size = hh_size_selection.value
        new_src = make_dataset(sel_year, hh_size, wg_dict)

        src.data.update(new_src.data)

    def setup_plot(src):
        """
        Create the heatmap plot.

        src: ColumnDataSource
        """

        # Prepare a color pallete and color mapper
        mapper = LinearColorMapper(
            # force 0 to be mapped with white color
            palette=tuple(
                itertools.chain(["#FFFFFF"], tuple(reversed(Viridis256[1:])))
            ),
            low=0,
            high=1000,
        )

        # Actual figure setup
        p = figure(
            plot_width=800,
            plot_height=400,
            x_range=(src.data["Miete"].min(), src.data["Miete"].max()),
            y_range=(src.data["Einkommen"].min(), src.data["Einkommen"].max()),
            tools="hover",
            tooltips="Housing Benefit: @Wohngeld{0.0f}€",
        )

        p.rect(
            x="Miete",
            y="Einkommen",
            width=25,
            height=src.data["Einkommen"][1] - src.data["Einkommen"][0],
            source=src,
            line_color=transform("Wohngeld", mapper),
            fill_color=transform("Wohngeld", mapper),
        )

        color_bar = ColorBar(
            color_mapper=mapper,
            location=(0, 0),
            ticker=BasicTicker(desired_num_ticks=20),
            formatter=NumeralTickFormatter(format="0€"),
            label_standoff=12,
        )
        p.add_layout(color_bar, "right")

        plot = plotstyle(p, plot_dict)

        return plot

    wg_dict = data

    year_selection = RadioButtonGroup(
        labels=[str(i) for i in [1992, 2001, 2009, 2016, 2020, 2021]], active=5
    )
    year_selection.on_change("active", update_plot)

    hh_size_selection = Slider(start=1, end=12, value=4, step=1, title="Household Size")
    hh_size_selection.on_change("value", update_plot)

    src = make_dataset(2021, 4, wg_dict)

    p = setup_plot(src)

    description = Div(text=plot_dict["description"], width=1000,)

    year_label = Div(text="Year")

    layout = column(description, year_label, year_selection, hh_size_selection, p)

    tab = Panel(child=layout, title="Housing benefits")

    return tab

0 View Source File : interact.py
License : MIT License
Project Creator : nasa

def show_interact_widget(tpf, notebook_url='localhost:8888',
                         max_cadences=30000,
                         aperture_mask='pipeline',
                         exported_filename=None):
    """Display an interactive Jupyter Notebook widget to inspect the pixel data.

    The widget will show both the lightcurve and pixel data.  The pixel data
    supports pixel selection via Bokeh tap and box select tools in an
    interactive javascript user interface.

    Note: at this time, this feature only works inside an active Jupyter
    Notebook, and tends to be too slow when more than ~30,000 cadences
    are contained in the TPF (e.g. short cadence data).

    Parameters
    ----------
    tpf : lightkurve.TargetPixelFile
        Target Pixel File to interact with
    notebook_url: str
        Location of the Jupyter notebook page (default: "localhost:8888")
        When showing Bokeh applications, the Bokeh server must be
        explicitly configured to allow connections originating from
        different URLs. This parameter defaults to the standard notebook
        host and port. If you are running on a different location, you
        will need to supply this value for the application to display
        properly. If no protocol is supplied in the URL, e.g. if it is
        of the form "localhost:8888", then "http" will be used.
    max_cadences : int
        Raise a RuntimeError if the number of cadences shown is larger than
        this value. This limit helps keep browsers from becoming unresponsive.
    """
    try:
        import bokeh
        if bokeh.__version__[0] == '0':
            warnings.warn("interact() requires Bokeh version 1.0 or later", LightkurveWarning)
    except ImportError:
        log.error("The interact() tool requires the `bokeh` Python package; "
                  "you can install bokeh using e.g. `conda install bokeh`.")
        return None

    aperture_mask = tpf._parse_aperture_mask(aperture_mask)

    if exported_filename is None:
        exported_filename = make_default_export_name(tpf)
    try:
        exported_filename = str(exported_filename)
    except:
        log.error('Invalid input filename type for interact()')
        raise
    if ('.fits' not in exported_filename.lower()):
        exported_filename += '.fits'

    lc = tpf.to_lightcurve(aperture_mask=aperture_mask)

    npix = tpf.flux[0, :, :].size
    pixel_index_array = np.arange(0, npix, 1).reshape(tpf.flux[0].shape)

    # Bokeh cannot handle many data points
    # https://github.com/bokeh/bokeh/issues/7490
    if len(lc.cadenceno) > max_cadences:
        msg = 'Interact cannot display more than {} cadences.'
        raise RuntimeError(msg.format(max_cadences))

    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)

        # Create the TPF figure and its stretch slider
        pedestal = np.nanmin(tpf.flux)
        fig_tpf, stretch_slider = make_tpf_figure_elements(tpf, tpf_source,
                                                           pedestal=pedestal,
                                                           fiducial_frame=0)

        # 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 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 != []:
                selected_indices = np.array(new)
                selected_mask = np.isin(pixel_index_array, selected_indices)
                lc_new = tpf.to_lightcurve(aperture_mask=selected_mask)
                lc_source.data['flux'] = lc_new.flux
                ylims = get_lightcurve_y_limits(lc_source)
                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 != []:
                selected_indices = np.array(tpf_source.selected.indices)
                selected_mask = np.isin(pixel_index_array, selected_indices)
                lc_new = tpf.to_lightcurve(aperture_mask=selected_mask)
                lc_new.to_fits(exported_filename, overwrite=True,
                               flux_column_name='SAP_FLUX',
                               aperture_mask=selected_mask.astype(np.int),
                               SOURCE='lightkurve interact',
                               NOTE='custom mask',
                               MASKNPIX=np.nansum(selected_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)

    output_notebook(verbose=False, hide_banner=True)
    return show(create_interact_ui, notebook_url=notebook_url)


def show_skyview_widget(tpf, notebook_url='localhost:8888', magnitude_limit=18):

0 View Source File : interact_bls.py
License : MIT License
Project Creator : nasa

def show_interact_widget(lc, notebook_url='localhost:8888', minimum_period=None,
                         maximum_period=None, resolution=2000):
    """Show the BLS interact widget.

    Parameters
    ----------
    notebook_url: str
        Location of the Jupyter notebook page (default: "localhost:8888")
        When showing Bokeh applications, the Bokeh server must be
        explicitly configured to allow connections originating from
        different URLs. This parameter defaults to the standard notebook
        host and port. If you are running on a different location, you
        will need to supply this value for the application to display
        properly. If no protocol is supplied in the URL, e.g. if it is
        of the form "localhost:8888", then "http" will be used.
    minimum_period : float or None
        Minimum period to assess the BLS to. If None, default value of 0.3 days
        will be used.
    maximum_period : float or None
        Maximum period to evaluate the BLS to. If None, the time coverage of the
        lightcurve / 4 will be used.
    resolution : int
        Number of points to use in the BLS panel. Lower this value to have a faster
        but less accurate compute time. You can also vary this value using the
        Resolution Slider.
    """
    try:
        import bokeh
        if bokeh.__version__[0] == '0':
            warnings.warn("interact_bls() requires Bokeh version 1.0 or later", LightkurveWarning)
    except ImportError:
        log.error("The interact_bls() tool requires the `bokeh` package; "
                  "you can install bokeh using e.g. `conda install bokeh`.")
        return None

    try:
        from astropy.timeseries import BoxLeastSquares
    except ImportError:
        try:
            from astropy.stats import BoxLeastSquares
        except ImportError:
            log.error("The `interact_bls()` tool requires AstroPy v3.1 or later.")

    def _create_interact_ui(doc, minp=minimum_period, maxp=maximum_period, resolution=resolution):
        """Create BLS interact user interface."""
        if minp is None:
            minp = 0.3
        if maxp is None:
            maxp = (lc.time[-1] - lc.time[0])/2

        time_format = ''
        if lc.time_format == 'bkjd':
            time_format = ' - 2454833 days'
        if lc.time_format == 'btjd':
            time_format = ' - 2457000 days'

        # Some sliders
        duration_slider = Slider(start=0.01,
                                 end=0.5,
                                 value=0.05,
                                 step=0.01,
                                 title="Duration [Days]",
                                 width=400)

        npoints_slider = Slider(start=500,
                                end=10000,
                                value=resolution,
                                step=100,
                                title="BLS Resolution",
                                width=400)

        # Set up the period values, BLS model and best period
        period_values = np.logspace(np.log10(minp), np.log10(maxp), npoints_slider.value)
        period_values = period_values[(period_values > duration_slider.value) &
                                        (period_values   <   maxp)]
        model = BoxLeastSquares(lc.time, lc.flux)
        result = model.power(period_values, duration_slider.value)
        loc = np.argmax(result.power)
        best_period = result.period[loc]
        best_t0 = result.transit_time[loc]

        # Some Buttons
        double_button = Button(label="Double Period", button_type="danger", width=100)
        half_button = Button(label="Half Period", button_type="danger", width=100)
        text_output = Paragraph(text="Period: {} days, T0: {}{}".format(
                                                    np.round(best_period, 7),
                                                    np.round(best_t0, 7), time_format),
                                width=350, height=40)

        # Set up BLS source
        bls_source = prepare_bls_datasource(result, loc)
        bls_help_source = prepare_bls_help_source(bls_source, npoints_slider.value)

        # Set up the model LC
        mf = model.model(lc.time, best_period, duration_slider.value, best_t0)
        mf /= np.median(mf)
        mask = ~(convolve(np.asarray(mf == np.median(mf)), Box1DKernel(2)) > 0.9)
        model_lc = LightCurve(lc.time[mask], mf[mask])
        model_lc = model_lc.append(LightCurve([(lc.time[0] - best_t0) + best_period/2], [1]))
        model_lc = model_lc.append(LightCurve([(lc.time[0] - best_t0) + 3*best_period/2], [1]))

        model_lc_source = ColumnDataSource(data=dict(
                                     time=np.sort(model_lc.time),
                                     flux=model_lc.flux[np.argsort(model_lc.time)]))

        # Set up the LC
        nb = int(np.ceil(len(lc.flux)/5000))
        lc_source = prepare_lightcurve_datasource(lc[::nb])
        lc_help_source = prepare_lc_help_source(lc)

        # Set up folded LC
        nb = int(np.ceil(len(lc.flux)/10000))
        f = lc.fold(best_period, best_t0)
        f_source = prepare_folded_datasource(f[::nb])
        f_help_source = prepare_f_help_source(f)

        f_model_lc = model_lc.fold(best_period, best_t0)
        f_model_lc = LightCurve([-0.5], [1]).append(f_model_lc)
        f_model_lc = f_model_lc.append(LightCurve([0.5], [1]))

        f_model_lc_source = ColumnDataSource(data=dict(
                                 phase=f_model_lc.time,
                                 flux=f_model_lc.flux))

        def _update_light_curve_plot(event):
            """If we zoom in on LC plot, update the binning."""
            mint, maxt = fig_lc.x_range.start, fig_lc.x_range.end
            inwindow = (lc.time > mint) & (lc.time  <  maxt)
            nb = int(np.ceil(inwindow.sum()/5000))
            temp_lc = lc[inwindow]
            lc_source.data = {'time': temp_lc.time[::nb],
                              'flux': temp_lc.flux[::nb]}

        def _update_folded_plot(event):
            loc = np.argmax(bls_source.data['power'])
            best_period = bls_source.data['period'][loc]
            best_t0 = bls_source.data['transit_time'][loc]
            # Otherwise, we can just update the best_period index
            minphase, maxphase = fig_folded.x_range.start, fig_folded.x_range.end
            f = lc.fold(best_period, best_t0)
            inwindow = (f.time > minphase) & (f.time  <  maxphase)
            nb = int(np.ceil(inwindow.sum()/10000))
            f_source.data = {'phase': f[inwindow].time[::nb],
                             'flux': f[inwindow].flux[::nb]}

        # Function to update the widget
        def _update_params(all=False, best_period=None, best_t0=None):
            if all:
                # If we're updating everything, recalculate the BLS model
                minp, maxp = fig_bls.x_range.start, fig_bls.x_range.end
                period_values = np.logspace(np.log10(minp), np.log10(maxp), npoints_slider.value)
                ok = (period_values > duration_slider.value) & (period_values  <  maxp)
                if ok.sum() == 0:
                    return
                period_values = period_values[ok]
                result = model.power(period_values, duration_slider.value)
                ok = np.isfinite(result['power']) & np.isfinite(result['duration']) &\
                         np.isfinite(result['transit_time']) & np.isfinite(result['period'])
                bls_source.data = dict(
                                     period=result['period'][ok],
                                     power=result['power'][ok],
                                     duration=result['duration'][ok],
                                     transit_time=result['transit_time'][ok])
                loc = np.nanargmax(bls_source.data['power'])
                best_period = bls_source.data['period'][loc]
                best_t0 = bls_source.data['transit_time'][loc]

                minpow, maxpow = bls_source.data['power'].min()*0.95,  bls_source.data['power'].max()*1.05
                fig_bls.y_range.start = minpow
                fig_bls.y_range.end = maxpow

            # Otherwise, we can just update the best_period index
            minphase, maxphase = fig_folded.x_range.start, fig_folded.x_range.end
            f = lc.fold(best_period, best_t0)
            inwindow = (f.time > minphase) & (f.time  <  maxphase)
            nb = int(np.ceil(inwindow.sum()/10000))
            f_source.data = {'phase': f[inwindow].time[::nb],
                             'flux': f[inwindow].flux[::nb]}

            mf = model.model(lc.time, best_period, duration_slider.value, best_t0)
            mf /= np.median(mf)
            mask = ~(convolve(np.asarray(mf == np.median(mf)), Box1DKernel(2)) > 0.9)
            model_lc = LightCurve(lc.time[mask], mf[mask])

            model_lc_source.data = {'time': np.sort(model_lc.time),
                                    'flux': model_lc.flux[np.argsort(model_lc.time)]}

            f_model_lc = model_lc.fold(best_period, best_t0)
            f_model_lc = LightCurve([-0.5], [1]).append(f_model_lc)
            f_model_lc = f_model_lc.append(LightCurve([0.5], [1]))

            f_model_lc_source.data = {'phase': f_model_lc.time,
                                      'flux': f_model_lc.flux}

            vertical_line.update(location=best_period)
            fig_folded.title.text = 'Period: {} days \t T0: {}{}'.format(
                                        np.round(best_period, 7),
                                        np.round(best_t0, 7), time_format)
            text_output.text = "Period: {} days, \t T0: {}{}".format(
                                        np.round(best_period, 7),
                                        np.round(best_t0, 7), time_format)

        # Callbacks
        def _update_upon_period_selection(attr, old, new):
            """When we select a period we should just update a few things, but we should not recalculate model
            """
            if len(new) > 0:
                new = new[0]
                best_period = bls_source.data['period'][new]
                best_t0 = bls_source.data['transit_time'][new]
                _update_params(best_period=best_period, best_t0=best_t0)

        def _update_model_slider(attr, old, new):
            """If the duration slider is updated, then update the whole model set."""
            _update_params(all=True)

        def _update_model_slider_EVENT(event):
            """If we update the duration slider, we should update the whole model set.
            This is the same as the _update_model_slider but it has a different call signature...
            """
            _update_params(all=True)

        def _double_period_event():
            fig_bls.x_range.start *= 2
            fig_bls.x_range.end *= 2
            _update_params(all=True)

        def _half_period_event():
            fig_bls.x_range.start /= 2
            fig_bls.x_range.end /= 2
            _update_params(all=True)

        # Help Hover Call Backs
        def _update_folded_plot_help_reset(event):
            f_help_source.data['phase'] = [(np.max(f.time) - np.min(f.time)) * 0.98 + np.min(f.time)]
            f_help_source.data['flux'] = [(np.max(f.flux) - np.min(f.flux)) * 0.98 + np.min(f.flux)]

        def _update_folded_plot_help(event):
            f_help_source.data['phase'] = [(fig_folded.x_range.end - fig_folded.x_range.start) * 0.95 + fig_folded.x_range.start]
            f_help_source.data['flux'] = [(fig_folded.y_range.end - fig_folded.y_range.start) * 0.95 + fig_folded.y_range.start]

        def _update_lc_plot_help_reset(event):
            lc_help_source.data['time'] = [(np.max(lc.time) - np.min(lc.time)) * 0.98 + np.min(lc.time)]
            lc_help_source.data['flux'] = [(np.max(lc.flux) - np.min(lc.flux)) * 0.9 + np.min(lc.flux)]

        def _update_lc_plot_help(event):
            lc_help_source.data['time'] = [(fig_lc.x_range.end - fig_lc.x_range.start) * 0.95 + fig_lc.x_range.start]
            lc_help_source.data['flux'] = [(fig_lc.y_range.end - fig_lc.y_range.start) * 0.9 + fig_lc.y_range.start]

        def _update_bls_plot_help_event(event):
            bls_help_source.data['period'] = [bls_source.data['period'][int(npoints_slider.value*0.95)]]
            bls_help_source.data['power'] = [(np.max(bls_source.data['power']) - np.min(bls_source.data['power'])) * 0.98
                                             + np.min(bls_source.data['power'])]

        def _update_bls_plot_help(attr, old, new):
            bls_help_source.data['period'] = [bls_source.data['period'][int(npoints_slider.value*0.95)]]
            bls_help_source.data['power'] = [(np.max(bls_source.data['power']) - np.min(bls_source.data['power'])) * 0.98
                                             + np.min(bls_source.data['power'])]

        # Create all the figures.
        fig_folded = make_folded_figure_elements(f, f_model_lc, f_source, f_model_lc_source, f_help_source)
        fig_folded.title.text = 'Period: {} days \t T0: {}{}'.format(np.round(best_period, 7), np.round(best_t0, 5), time_format)
        fig_bls, vertical_line = make_bls_figure_elements(result, bls_source, bls_help_source)
        fig_lc = make_lightcurve_figure_elements(lc, model_lc, lc_source, model_lc_source, lc_help_source)

        # Map changes

        # If we click a new period, update
        bls_source.selected.on_change('indices', _update_upon_period_selection)

        # If we change the duration, update everything, including help button for BLS
        duration_slider.on_change('value', _update_model_slider)
        duration_slider.on_change('value', _update_bls_plot_help)

        # If we increase resolution, update everything
        npoints_slider.on_change('value', _update_model_slider)

        # Make sure the vertical line always goes to the best period.
        vertical_line.update(location=best_period)

        # If we pan in the BLS panel, update everything
        fig_bls.on_event(PanEnd, _update_model_slider_EVENT)
        fig_bls.on_event(Reset, _update_model_slider_EVENT)

        # If we pan in the LC panel, rebin the points
        fig_lc.on_event(PanEnd, _update_light_curve_plot)
        fig_lc.on_event(Reset, _update_light_curve_plot)

        # If we pan in the Folded panel, rebin the points
        fig_folded.on_event(PanEnd, _update_folded_plot)
        fig_folded.on_event(Reset, _update_folded_plot)

        # Deal with help button
        fig_bls.on_event(PanEnd, _update_bls_plot_help_event)
        fig_bls.on_event(Reset, _update_bls_plot_help_event)
        fig_folded.on_event(PanEnd, _update_folded_plot_help)
        fig_folded.on_event(Reset, _update_folded_plot_help_reset)
        fig_lc.on_event(PanEnd, _update_lc_plot_help)
        fig_lc.on_event(Reset, _update_lc_plot_help_reset)

        # Buttons
        double_button.on_click(_double_period_event)
        half_button.on_click(_half_period_event)

        # Layout the widget
        doc.add_root(layout([
                            [fig_bls, fig_folded],
                            fig_lc,
                            [Spacer(width=70), duration_slider, Spacer(width=50), npoints_slider],
                            [Spacer(width=70), double_button, Spacer(width=70), half_button, Spacer(width=300), text_output]
                                ]))

    output_notebook(verbose=False, hide_banner=True)
    return show(_create_interact_ui, notebook_url=notebook_url)

0 View Source File : geoplot.py
License : MIT License
Project Creator : PatrikHlobil

def geoplot(  # noqa C901
    gdf_in,
    geometry_column="geometry",
    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,
    colorbar_tick_format=None,
    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.layouts import column, row
    from bokeh.models import (
        BasicTicker,
        BoxZoomTool,
        ColorBar,
        ColumnDataSource,
        GeoJSONDataSource,
        HoverTool,
        LinearColorMapper,
        LogColorMapper,
        LogTicker,
        Select,
        Slider,
        WheelZoomTool,
    )
    from bokeh.models.callbacks import CustomJS
    from bokeh.models.widgets import Dropdown
    from bokeh.palettes import all_palettes
    from bokeh.plotting import show

    # 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(
                f"Can only plot GeoDataFrames/Series with single type of geometry (either Point, Line or Polygon). Provided is a GeoDataFrame/Series with types: {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",
        "match_aspect": True,
    }
    if figsize is not 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(epsg=3857, inplace=True)

        # Simplify shapes if wanted:
        if isinstance(simplify_shapes, numbers.Number):
            if layertypes[0] in ["Line", "Polygon"]:
                gdf[geometry_column] = gdf[geometry_column].simplify(simplify_shapes)
        elif simplify_shapes is not None:
            raise ValueError(
                "  <  simplify_shapes> parameter only accepts numbers or None."
            )

    # Check for category, dropdown or slider (choropleth map column):
    category_options = 0
    if category is not None:
        category_options += 1
        category_columns = [category]
    if dropdown is not None:
        category_options += 1
        category_columns = dropdown
    if slider is not 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(
            f"Could not find column '{category}' in GeoDataFrame. For  < category>, please provide an existing single column of the GeoDataFrame."
        )

    # 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(
                    f"Could not find column '{col}' for  < dropdown> in GeoDataFrame. "
                )

    # 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(
                    f"Could not find column '{col}' for  < slider> in GeoDataFrame. "
                )

        if slider_range is not 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(
                    f" < 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 ): {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(
                    f"Could not find  < colormap> with name {colormap}. The following predefined colormaps are supported (see also https://bokeh.pydata.org/en/latest/docs/reference/palettes.html ): {list(all_palettes.keys())}"
                )
        else:
            raise ValueError(
                f" < 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 ): {list(all_palettes.keys())}"
            )
    else:
        if isinstance(color, str):
            colormap = [color]
        elif color is None:
            colormap = ["blue"]
        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:
                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.")

                from pyproj import Transformer

                transformer = Transformer.from_crs("epsg:4326", "epsg:3857")
                xmin = transformer.transform(0, xmin)[0]
                xmax = transformer.transform(0, xmax)[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:
                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.")

                from pyproj import Transformer

                transformer = Transformer.from_crs("epsg:4326", "epsg:3857")
                ymin = transformer.transform(ymin, 0)[1]
                ymax = transformer.transform(ymax, 0)[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:
        figure_options["x_axis_label"] = (
            figure_options["x_axis_label"]
            if figure_options["x_axis_label"] is not None
            else "Longitute"
        )
        figure_options["y_axis_label"] = (
            figure_options["y_axis_label"]
            if figure_options["y_axis_label"] is not None
            else "Latitude"
        )
        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."
        )

    for t in p.tools:
        # Get ridd of zoom on axes:
        if isinstance(t, WheelZoomTool):
            t.zoom_on_axis = False
        # Make sure that box zoom matches aspect:
        if isinstance(t, BoxZoomTool):
            t.match_aspect = True

    # 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 category is not None:
        # Check if category column is numerical:
        if not issubclass(gdf[category].dtype.type, np.number):
            raise NotImplementedError(
                f" < category> plot only yet implemented for numerical columns. Column '{category}' is not numerical."
            )

        field = category
        colormapper_options = {"palette": colormap}
        if colormap_range is not 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 dropdown is not 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(
                    f" < dropdown> plot only yet implemented for numerical columns. Column '{col}' is not numerical."
                )

        field = dropdown[0]
        colormapper_options = {"palette": colormap}
        if colormap_range is not 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 slider is not 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(
                    f" < slider> plot only yet implemented for numerical columns. Column '{col}' is not numerical."
                )

        field = slider[0]
        colormapper_options = {"palette": colormap}
        if colormap_range is not 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_column, 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 category is not None:
                hovertool_columns = [category]
            elif dropdown is not None:
                hovertool_columns = dropdown
            elif slider is not None:
                hovertool_columns = slider
            else:
                hovertool_columns = []
        else:
            for col in hovertool_columns:
                if col not in gdf.columns:
                    raise ValueError(
                        f"Could not find columns '{col}' in GeoDataFrame.  < hovertool_columns> has to be a list of columns of the GeoDataFrame or the string 'all'."
                    )
    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_column]
    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_label=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_label=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, geometry_column)
        )

        # Plot polygons:
        glyph = p.multi_polygons(
            xs="__x__", ys="__y__", source=geo_source, legend_label=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()

        if colorbar_tick_format:
            colorbar_options["formatter"] = get_tick_formatter(colorbar_tick_format)

        colorbar = ColorBar(**colorbar_options)

        p.add_layout(colorbar, "right")

    # Add Dropdown Widget:
    if dropdown is not None:
        # Define Dropdown widget:
        dropdown_widget = Select(
            title="Select Choropleth Layer", options=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 slider is not 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;
                var i;
                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

0 View Source File : base.py
License : MIT License
Project Creator : phurwicz

    def value_patch_by_slider(self, col_original, col_patch, **kwargs):
        """
        ???+ note "Allow source values to be dynamically patched through a slider."
            | Param            | Type   | Description                  |
            | :--------------- | :----- | :--------------------------- |
            | `col_original`   | `str`  | column of values before the patch |
            | `col_patch`      | `str`  | column of list of values to use as patches |
            | `**kwargs`       |        | forwarded to the slider |

            [Reference](https://github.com/bokeh/bokeh/blob/2.4.2/examples/howto/patch_app.py)
        """
        # add a patch slider to widgets, if none exist
        if "patch_slider" not in self._dynamic_widgets:
            slider = Slider(start=0, end=1, value=0, step=1, **kwargs)
            slider.disabled = True
            self._dynamic_widgets["patch_slider"] = slider
        else:
            slider = self._dynamic_widgets["patch_slider"]

        # create a slider-adjusting callback exposed to the outside
        def adjust_slider():
            """
            Infer slider length from the number of patch values.
            """
            num_patches = None
            for _key, _df in self.dfs.items():
                assert (
                    col_patch in _df.columns
                ), f"Subset {_key} expecting column {col_patch} among columns, got {_df.columns}"
                # find all array lengths; note that the data subset can be empty
                _num_patches_seen = _df[col_patch].apply(len).values
                assert (
                    len(set(_num_patches_seen))   <  = 1
                ), f"Expecting consistent number of patches, got {_num_patches_seen}"
                _num_patches = _num_patches_seen[0] if _df.shape[0] > 0 else None

                # if a previous subset has implied the number of patches, run a consistency check
                if num_patches is None:
                    num_patches = _num_patches
                else:
                    assert (
                        num_patches == _num_patches
                    ), f"Conflicting number of patches: {num_patches} vs {_num_patches}"

            assert num_patches >= 2, f"Expecting at least 2 patches, got {num_patches}"
            slider.end = num_patches - 1
            slider.disabled = False

        self._dynamic_callbacks["adjust_patch_slider"] = adjust_slider

        # create the callback for patching values
        def update_patch(attr, old, new):
            for _key, _df in self.dfs.items():
                # calculate the patch corresponding to slider value
                _value = [_arr[new] for _arr in _df[col_patch].values]
                _slice = slice(_df.shape[0])
                _patch = {col_original: [(_slice, _value)]}
                self.sources[_key].patch(_patch)

        slider.on_change("value", update_patch)
        self._good(f"Patching {col_original} using {col_patch}")

    def _mandatory_column_defaults(self):

0 View Source File : neural.py
License : MIT License
Project Creator : phurwicz

    def _setup_widgets(self):
        """
        ???+ note "Bokeh widgets for changing hyperparameters through user interaction."
        """
        self.epochs_slider = Slider(start=1, end=50, value=1, step=1, title="# epochs")
        self.loglr_slider = Slider(
            title="learning rate",
            start=1.0,
            end=7.0,
            value=self.__class__.DEFAULT_OPTIM_LOGLR,
            step=0.1,
            format=FuncTickFormatter(code="return Math.pow(0.1, tick).toFixed(8)"),
        )

        def update_lr(attr, old, new):
            self._dynamic_params["optimizer"]["lr"] = 0.1**self.loglr_slider.value

        self.loglr_slider.on_change("value", update_lr)

    def _layout_widgets(self):

0 View Source File : main.py
License : MIT License
Project Creator : Psy-Fer

def bkapp(doc):
    global signal
    global ut
    global lt
    global show_segs
    show_segs = False
    ut = 0
    lt = 0
    if signal.any():
        ut = max(signal)
        lt = min(signal)
        source = ColumnDataSource(data={
            'signal'    : signal,
            'position'  : list(range(0,len(signal)))
            })

        p = figure()

        p.line('position','signal', source=source)

        p.add_tools(HoverTool(
            tooltips=[
                ('signal', '@signal'),
                ('position', '@position'),
            ],
            formatters={
                'signal'    : 'printf',
                'position'    : 'printf'
            },
            mode='vline'
        ))

        renderer = p.multi_line([[1,1]], [[1,1]], line_width=4, alpha=0.5, color='green')
        draw_tool = FreehandDrawTool(renderers=[renderer])
        p.add_tools(draw_tool)

        src = ColumnDataSource({
            'x':[1,1,1], 'y':[1,1,1], 'width':[1,1,1], 'height':[1,1,1]
        })
        box_renderer = p.rect('x', 'y', 'width', 'height', fill_alpha=0.4, fill_color='orange', line_color='orange', source=src)
        box_draw_tool = BoxEditTool(renderers=[box_renderer], empty_value=1, num_objects = 5)
        p.add_tools(box_draw_tool)

        ut_slider = Slider(start=lt, end=max(signal), value=max(signal), name='upper_thresh', step=1, title="Upper Threshold")
        lt_slider = Slider(start=min(signal), end=ut, value=min(signal), name='lower_thresh', step=1, title="Lower Threshold")

        def ut_callback(attr, old, new):
            global signal
            global ut
            global lt
            ut = new
            new_signal = scale_outliers(signal, ut, lt)
            source.data = {
                        'signal'    : new_signal,
                        'position'  : list(range(0,len(new_signal)))
                        }
            update_segs()

        def lt_callback(attr, old, new):
            global signal
            global ut
            global lt
            lt = new
            new_signal = scale_outliers(signal, ut, lt)
            source.data = {
                        'signal'    : new_signal,
                        'position'  : list(range(0,len(new_signal)))
                        }
            update_segs()

        ut_slider.on_change('value', ut_callback)
        lt_slider.on_change('value', lt_callback)

        segments = ColumnDataSource(data={
            'top'     : [1,1],
            'bottom'  : [1,1],
            'left'    : [1,1],
            'right'   : [1,1]
            })

        button = Toggle(label="View Segments", sizing_mode="scale_width")

        def segment_handler(new):
            global show_segs
            show_segs = new
            if not new:
                segments.data = {
                    'top'     : [1,1],
                    'bottom'  : [1,1],
                    'left'    : [1,1],
                    'right'   : [1,1]
                            }
            update_segs()

        button.on_click(segment_handler)

        err_slider = Slider(start=0, end=20, value=5, name='error', step=1, title="Allowable Error")
        err_win_slider = Slider(start=0, end=100, value=50, name='err_win', step=1, title="Error Window Size")
        min_win_slider = Slider(start=0, end=500, value=150, name='min_win', step=1, title="Minimum Window Size")
        max_merge_slider = Slider(start=0, end=100, value=50, name='max_merge', step=1, title="Max Merge Distance")
        stdev_scale_slider = Slider(start=0, end=5, value=0.75, name='stdev_scale', step=0.01, title="Standard Deviation Scale Factor")
        stall_len_slider = Slider(start=0, end=5, value=0.25, name='stall_len', step=0.01, title="Stall Length")

        p.quad(top='top',bottom='bottom',left='left',right='right',source=segments,fill_alpha=0.5,fill_color='pink',line_color='pink')

        def err_callback(atrr, old, new):
            global err
            err = new
            update_segs()

        def err_win_callback(atrr, old, new):
            global err_win
            err_win = new
            update_segs()

        def min_win_callback(atrr, old, new):
            global min_win
            min_win = new
            update_segs()

        def max_merge_callback(atrr, old, new):
            global max_merge
            max_merge = new
            update_segs()

        def stdev_scale_callback(atrr, old, new):
            global stdev_scale
            stdev_scale = new
            update_segs()

        def stall_len_callback(atrr, old, new):
            global stall_len
            stall_len = new
            update_segs()

        def update_segs():
            #need to take into account the modified signal- somehow access it?
            global err
            global err_win
            global min_win
            global max_merge
            global stdev_scale
            global stall_len
            global ut
            global lt
            global show_segs
            left = None
            right = None
            if show_segs:
                sig = scale_outliers(signal, ut, lt)
                if sig.any():
                    left, right = get_segs(sig, err, err_win, min_win, max_merge, stdev_scale, stall_len)
                if left is not None and right is not None:
                    segments.data = {
                                'top'     :  np.full(len(left),1000),
                                'bottom'  :  np.full(len(left),0),
                                'left'    :  left,
                                'right'   :  right
                                }
                else:
                    segments.data = {
                        'top'     : [1,1],
                        'bottom'  : [1,1],
                        'left'    : [1,1],
                        'right'   : [1,1]
                                }


        err_slider.on_change('value', err_callback)
        err_win_slider.on_change('value', err_win_callback)
        min_win_slider.on_change('value', min_win_callback)
        max_merge_slider.on_change('value', max_merge_callback)
        stdev_scale_slider.on_change('value', stdev_scale_callback)
        stall_len_slider.on_change('value', stall_len_callback)

        doc.add_root(row(column(Spacer(height=10), ut_slider, lt_slider, Spacer(height=10), button, err_slider, err_win_slider, min_win_slider, max_merge_slider, stdev_scale_slider, stall_len_slider, Spacer(height=10), sizing_mode="stretch_height"), p, sizing_mode="stretch_both"))
        doc.theme = Theme(filename="theme.yaml")

def bk_worker():

0 View Source File : test_callbacks.py
License : MIT License
Project Creator : rthorst

def test_py_callback():
    slider = Slider()
    foo = None  # fool pyflakes

    def cb(x=slider):
        foo()
    cb = CustomJS.from_py_func(cb)
    assert 'foo()' in cb.code
    assert cb.args['x'] is slider

    def cb(x=4):
        foo()
    cb = CustomJS.from_py_func(cb)
    assert 'foo()' in cb.code
    assert cb.args['x'] == 4

#-----------------------------------------------------------------------------
# Dev API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Private API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------

0 View Source File : test_formatters.py
License : MIT License
Project Creator : rthorst

def test_functickformatter_from_coffeescript_with_args():
    coffee_code = dedent("""
         return slider.get("value") // 2 + tick
         """)

    slider = Slider()
    formatter = FuncTickFormatter.from_coffeescript(code=coffee_code, args={"slider": slider})

    assert formatter.code == dedent("""\
        return Math.floor(slider.get("value") / 2) + tick;
        """)
    assert formatter.args == {"slider": slider}

#-----------------------------------------------------------------------------
# Dev API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Private API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------

0 View Source File : test_transforms.py
License : MIT License
Project Creator : rthorst

def test_customjstransform_from_py_func_with_args():

    slider = Slider()

    def cosine(foo=slider):
        from pscript import window
        return window.Math.cos(x) # noqa

    def v_cosine(foo=slider):
        from pscript import window
        return [window.Math.cos(x) for x in xs] # noqa

    transform = CustomJSTransform.from_py_func(cosine, v_cosine)

    assert transform.args['foo'] is slider

    js_code = pscript.py2js(cosine, 'transformer')
    function_wrapper = transform.func.replace(js_code, '')
    assert function_wrapper == "return transformer(foo);\n"

    v_js_code = pscript.py2js(v_cosine, 'transformer')
    v_function_wrapper = transform.v_func.replace(v_js_code, '')
    assert v_function_wrapper == "return transformer(foo);\n"

def test_customjstransform_bad_pyfunc_formats():

0 View Source File : test_transforms.py
License : MIT License
Project Creator : rthorst

def test_customjstransform_from_coffeescript_with_args():
    code = "return foo.get('value') // 2 + x"
    v_code = "return [foo.get('value') // 2 + x for x in xs]"

    slider = Slider()
    formatter = CustomJSTransform.from_coffeescript(func=code, v_func=v_code, args={"foo": slider})

    assert formatter.func == dedent("""\
        return Math.floor(foo.get('value') / 2) + x;
        """)

    assert formatter.v_func == dedent("""\
        var x;
        return [
            (function () {
                var i, len, results;
                results = [];
                for (i = 0, len = xs.length; i   <   len; i++) {
                    x = xs[i];
                    results.push(Math.floor(foo.get('value') / 2) + x);
                }
                return results;
            })()
        ];
        """)

    assert formatter.args == {"foo": slider}

#-----------------------------------------------------------------------------
# Dev API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Private API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------