bokeh.layouts.column

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

155 Examples 7

3 Source : utils.py
with MIT License
from allenbai01

    def save(self, title='Training Results'):
        if len(self.figures) > 0:
            if os.path.isfile(self.plot_path):
                os.remove(self.plot_path)
            output_file(self.plot_path, title=title)
            plot = column(*self.figures)
            save(plot)
            self.figures = []
        self.results.to_csv(self.path, index=False, index_label=False)

    def load(self, path=None):

3 Source : utils.py
with MIT License
from allenbai01

    def show(self):
        if len(self.figures) > 0:
            plot = column(*self.figures)
            show(plot)

    #def plot(self, *kargs, **kwargs):
    #    line = Line(data=self.results, *kargs, **kwargs)
    #    self.figures.append(line)

    def image(self, *kargs, **kwargs):

3 Source : trending_delta4.py
with MIT License
from cutright

    def __do_layout(self):
        # TODO: Generalize for 1 or 2 groups
        self.layout = column(row(self.select_y, self.select_linac[1], self.select_linac[2], self.avg_len_input,
                                 self.percentile_input, self.bins_input),
                             row(self.select_energies[1], self.select_energies[2]),
                             row(self.start_date_picker, self.end_date_picker),
                             row(Div(text='Gamma Criteria: '), self.checkbox_button_group),
                             self.div_summary[1],
                             self.div_summary[2],
                             row(Spacer(width=10), self.fig),
                             Spacer(height=50),
                             row(Spacer(width=10), self.histogram),
                             Spacer(height=50),
                             row(Spacer(width=10), self.ichart),
                             row(self.div_center_line[1], self.div_ucl[1], self.div_lcl[1]),
                             row(self.div_center_line[2], self.div_ucl[2], self.div_lcl[2]))

    def update_source_ticker(self, attr, old, new):

3 Source : log.py
with Apache License 2.0
from Drajan

    def show(self, title=None):
        title = title or self.title
        if len(self.figures) > 0:
            plot = column(
                Div(text='  <  h1 align="center">{} < /h1>'.format(title)), *self.figures)
            show(plot)

    def plot(self, *kargs, **kwargs):

3 Source : figures.py
with GNU General Public License v3.0
from gotzl

def getTrackMapPanel(df):
    mode_select = Select(title="Mode:", value='speed',
                         options=['oversteer',
                                  'speed',
                                  'pedals',
                                  'throttle',
                                  'brake',
                                  'g_lon'])

    layout = column(mode_select, getTrackMap(df, view='trackmap'))

    def mode_change(attrname, old, new):
        layout.children[1] = getTrackMap(df, view='trackmap', mode=new)

    mode_select.on_change('value', mode_change)

    return layout

3 Source : analyzer.py
with GNU General Public License v3.0
from happydasch

    def _get_analyzer_info(self):
        tablegen = AnalysisTableGenerator(self._app.scheme)
        acolumns = []
        for analyzer in self._figurepage.analyzers:
            table_header, elements = tablegen.get_tables(analyzer)
            if table_header and elements:
                acolumns.append(column([table_header] + elements))
        info = gridplot(
            acolumns,
            ncols=self._app.scheme.analyzer_tab_num_cols,
            sizing_mode='stretch_width',
            toolbar_options={'logo': None})
        return info

    def _on_update_analyzer_info(self):

3 Source : config.py
with GNU General Public License v3.0
from happydasch

    def _create_fill_gaps_config(self):
        title = Paragraph(
            text='Fill Gaps',
            css_classes=['config-title'])

        if self._client.fill_gaps:
            active = [0]
        else:
            active = []
        self.chk_fill_gaps = CheckboxGroup(
            labels=['Fill gaps with data'],
            active=active)

        return column([title, self.chk_fill_gaps], sizing_mode='stretch_width')

    def _apply_fill_gaps_config(self):

3 Source : config.py
with GNU General Public License v3.0
from 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 Source : metadata.py
with GNU General Public License v3.0
from happydasch

    def _get_strategy(self, strategy):
        columns = []
        childs = []
        childs.append(self._get_title(f'Strategy: {obj2label(strategy)}'))
        childs.append(self._get_parameter_table(strategy.params))
        for o in strategy.observers:
            childs.append(self._get_title(f'Observer: {obj2label(o)}'))
            childs.append(self._get_parameter_table(o.params))
        for a in strategy.analyzers:
            childs.append(self._get_title(f'Analyzer: {obj2label(a)}{" [Analysis Table]" if hasattr(a, "get_analysis_table") else ""}'))
            childs.append(self._get_parameter_table(a.params))
        columns.append(column(childs))
        return columns

    def _get_indicators(self, strategy):

3 Source : metadata.py
with GNU General Public License v3.0
from happydasch

    def _get_indicators(self, strategy):
        columns = []
        childs = []
        inds = strategy.getindicators()
        for i in inds:
            if isinstance(i, bt.IndicatorBase):
                childs.append(self._get_title(
                    f'Indicator: {obj2label(i)}@{obj2data(i)}'))
                childs.append(self._get_parameter_table(i.params))
        columns.append(column(childs))
        return columns

    def _get_datas(self, strategy):

3 Source : source.py
with GNU General Public License v3.0
from happydasch

    def _get_panel(self):
        title = Paragraph(
            text='Source Code',
            css_classes=['panel-title'])
        child = column(
            [title,
             Div(text=self._getSource(),
                 css_classes=['source-pre'],
                 sizing_mode='stretch_width')],
            sizing_mode='stretch_width')
        return child, 'Source Code'

3 Source : edit.py
with GNU General Public License v3.0
from j-brady

    def init(self, doc):
        """ initialise the bokeh app """

        doc.add_root(
            column(
                self.intro_div,
                row(column(self.p, self.doc_link), column(self.data_table, self.tabs)),
                sizing_mode="stretch_both",
            )
        )
        doc.title = "peakipy: Edit Fits"

    @property

3 Source : _comparison.py
with MIT License
from metriculous-ml

def _html_figure_table(
    model_evaluations: Sequence[Evaluation], include_spacer: Optional[bool]
) -> str:
    html_output = ""

    rows = _figure_rows(model_evaluations, include_spacer=include_spacer)

    if rows:
        html_output += file_html(
            models=column(rows, sizing_mode="scale_width"),
            resources=CDN,
            title="Comparison",
        )

    return html_output


def _figure_rows(

3 Source : uibokeh_well.py
with Apache License 2.0
from OpendTect

    def display(self):
        if self.withui:
          self.tracklayout = bl.column(self.track)
          tracktab = bm.Panel(child=self.tracklayout, title="Plot")
          datatab = bm.Panel(child=self.data_ui, title="Data")
          settingstab = bm.Panel(child=self.settings_ui, title="Settings")
          self.tabs = bm.Tabs(tabs=[datatab, tracktab, settingstab])
          self.tabs.on_change('active', self._change_tab)
          return self.tabs
        else:
          return self.track

    def _getLogLimits(self, lognm):

3 Source : geoplot.py
with MIT License
from PatrikHlobil

def _get_figure(col):
    """Gets the bokeh.plotting.figure from a bokeh.layouts.column."""

    from bokeh.layouts import column
    from bokeh.plotting import figure

    for children in col.children:
        if isinstance(children, type(figure())):
            return children
        elif isinstance(children, type(column())):
            return _get_figure(children)


def convert_geoDataFrame_to_patches(gdf, geometry_column):

3 Source : base.py
with MIT License
from phurwicz

    def view(self):
        """
        ???+ note "Define the high-level visual layout of the whole explorer."
        """
        from bokeh.layouts import column

        return column(self._layout_widgets(), self.figure)

    def _build_tooltip(self, extra):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(
                column(self.search_pos, self.search_neg),
                column(self.search_filter_box),
            ),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehTextAnnotator(BokehDataAnnotator, BokehForText):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(self.search_pos, self.search_neg),
            row(self.annotator_input, self.annotator_apply),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehTextSoftLabel(BokehSoftLabelExplorer, BokehForText):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(self.search_pos, self.search_neg),
            row(self.score_filter),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehTextMargin(BokehMarginExplorer, BokehForText):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(self.search_pos, self.search_neg),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehTextSnorkel(BokehSnorkelExplorer, BokehForText):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(self.search_pos, self.search_neg),
            row(self.lf_apply_trigger, self.lf_filter_trigger, self.lf_list_refresher),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehAudioFinder(BokehDataFinder, BokehForAudio):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(
                column(self.search_sim, self.search_threshold),
                column(self.search_filter_box),
            ),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehAudioAnnotator(BokehDataAnnotator, BokehForAudio):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(self.search_sim, self.search_threshold),
            row(self.annotator_input, self.annotator_apply),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehAudioSoftLabel(BokehSoftLabelExplorer, BokehForAudio):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(self.search_sim, self.search_threshold),
            row(self.score_filter),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehAudioMargin(BokehMarginExplorer, BokehForAudio):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(self.search_sim, self.search_threshold),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehAudioSnorkel(BokehSnorkelExplorer, BokehForAudio):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(self.search_sim, self.search_threshold),
            row(self.lf_apply_trigger, self.lf_filter_trigger, self.lf_list_refresher),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehImageFinder(BokehDataFinder, BokehForImage):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(
                column(self.search_sim, self.search_threshold),
                column(self.search_filter_box),
            ),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehImageAnnotator(BokehDataAnnotator, BokehForImage):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(self.search_sim, self.search_threshold),
            row(self.annotator_input, self.annotator_apply),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehImageSoftLabel(BokehSoftLabelExplorer, BokehForImage):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(self.search_sim, self.search_threshold),
            row(self.score_filter),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehImageMargin(BokehMarginExplorer, BokehForImage):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(self.search_sim, self.search_threshold),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)


class BokehImageSnorkel(BokehSnorkelExplorer, BokehForImage):

3 Source : specialization.py
with MIT License
from phurwicz

    def _layout_widgets(self):
        """Define the layout of widgets."""
        layout_rows = (
            row(self.subset_toggle_widget_column, self.selection_option_box),
            row(self.search_sim, self.search_threshold),
            row(self.lf_apply_trigger, self.lf_filter_trigger, self.lf_list_refresher),
            row(self.dropdown_x_axis, self.dropdown_y_axis),
            row(*self._dynamic_widgets.values()),
        )
        return column(*layout_rows)

3 Source : subroutine.py
with MIT License
from phurwicz

def recipe_layout(*components, style="horizontal"):
    """
    ???+ note "Create a recipe-level layout of bokeh objects."

        | Param      | Type     | Description                          |
        | :--------- | :------- | :----------------------------------- |
        | `*components` | `bokeh` objects | objects to be plotted      |
        | `style`    | `str`    | "horizontal" or "vertical"           |
    """
    if style == "horizontal":
        return row(*components)
    elif style == "vertical":
        return column(*components)
    else:
        raise ValueError(f"Unexpected layout style {style}")


def get_explorer_class(task, feature):

3 Source : bokeh_helper.py
with MIT License
from phurwicz

def show_as_interactive(obj, **kwargs):
    """
    ???+ note "Wrap a bokeh LayoutDOM as an application to allow Python callbacks."

        Must have the same signature as `bokeh.io.show()`[https://docs.bokeh.org/en/latest/docs/reference/io.html#bokeh.io.show].
    """
    from bokeh.io import show
    from bokeh.models.layouts import LayoutDOM

    assert isinstance(obj, LayoutDOM), f"Expected Bokeh LayoutDOM, got {type(obj)}"

    def handle(doc):
        doc.add_root(column(obj))

    return show(handle, **kwargs)


def bokeh_hover_tooltip(

3 Source : test_layouts.py
with MIT License
from rthorst

def test_gridplot_merge_tools_nested():
    p1, p2, p3, p4, p5, p6, p7 = figure(), figure(), figure(), figure(), figure(), figure(), figure()
    r1 = row(p1, p2)
    r2 = row(p3, p4)
    c = column(row(p5), row(p6))

    gridplot([[r1, r2], [c, p7]], merge_tools=True)

    for p in p1, p2, p3, p4, p5, p6, p7:
        assert p.toolbar_location is None


def test_gridplot_None():

3 Source : log.py
with MIT License
from shunithaviv

    def show(self, title=None):
        title = title or self.title
        if len(self.figures) > 0:
            plot = column(
                Div(text='  <  h1 align="center">{} < /h1>'.format(title)), *self.figures)
            show(plot)

    def plot(self, x, y, title=None, xlabel=None, ylabel=None, legend=None,

3 Source : utils.py
with MIT License
from wenwei202

    def show(self):
        if len(self.figures) > 0:
            plot = column(*self.figures)
            show(plot)

    def plot(self, *kargs, **kwargs):

0 Source : line.py
with GNU Affero General Public License v3.0
from andrewcooke

def htile(maps, n):
    return column([row(maps[i:i + n]) for i in range(0, len(maps), n)])


def vtile(maps, n):

0 Source : line.py
with GNU Affero General Public License v3.0
from andrewcooke

def vtile(maps, n):
    return row([column(maps[i::n]) for i in range(n)])

0 Source : month.py
with GNU Affero General Public License v3.0
from andrewcooke

def month(month):

    f'''
    # Month: {month}
    '''

    '''
    $contents
    '''

    '''
    ## Preparation
    '''
    
    s = session('-v2')
    output_file(filename='/dev/null')
    map_size = 100
    month_start = to_date(month).replace(day=1)

    '''
    ## Generate Plot
    '''

    def days():

        for i in Calendar().iterweekdays():
            yield Div(text=f'  <  h2>{day_name[i]} < /h2>')

        day = month_start - dt.timedelta(days=month_start.weekday())
        while day.replace(day=1)  < = month_start:
            for weekday in range(7):
                if day.month == month_start.month:
                    contents = [Div(text=f' < h1>{day.strftime("%d")} < /h1>')]
                    for a in s.query(ActivityJournal). \
                            filter(ActivityJournal.start >= local_date_to_time(day),
                                   ActivityJournal.start  <  local_date_to_time(day + dt.timedelta(days=1))).all():
                        df = Statistics(s, activity_journal=a). \
                            by_name(ActivityReader, N.SPHERICAL_MERCATOR_X, N.SPHERICAL_MERCATOR_Y).df
                        contents.append(map_thumbnail(map_size, map_size, df, title=False))
                        df = Statistics(s, activity_journal=a). \
                            by_name(ActivityCalculator, N.ACTIVE_DISTANCE, N.ACTIVE_TIME).df
                        contents.append(Div(
                            text=f'{format_km(df[N.ACTIVE_DISTANCE][0])} {format_seconds(df[N.ACTIVE_TIME][0])}'))
                else:
                    contents = [Spacer()]
                yield column(contents)
                day += dt.timedelta(days=1)

    show(grid(list(days()), ncols=7))

0 Source : plot.py
with BSD 3-Clause "New" or "Revised" License
from canzarlab

def interactive(
    umap_object,
    labels=None,
    values=None,
    hover_data=None,
    theme=None,
    cmap="Blues",
    color_key=None,
    color_key_cmap="Spectral",
    background="white",
    width=800,
    height=800,
    point_size=None,
    subset_points=None,
    interactive_text_search=False,
    interactive_text_search_columns=None,
    interactive_text_search_alpha_contrast=0.95,
):
    """Create an interactive bokeh plot of a UMAP embedding.
    While static plots are useful, sometimes a plot that
    supports interactive zooming, and hover tooltips for
    individual points is much more desireable. This function
    provides a simple interface for creating such plots. The
    result is a bokeh plot that will be displayed in a notebook.

    Note that more complex tooltips etc. will require custom
    code -- this is merely meant to provide fast and easy
    access to interactive plotting.

    Parameters
    ----------
    umap_object: trained UMAP object
        A trained UMAP object that has a 2D embedding.

    labels: array, shape (n_samples,) (optional, default None)
        An array of labels (assumed integer or categorical),
        one for each data sample.
        This will be used for coloring the points in
        the plot according to their label. Note that
        this option is mutually exclusive to the ``values``
        option.

    values: array, shape (n_samples,) (optional, default None)
        An array of values (assumed float or continuous),
        one for each sample.
        This will be used for coloring the points in
        the plot according to a colorscale associated
        to the total range of values. Note that this
        option is mutually exclusive to the ``labels``
        option.

    hover_data: DataFrame, shape (n_samples, n_tooltip_features)
    (optional, default None)
        A dataframe of tooltip data. Each column of the dataframe
        should be a Series of length ``n_samples`` providing a value
        for each data point. Column names will be used for
        identifying information within the tooltip.

    theme: string (optional, default None)
        A color theme to use for plotting. A small set of
        predefined themes are provided which have relatively
        good aesthetics. Available themes are:
           * 'blue'
           * 'red'
           * 'green'
           * 'inferno'
           * 'fire'
           * 'viridis'
           * 'darkblue'
           * 'darkred'
           * 'darkgreen'

    cmap: string (optional, default 'Blues')
        The name of a matplotlib colormap to use for coloring
        or shading points. If no labels or values are passed
        this will be used for shading points according to
        density (largely only of relevance for very large
        datasets). If values are passed this will be used for
        shading according the value. Note that if theme
        is passed then this value will be overridden by the
        corresponding option of the theme.

    color_key: dict or array, shape (n_categories) (optional, default None)
        A way to assign colors to categoricals. This can either be
        an explicit dict mapping labels to colors (as strings of form
        '#RRGGBB'), or an array like object providing one color for
        each distinct category being provided in ``labels``. Either
        way this mapping will be used to color points according to
        the label. Note that if theme
        is passed then this value will be overridden by the
        corresponding option of the theme.

    color_key_cmap: string (optional, default 'Spectral')
        The name of a matplotlib colormap to use for categorical coloring.
        If an explicit ``color_key`` is not given a color mapping for
        categories can be generated from the label list and selecting
        a matching list of colors from the given colormap. Note
        that if theme
        is passed then this value will be overridden by the
        corresponding option of the theme.

    background: string (optional, default 'white')
        The color of the background. Usually this will be either
        'white' or 'black', but any color name will work. Ideally
        one wants to match this appropriately to the colors being
        used for points etc. This is one of the things that themes
        handle for you. Note that if theme
        is passed then this value will be overridden by the
        corresponding option of the theme.

    width: int (optional, default 800)
        The desired width of the plot in pixels.

    height: int (optional, default 800)
        The desired height of the plot in pixels

    point_size: int (optional, default None)
        The size of each point marker

    subset_points: array, shape (n_samples,) (optional, default None)
        A way to select a subset of points based on an array of boolean
        values.

    interactive_text_search: bool (optional, default False)
        Whether to include a text search widget above the interactive plot

    interactive_text_search_columns: list (optional, default None)
        Columns of data source to search. Searches labels and hover_data by default.

    interactive_text_search_alpha_contrast: float (optional, default 0.95)
        Alpha value for points matching text search. Alpha value for points
        not matching text search will be 1 - interactive_text_search_alpha_contrast

    Returns
    -------

    """
    if theme is not None:
        cmap = _themes[theme]["cmap"]
        color_key_cmap = _themes[theme]["color_key_cmap"]
        background = _themes[theme]["background"]

    if labels is not None and values is not None:
        raise ValueError(
            "Conflicting options; only one of labels or values should be set"
        )

    points = umap_object.embedding_
    if subset_points is not None:
        if len(subset_points) != points.shape[0]:
            raise ValueError(
                "Size of subset points ({}) does not match number of input points ({})".format(
                    len(subset_points), points.shape[0]
                )
            )
        points = points[subset_points]

    if points.shape[1] != 2:
        raise ValueError("Plotting is currently only implemented for 2D embeddings")

    if point_size is None:
        point_size = 100.0 / np.sqrt(points.shape[0])

    data = pd.DataFrame(umap_object.embedding_, columns=("x", "y"))

    if labels is not None:
        data["label"] = labels

        if color_key is None:
            unique_labels = np.unique(labels)
            num_labels = unique_labels.shape[0]
            color_key = _to_hex(
                plt.get_cmap(color_key_cmap)(np.linspace(0, 1, num_labels))
            )

        if isinstance(color_key, dict):
            data["color"] = pd.Series(labels).map(color_key)
        else:
            unique_labels = np.unique(labels)
            if len(color_key)   <   unique_labels.shape[0]:
                raise ValueError(
                    "Color key must have enough colors for the number of labels"
                )

            new_color_key = {k: color_key[i] for i, k in enumerate(unique_labels)}
            data["color"] = pd.Series(labels).map(new_color_key)

        colors = "color"

    elif values is not None:
        data["value"] = values
        palette = _to_hex(plt.get_cmap(cmap)(np.linspace(0, 1, 256)))
        colors = btr.linear_cmap(
            "value", palette, low=np.min(values), high=np.max(values)
        )

    else:
        colors = matplotlib.colors.rgb2hex(plt.get_cmap(cmap)(0.5))

    if subset_points is not None:
        data = data[subset_points]
        if hover_data is not None:
            hover_data = hover_data[subset_points]

    if points.shape[0]  < = width * height // 10:

        if hover_data is not None:
            tooltip_dict = {}
            for col_name in hover_data:
                data[col_name] = hover_data[col_name]
                tooltip_dict[col_name] = "@" + col_name
            tooltips = list(tooltip_dict.items())
        else:
            tooltips = None

        data["alpha"] = 1

        # bpl.output_notebook(hide_banner=True) # this doesn't work for non-notebook use
        data_source = bpl.ColumnDataSource(data)

        plot = bpl.figure(
            width=width,
            height=height,
            tooltips=tooltips,
            background_fill_color=background,
        )
        plot.circle(
            x="x",
            y="y",
            source=data_source,
            color=colors,
            size=point_size,
            alpha="alpha",
        )

        plot.grid.visible = False
        plot.axis.visible = False

        if interactive_text_search:
            text_input = TextInput(value="", title="Search:")

            if interactive_text_search_columns is None:
                interactive_text_search_columns = []
                if hover_data is not None:
                    interactive_text_search_columns.extend(hover_data.columns)
                if labels is not None:
                    interactive_text_search_columns.append("label")

            if len(interactive_text_search_columns) == 0:
                warn(
                    "interactive_text_search_columns set to True, but no hover_data or labels provided."
                    "Please provide hover_data or labels to use interactive text search."
                )

            else:
                callback = CustomJS(
                    args=dict(
                        source=data_source,
                        matching_alpha=interactive_text_search_alpha_contrast,
                        non_matching_alpha=1 - interactive_text_search_alpha_contrast,
                        search_columns=interactive_text_search_columns,
                    ),
                    code="""
                    var data = source.data;
                    var text_search = cb_obj.value;
                    
                    var search_columns_dict = {}
                    for (var col in search_columns){
                        search_columns_dict[col] = search_columns[col]
                    }
                    
                    // Loop over columns and values
                    // If there is no match for any column for a given row, change the alpha value
                    var string_match = false;
                    for (var i = 0; i  <  data.x.length; i++) {
                        string_match = false
                        for (var j in search_columns_dict) {
                            if (String(data[search_columns_dict[j]][i]).includes(text_search) ) {
                                string_match = true
                            }
                        }
                        if (string_match){
                            data['alpha'][i] = matching_alpha
                        }else{
                            data['alpha'][i] = non_matching_alpha
                        }
                    }
                    source.change.emit();
                """,
                )

                text_input.js_on_change("value", callback)

                plot = column(text_input, plot)

        # bpl.show(plot)
    else:
        if hover_data is not None:
            warn(
                "Too many points for hover data -- tooltips will not"
                "be displayed. Sorry; try subssampling your data."
            )
        if interactive_text_search:
            warn(
                "Too many points for text search." "Sorry; try subssampling your data."
            )
        hv.extension("bokeh")
        hv.output(size=300)
        hv.opts('RGB [bgcolor="{}", xaxis=None, yaxis=None]'.format(background))
        if labels is not None:
            point_plot = hv.Points(data, kdims=["x", "y"])
            plot = hd.datashade(
                point_plot,
                aggregator=ds.count_cat("color"),
                color_key=color_key,
                cmap=plt.get_cmap(cmap),
                width=width,
                height=height,
            )
        elif values is not None:
            min_val = data.values.min()
            val_range = data.values.max() - min_val
            data["val_cat"] = pd.Categorical(
                (data.values - min_val) // (val_range // 256)
            )
            point_plot = hv.Points(data, kdims=["x", "y"], vdims=["val_cat"])
            plot = hd.datashade(
                point_plot,
                aggregator=ds.count_cat("val_cat"),
                cmap=plt.get_cmap(cmap),
                width=width,
                height=height,
            )
        else:
            point_plot = hv.Points(data, kdims=["x", "y"])
            plot = hd.datashade(
                point_plot,
                aggregator=ds.count(),
                cmap=plt.get_cmap(cmap),
                width=width,
                height=height,
            )

    return plot

0 Source : utils.py
with Apache License 2.0
from CNES

def compare_2_disparities(
    input_first_disp_map: xr.Dataset, first_title: str, input_second_disp_map: xr.Dataset, second_title: str
) -> None:
    """
    Show 2 disparity maps
    :param input_first_disp_map: disparity map
    :type input_first_disp_map: dataset
    :param first_title: disparity map title
    :type first_title: str
    :param input_second_disp_map: disparity map
    :type input_second_disp_map: dataset
    :param second_title: disparity map title
    :type second_title: str
    :return: none
    """
    output_notebook()
    size = 0.5

    first_disp_map = add_validity_mask_to_dataset(input_first_disp_map)
    second_disp_map = add_validity_mask_to_dataset(input_second_disp_map)

    valid_idx = np.where(first_disp_map["validity_mask"].data == 0)
    min_d = np.nanmin(first_disp_map["disparity_map"].data[valid_idx])
    max_d = np.nanmax(first_disp_map["disparity_map"].data[valid_idx])

    cmap_pandora = pandora_cmap()
    mapper_avec_opti = LinearColorMapper(palette=cmap_to_palette(cmap_pandora), low=min_d, high=max_d)

    color_bar = ColorBar(
        color_mapper=mapper_avec_opti, ticker=BasicTicker(), label_standoff=12, border_line_color=None, location=(0, 0)
    )

    dw = first_disp_map["disparity_map"].shape[1]
    dh = first_disp_map["disparity_map"].shape[0]

    if first_title == None:
        first_title = "First disparity map"
    if second_title == None:
        second_title = "Second disparity map"

    # First disparity map
    first_fig = figure(
        title=first_title, width=450, height=450, tools=["reset", "pan", "box_zoom"], output_backend="webgl"
    )

    first_fig.image(
        image=[np.flip(first_disp_map["disparity_map"].data, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti
    )

    x = np.where(first_disp_map["invalid_mask"].data != 0)[1]
    y = dh - np.where(first_disp_map["invalid_mask"].data != 0)[0]
    first_inv_msk = first_fig.circle(x=x, y=y, size=size, color="black")

    legend = Legend(items=[("inv msk", [first_inv_msk])], location="center", click_policy="hide")

    first_fig.add_layout(legend, "below")
    first_fig.add_layout(color_bar, "right")

    # Second disparity map
    second_fig = figure(
        title=second_title,
        width=450,
        height=450,
        tools=["reset", "pan", "box_zoom"],
        output_backend="webgl",
        x_range=first_fig.x_range,
        y_range=first_fig.y_range,
    )

    second_fig.image(
        image=[np.flip(second_disp_map["disparity_map"].data, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti
    )

    x = np.where(second_disp_map["invalid_mask"].data != 0)[1]
    y = dh - np.where(second_disp_map["invalid_mask"].data != 0)[0]
    second_inv_msk = second_fig.circle(x=x, y=y, size=size, color="black")

    legend = Legend(
        items=[("inv msk", [second_inv_msk])], glyph_height=10, glyph_width=10, location="center", click_policy="hide"
    )

    second_fig.add_layout(legend, "below")
    second_fig.add_layout(color_bar, "right")

    layout = column(row(first_fig, second_fig))

    show(layout)


def compare_3_disparities_and_error(

0 Source : utils.py
with Apache License 2.0
from CNES

def compare_3_disparities_and_error(
    input_first_disp_map: xr.Dataset,
    first_title: str,
    input_second_disp_map: xr.Dataset,
    second_title: str,
    input_third_disp_map: xr.Dataset,
    third_title: str,
    error_map: np.array,
    error_title: str,
) -> None:
    """
    Show 3 disparity maps and error
    :param input_first_disp_map: disparity map
    :type input_first_disp_map: dataset
    :param first_title: disparity map title
    :type first_title: str
    :param input_second_disp_map: disparity map
    :type input_second_disp_map: dataset
    :param second_title: disparity map title
    :type second_title: str
    :param input_third_disp_map: disparity map
    :type input_third_disp_map: dataset
    :param third_title: disparity map title
    :type third_title: str
    :param error_map: error map
    :type error_map: np.array
    :param error_title: error title
    :type error_title: str
    :return: none
    """
    output_notebook()
    size = 0.5

    first_disp_map = add_validity_mask_to_dataset(input_first_disp_map)
    second_disp_map = add_validity_mask_to_dataset(input_second_disp_map)
    third_disp_map = add_validity_mask_to_dataset(input_third_disp_map)

    valid_idx = np.where(first_disp_map["validity_mask"].data == 0)
    min_d = np.nanmin(first_disp_map["disparity_map"].data[valid_idx])
    max_d = np.nanmax(first_disp_map["disparity_map"].data[valid_idx])
    cmap_pandora = pandora_cmap()
    mapper_avec_opti = LinearColorMapper(palette=cmap_to_palette(cmap_pandora), low=min_d, high=max_d)

    color_bar = ColorBar(
        color_mapper=mapper_avec_opti, ticker=BasicTicker(), label_standoff=12, border_line_color=None, location=(0, 0)
    )

    dw = first_disp_map["disparity_map"].shape[1]
    dh = first_disp_map["disparity_map"].shape[0]

    # First disparity map
    first_fig = figure(
        title=first_title, width=400, height=400, tools=["reset", "pan", "box_zoom"], output_backend="webgl"
    )

    first_fig.image(
        image=[np.flip(first_disp_map["disparity_map"].data, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti
    )

    x = np.where(first_disp_map["invalid_mask"].data != 0)[1]
    y = dh - np.where(first_disp_map["invalid_mask"].data != 0)[0]
    first_inv_msk = first_fig.circle(x=x, y=y, size=size, color="black")
    legend = Legend(items=[("inv msk", [first_inv_msk])], location="center", click_policy="hide")
    first_fig.add_layout(legend, "below")
    first_fig.add_layout(color_bar, "right")

    # Second disparity map
    second_fig = figure(
        title=second_title,
        width=400,
        height=400,
        tools=["reset", "pan", "box_zoom"],
        output_backend="webgl",
        x_range=first_fig.x_range,
        y_range=first_fig.y_range,
    )

    second_fig.image(
        image=[np.flip(second_disp_map["disparity_map"].data, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti
    )

    x = np.where(second_disp_map["invalid_mask"].data != 0)[1]
    y = dh - np.where(second_disp_map["invalid_mask"].data != 0)[0]
    second_inv_msk = second_fig.circle(x=x, y=y, size=size, color="black")
    legend = Legend(
        items=[("inv msk", [second_inv_msk])], glyph_height=10, glyph_width=10, location="center", click_policy="hide"
    )
    second_fig.add_layout(legend, "below")
    second_fig.add_layout(color_bar, "right")

    # Third disparity map
    third_fig = figure(
        title=third_title,
        width=400,
        height=400,
        tools=["reset", "pan", "box_zoom"],
        output_backend="webgl",
        x_range=first_fig.x_range,
        y_range=first_fig.y_range,
    )

    third_fig.image(
        image=[np.flip(third_disp_map["disparity_map"].data, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti
    )

    x = np.where(third_disp_map["invalid_mask"].data != 0)[1]
    y = dh - np.where(third_disp_map["invalid_mask"].data != 0)[0]
    third_inv_msk = third_fig.circle(x=x, y=y, size=size, color="black")

    legend = Legend(
        items=[("inv msk", [third_inv_msk])], glyph_height=10, glyph_width=10, location="center", click_policy="hide"
    )
    third_fig.add_layout(legend, "below")
    third_fig.add_layout(color_bar, "right")

    # Error plot
    error_fig = figure(
        title=error_title,
        width=400,
        height=400,
        tools=["reset", "pan", "box_zoom"],
        output_backend="webgl",
        x_range=first_fig.x_range,
        y_range=first_fig.y_range,
    )
    min_d = 0
    max_d = 10
    reds_cmap = cm.get_cmap("Reds", 256)
    mapper_avec_opti = LinearColorMapper(palette=cmap_to_palette(reds_cmap), low=min_d, high=max_d)

    color_bar = ColorBar(
        color_mapper=mapper_avec_opti, ticker=BasicTicker(), label_standoff=12, border_line_color=None, location=(0, 0)
    )
    error_fig.image(image=[np.flip(error_map, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti)
    error_fig.add_layout(color_bar, "right")

    layout = column(row(first_fig, second_fig), row(third_fig, error_fig))

    show(layout)


def compare_disparity_and_error(

0 Source : utils.py
with Apache License 2.0
from CNES

def compare_disparity_and_error(
    input_first_disp_map: xr.Dataset, first_title: str, error_map: np.array, error_title: str
) -> None:
    """
    Show disparity map and error
    :param left_disp_map: disparity map
    :type left_disp_map: dataset
    :param title: disparity map title
    :type title: str
    :param error_map: error map
    :type error_map: np.array
    :param error_title: error title
    :type error_title: str
    :return: none
    """
    output_notebook()
    size = 0.5

    # Disparity map
    first_disp_map = add_validity_mask_to_dataset(input_first_disp_map)

    valid_idx = np.where(first_disp_map["validity_mask"].data == 0)
    min_d = np.nanmin(first_disp_map["disparity_map"].data[valid_idx])
    max_d = np.nanmax(first_disp_map["disparity_map"].data[valid_idx])
    cmap_pandora = pandora_cmap()
    mapper_avec_opti = LinearColorMapper(palette=cmap_to_palette(cmap_pandora), low=min_d, high=max_d)

    color_bar = ColorBar(
        color_mapper=mapper_avec_opti, ticker=BasicTicker(), label_standoff=12, border_line_color=None, location=(0, 0)
    )

    dw = first_disp_map["disparity_map"].shape[1]
    dh = first_disp_map["disparity_map"].shape[0]

    first_fig = figure(
        title=first_title,
        width=450,
        height=450,
        tools=["reset", "pan", "box_zoom"],
        output_backend="webgl",
        sizing_mode="scale_width",
    )
    first_fig.image(
        image=[np.flip(first_disp_map["disparity_map"].data, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti
    )

    x = np.where(first_disp_map["invalid_mask"].data != 0)[1]
    y = dh - np.where(first_disp_map["invalid_mask"].data != 0)[0]
    first_inv_msk = first_fig.circle(x=x, y=y, size=size, color="black")
    legend = Legend(items=[("inv msk", [first_inv_msk])], location="center", click_policy="hide")

    first_fig.add_layout(legend, "below")
    first_fig.add_layout(color_bar, "right")

    # Error plot
    error_fig = figure(
        title=error_title,
        width=450,
        height=450,
        tools=["reset", "pan", "box_zoom"],
        output_backend="webgl",
        x_range=first_fig.x_range,
        y_range=first_fig.y_range,
        sizing_mode="scale_width",
    )
    min_d = 0
    max_d = 10
    reds_cmap = cm.get_cmap("Reds", 256)
    mapper_avec_opti = LinearColorMapper(palette=cmap_to_palette(reds_cmap), low=min_d, high=max_d)

    color_bar = ColorBar(
        color_mapper=mapper_avec_opti, ticker=BasicTicker(), label_standoff=12, border_line_color=None, location=(0, 0)
    )
    error_fig.image(image=[np.flip(error_map, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti)

    # Add disparity's error mask on error
    x = np.where(first_disp_map["invalid_mask"].data != 0)[1]
    y = dh - np.where(first_disp_map["invalid_mask"].data != 0)[0]
    error_inv_msk = error_fig.circle(x=x, y=y, size=size, color="black")
    legend = Legend(items=[("inv msk", [error_inv_msk])], location="center", click_policy="hide")

    error_fig.add_layout(legend, "below")
    error_fig.add_layout(color_bar, "right")

    layout = column(row(first_fig, error_fig))
    show(layout)


def show_input_images(img_left: xr.Dataset, img_right: xr.Dataset) -> None:

0 Source : utils.py
with Apache License 2.0
from CNES

def show_input_images(img_left: xr.Dataset, img_right: xr.Dataset) -> None:
    """
    Show input images and anaglyph
    :param left_disp_map: disparity map
    :type left_disp_map: dataset
    :param right_disp_map: right disparity map
    :type right_disp_map: dataset
    :return: none
    """
    output_notebook()

    dw = np.flip(img_left.im.data, 0).shape[1]
    dh = np.flip(img_right.im.data, 0).shape[0]
    width = 320
    height = 320

    # Image left
    img_left_data = img_left.im.data
    left_fig = bpl.figure(title="Left image", width=width, height=height)
    left_fig.image(image=[np.flip(img_left_data, 0)], x=1, y=0, dw=dw, dh=dh)

    # Image right
    img_right_data = img_right.im.data
    right_fig = bpl.figure(
        title="Right image", width=width, height=height, x_range=left_fig.x_range, y_range=left_fig.y_range
    )
    right_fig.image(image=[np.flip(img_right_data, 0)], x=1, y=0, dw=dw, dh=dh)

    # Anaglyph
    img_left, img_right_align = xr.align(img_left, img_right)
    anaglyph = np.stack((img_left.im, img_right_align.im, img_right_align.im), axis=-1)

    clip_percent = 5
    vmin_ref = np.percentile(img_left.im, clip_percent)
    vmax_ref = np.percentile(img_left.im, 100 - clip_percent)
    vmin_sec = np.percentile(img_right.im, clip_percent)
    vmax_sec = np.percentile(img_right.im, 100 - clip_percent)
    vmin_anaglyph = np.array([vmin_ref, vmin_sec, vmin_sec])
    vmax_anaglyph = np.array([vmax_ref, vmax_sec, vmax_sec])
    img = np.clip((anaglyph - vmin_anaglyph) / (vmax_anaglyph - vmin_anaglyph), 0, 1)
    anaglyph = np.clip((anaglyph - vmin_anaglyph) / (vmax_anaglyph - vmin_anaglyph), 0, 1)

    # Add 4rth channel to use bokeh's image_rgba function
    img = np.empty((dh, dw), dtype=np.uint32)
    view = img.view(dtype=np.uint8).reshape(dh, dw, 4)
    for i in range(dh):
        for j in range(dw):
            view[i, j, 0] = anaglyph[i, j, 0] * 255
            view[i, j, 1] = anaglyph[i, j, 1] * 255
            view[i, j, 2] = anaglyph[i, j, 2] * 255
            view[i, j, 3] = 255
    anaglyph_fig = bpl.figure(
        title="Anaglyph", width=width, height=height, x_range=left_fig.x_range, y_range=left_fig.y_range
    )
    anaglyph_fig.image_rgba(image=[np.flip(img, 0)], x=1, y=0, dw=dw, dh=dh)
    layout = column(row(left_fig, right_fig, anaglyph_fig))
    show(layout)


def get_error(

0 Source : plot.py
with BSD 3-Clause "New" or "Revised" License
from CoffeaTeam

def bokeh_plot(histo, jup_url="http://127.0.0.1:8889"):
    if not isnotebook():
        raise NotImplementedError("Only usable in jupyter notebook")
    import bokeh.plotting.figure as bk_figure
    from bokeh.io import show
    from bokeh import palettes
    from bokeh.layouts import row, column
    from bokeh.models import ColumnDataSource
    from bokeh.models.widgets import RadioButtonGroup, CheckboxButtonGroup
    from bokeh.models.widgets import RangeSlider, Div
    from bokeh.io import output_notebook  # enables plot interface in J notebook

    # init bokeh

    from bokeh.application import Application
    from bokeh.application.handlers import FunctionHandler

    from bokeh.core.validation import silence
    from bokeh.core.validation.warnings import EMPTY_LAYOUT

    silence(EMPTY_LAYOUT, True)

    output_notebook()

    # Set up widgets
    cfg_labels = ["Ghost"]
    wi_config = CheckboxButtonGroup(labels=cfg_labels, active=[0])
    wi_dense_select = RadioButtonGroup(
        labels=[ax.name for ax in histo.dense_axes()], active=0
    )
    wi_sparse_select = RadioButtonGroup(
        labels=[ax.name for ax in histo.sparse_axes()], active=0
    )

    # Dense widgets
    sliders = {}
    for ax in histo.dense_axes():
        edge_vals = (histo.axis(ax.name).edges()[0], histo.axis(ax.name).edges()[-1])
        _smallest_bin = numpy.min(numpy.diff(histo.axis(ax.name).edges()))
        sliders[ax.name] = RangeSlider(
            title=ax.name,
            value=edge_vals,
            start=edge_vals[0],
            end=edge_vals[1],
            step=_smallest_bin,
            name=ax.name,
        )

    # Cat widgets
    togglers = {}
    for ax in histo.sparse_axes():
        togglers[ax.name] = CheckboxButtonGroup(
            labels=[i.name for i in ax.identifiers()], active=[0], name=ax.name
        )

    # Toggles for all widgets
    configers = {}
    for ax in histo.sparse_axes():
        configers[ax.name] = CheckboxButtonGroup(
            labels=["Display", "Ghost"], active=[0, 1], name=ax.name
        )
    for ax in histo.dense_axes():
        configers[ax.name] = CheckboxButtonGroup(
            labels=["Display"], active=[0], name=ax.name
        )

    # Figure
    fig = bk_figure(
        title="1D Projection",
        plot_width=500,
        plot_height=500,
        min_border=20,
        toolbar_location=None,
    )
    fig.yaxis.axis_label = "N"
    fig.xaxis.axis_label = "Quantity"

    # Iterate over possible overlays
    _max_idents = 0  # Max number of simultaneou histograms
    for ax in histo.sparse_axes():
        _max_idents = max(_max_idents, len([i.name for i in ax.identifiers()]))

    # Data source list
    sources = []
    sources_ghost = []
    for i in range(_max_idents):
        sources.append(ColumnDataSource(dict(left=[], top=[], right=[], bottom=[])))
        sources_ghost.append(
            ColumnDataSource(dict(left=[], top=[], right=[], bottom=[]))
        )

    # Hist list
    hists = []
    hists_ghost = []
    for i in range(_max_idents):
        if _max_idents   <   10:
            _color = palettes.Category10[min(max(3, _max_idents), 10)][i]
        else:
            _color = palettes.magma(_max_idents)[i]
        hists.append(
            fig.quad(
                left="left",
                right="right",
                top="top",
                bottom="bottom",
                source=sources[i],
                alpha=0.9,
                color=_color,
            )
        )
        hists_ghost.append(
            fig.quad(
                left="left",
                right="right",
                top="top",
                bottom="bottom",
                source=sources_ghost[i],
                alpha=0.05,
                color=_color,
            )
        )

    def update_data(attrname, old, new):
        sparse_active = wi_sparse_select.active
        sparse_name = [ax.name for ax in histo.sparse_axes()][sparse_active]
        sparse_other = [ax.name for ax in histo.sparse_axes() if ax.name != sparse_name]

        dense_active = wi_dense_select.active
        dense_name = [ax.name for ax in histo.dense_axes()][dense_active]
        dense_other = [ax.name for ax in histo.dense_axes() if ax.name != dense_name]

        # Apply cuts in projections
        _h = histo.copy()
        for proj_ax in sparse_other:
            _idents = histo.axis(proj_ax).identifiers()
            _labels = [ident.name for ident in _idents]
            if 0 in configers[proj_ax].active:
                _h = _h.integrate(
                    proj_ax, [_labels[i] for i in togglers[proj_ax].active]
                )
            else:
                _h = _h.integrate(proj_ax)

        for proj_ax in dense_other:
            _h = _h.integrate(
                proj_ax, slice(sliders[proj_ax].value[0], sliders[proj_ax].value[1])
            )

        for cat_ix in range(_max_idents):
            # Update histo for each toggled overlay
            if cat_ix in togglers[sparse_name].active:
                cat_value = histo.axis(sparse_name).identifiers()[cat_ix]
                h1d = _h.integrate(sparse_name, cat_value)

                # Get shown histogram
                values = h1d.project(dense_name).values()
                if values != {}:
                    h = values[()]
                    bins = h1d.axis(dense_name).edges()

                    # Apply cuts on shown axis
                    bin_los = bins[:-1][bins[:-1] > sliders[dense_name].value[0]]
                    bin_his = bins[1:][bins[1:]  <  sliders[dense_name].value[1]]
                    new_bins = numpy.intersect1d(bin_los, bin_his)
                    bin_ixs = numpy.searchsorted(bins, new_bins)[:-1]
                    h = h[bin_ixs]

                    sources[cat_ix].data = dict(
                        left=new_bins[:-1],
                        right=new_bins[1:],
                        top=h,
                        bottom=numpy.zeros_like(h),
                    )
                else:
                    sources[cat_ix].data = dict(left=[], right=[], top=[], bottom=[])

                # Add ghosts
                if 0 in wi_config.active:
                    h1d = histo.integrate(sparse_name, cat_value)
                    for proj_ax in sparse_other:
                        _idents = histo.axis(proj_ax).identifiers()
                        _labels = [ident.name for ident in _idents]
                        if 1 not in configers[proj_ax].active:
                            h1d = h1d.integrate(
                                proj_ax, [_labels[i] for i in togglers[proj_ax].active]
                            )
                        else:
                            h1d = h1d.integrate(proj_ax)
                    values = h1d.project(dense_name).values()
                    if values != {}:
                        h = h1d.project(dense_name).values()[()]
                        bins = h1d.axis(dense_name).edges()
                        sources_ghost[cat_ix].data = dict(
                            left=bins[:-1],
                            right=bins[1:],
                            top=h,
                            bottom=numpy.zeros_like(h),
                        )
                    else:
                        sources_ghost[cat_ix].data = dict(
                            left=[], right=[], top=[], bottom=[]
                        )
            else:
                sources[cat_ix].data = dict(left=[], right=[], top=[], bottom=[])
                sources_ghost[cat_ix].data = dict(left=[], right=[], top=[], bottom=[])

        # Cosmetics
        fig.xaxis.axis_label = dense_name

    for name, slider in sliders.items():
        slider.on_change("value", update_data)
    for name, toggler in togglers.items():
        toggler.on_change("active", update_data)
    for name, configer in configers.items():
        configer.on_change("active", update_data)
    # Button
    for w in [wi_dense_select, wi_sparse_select, wi_config]:
        w.on_change("active", update_data)

    from bokeh.models.widgets import Panel, Tabs

    layout = row(
        fig,
        column(
            Div(
                text=" < b>Overlay Axis: < /b>",
                style={"font-size": "100%", "color": "black"},
            ),
            wi_sparse_select,
            Div(
                text=" < b>Plot Axis: < /b>", style={"font-size": "100%", "color": "black"}
            ),
            wi_dense_select,
            Div(
                text=" < b>Categorical Cuts: < /b>",
                style={"font-size": "100%", "color": "black"},
            ),
            *[toggler for name, toggler in togglers.items()],
            Div(
                text=" < b>Dense Cuts: < /b>", style={"font-size": "100%", "color": "black"}
            ),
            *[slider for name, slider in sliders.items()]
        ),
    )

    # Config prep
    incl_lists = [[], [], []]
    for i, key in enumerate(list(configers.keys())):
        incl_lists[i // max(5, len(list(configers.keys())) / 3)].append(
            Div(
                text=" < b>{}: < /b>".format(key),
                style={"font-size": "70%", "color": "black"},
            )
        )
        incl_lists[i // max(5, len(list(configers.keys())) / 3)].append(configers[key])

    layout_cfgs = column(
        row(
            column(
                Div(
                    text=" < b>Configs: < /b>",
                    style={"font-size": "100%", "color": "black"},
                ),
                wi_config,
            )
        ),
        Div(
            text=" < b>Axis togglers: < /b>", style={"font-size": "100%", "color": "black"}
        ),
        row(
            column(incl_lists[0]),
            column(incl_lists[1]),
            column(incl_lists[2]),
        ),
    )

    # Update active buttons
    def update_layout(attrname, old, new):
        active_axes = [None]
        for name, wi in configers.items():
            if 0 in wi.active:
                active_axes.append(name)
        for child in layout.children[1].children:
            if child.name not in active_axes:
                child.visible = False
            else:
                child.visible = True

    for name, configer in configers.items():
        configer.on_change("active", update_layout)

    tab1 = Panel(child=layout, title="Projection")
    tab2 = Panel(child=layout_cfgs, title="Configs")
    tabs = Tabs(tabs=[tab1, tab2])

    def modify_doc(doc):
        doc.add_root(row(tabs, width=800))
        doc.title = "Sliders"

    handler = FunctionHandler(modify_doc)
    app = Application(handler)

    show(app, notebook_url=jup_url)
    update_data("", "", "")

0 Source : log.py
with Apache License 2.0
from Drajan

    def save(self, title=None):
        """save the json file.
        Parameters
        ----------
        title: string
            title of the HTML file
        """
        title = title or self.title
        if len(self.figures) > 0:
            if os.path.isfile(self.plot_path):
                os.remove(self.plot_path)
            if self.first_save:
                self.first_save = False
                logging.info('Plot file saved at: {}'.format(
                    os.path.abspath(self.plot_path)))

            output_file(self.plot_path, title=title)
            plot = column(
                Div(text='  <  h1 align="center">{} < /h1>'.format(title)), *self.figures)
            save(plot)
            self.clear()

        if self.data_format == 'json':
            self.results.to_json(self.data_path, orient='records', lines=True)
        else:
            self.results.to_csv(self.data_path, index=False, index_label=False)

    def load(self, path=None):

0 Source : bokeh_sliders.py
with GNU General Public License v3.0
from drscotthawley

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)


def update_input(attrname, old, new):

0 Source : visual_midi.py
with MIT License
from dubreuia

    def plot(self, pm: PrettyMIDI):
        """
        Plots the pretty midi object as a plot object.

          :param pm: the PrettyMIDI instance to plot
          :return: the bokeh plot layout
        """
        preset = self._preset

        # Calculates the QPM from the MIDI file, might raise exception if confused
        qpm = self._get_qpm(pm)

        # Initialize the tools, those are present on the right hand side
        plot = bokeh.plotting.figure(
            tools="reset,hover,save,wheel_zoom,pan",
            toolbar_location=preset.toolbar_location)

        # Setup the hover and the data dict for bokeh,
        # each property must match a property in the data dict
        plot.select(dict(type=bokeh.models.HoverTool)).tooltips = ({
            "program": "@program",
            "pitch": "@top",
            "velocity": "@velocity",
            "duration": "@duration",
            "start_time": "@left",
            "end_time": "@right"})
        data = dict(
            program=[],
            top=[],
            bottom=[],
            left=[],
            right=[],
            duration=[],
            velocity=[],
            color=[])

        # Puts the notes in the dict for bokeh and saves first
        # and last note time, bigger and smaller pitch
        pitch_min = None
        pitch_max = None
        first_note_start = None
        last_note_end = None
        index_instrument = 0
        for instrument in pm.instruments:
            for note in instrument.notes:
                pitch_min = min(pitch_min or self._MAX_PITCH, note.pitch)
                pitch_max = max(pitch_max or self._MIN_PITCH, note.pitch)
                color = self._get_color(index_instrument, note)
                note_start = note.start
                note_end = note.start + (note.end - note.start)
                data["program"].append(instrument.program)
                data["top"].append(note.pitch)
                if self._show_velocity:
                    data["bottom"].append(note.pitch + (note.velocity / 127))
                else:
                    data["bottom"].append(note.pitch + 1)
                data["left"].append(note_start)
                data["right"].append(note_end)
                data["duration"].append(note_end - note_start)
                data["velocity"].append(note.velocity)
                data["color"].append(color)
                first_note_start = min(first_note_start or sys.maxsize, note_start)
                last_note_end = max(last_note_end or 0, note_end)
            index_instrument = index_instrument + 1

        # Shows an empty plot even if there are no notes
        if first_note_start is None or last_note_end is None or pitch_min is None or pitch_max is None:
            pitch_min = self._MIN_PITCH
            pitch_max = pitch_min + 5
            first_note_start = 0
            last_note_end = 0

        # Gets the pitch range (min, max) from either the provided arguments
        # or min and max values from the notes
        if self._plot_pitch_range_start is not None:
            pitch_min = self._plot_pitch_range_start
        else:
            pitch_min = min(self._MAX_PITCH, pitch_min)
        if self._plot_pitch_range_stop is not None:
            pitch_max = self._plot_pitch_range_stop
        else:
            pitch_max = max(self._MIN_PITCH, pitch_max)

        pitch_range = pitch_max + 1 - pitch_min

        # Draws the rectangles on the plot from the data
        source = ColumnDataSource(data=data)
        plot.quad(left="left",
                  right="right",
                  top="top",
                  bottom="bottom",
                  line_alpha=1,
                  line_color="black",
                  color="color",
                  source=source)

        # Draws the y grid by hand, because the grid has label on the ticks, but
        # for a plot like this, the labels needs to fit in between the ticks.
        # Also useful to change the background of the grid each line
        for pitch in range(pitch_min, pitch_max + 1):
            # Draws the background box and contours, on the underlay layer, so
            # that the rectangles and over the box annotations
            fill_alpha = (0.15 if pitch % 2 == 0 else 0.00)
            box = BoxAnnotation(bottom=pitch,
                                top=pitch + 1,
                                fill_color="gray",
                                fill_alpha=fill_alpha,
                                line_color="black",
                                line_alpha=0.3,
                                line_width=1,
                                level="underlay")
            plot.add_layout(box)
            label = Label(
                x=preset.label_y_axis_offset_x,
                y=pitch + preset.label_y_axis_offset_y,
                x_units="screen",
                text=str(pitch),
                render_mode="css",
                text_font_size=preset.label_text_font_size,
                text_font_style=preset.label_text_font_style)
            plot.add_layout(label)

        # Gets the time signature from pretty midi, or 4/4 if none
        if self._midi_time_signature:
            numerator, denominator = self._midi_time_signature.split("/")
            time_signature = TimeSignature(int(numerator), int(denominator), 0)
        else:
            if pm.time_signature_changes:
                if len(pm.time_signature_changes) > 1:
                    raise Exception("Multiple time signatures are not supported")
                time_signature = pm.time_signature_changes[0]
            else:
                time_signature = TimeSignature(4, 4, 0)

        # Gets seconds per bar and seconds per beat
        if len(pm.get_beats()) >= 2:
            seconds_per_beat = pm.get_beats()[1] - pm.get_beats()[0]
        else:
            seconds_per_beat = 0.5
        if len(pm.get_downbeats()) >= 2:
            seconds_per_bar = pm.get_downbeats()[1] - pm.get_downbeats()[0]
        else:
            seconds_per_bar = 2.0

        # Defines the end time of the plot in seconds
        if self._plot_bar_range_stop is not None:
            plot_end_time = self._plot_bar_range_stop * seconds_per_bar
        else:
            # Calculates the plot start and end time, the start time can start after
            # notes or truncate notes if the plot is too long (we left truncate the
            # plot with the bounds)
            # The plot start and plot end are a multiple of seconds per bar (closest
            # smaller value for the start time, closest higher value for the end time)
            plot_end_time = int((last_note_end) / seconds_per_bar) * seconds_per_bar
            # If the last note end is exactly on a multiple of seconds per bar,
            # we don't start a new one
            is_on_bar = math.isclose(last_note_end % seconds_per_bar, seconds_per_bar)
            is_on_bar_exact = math.isclose(last_note_end % seconds_per_bar, 0.0)
            if not is_on_bar and not is_on_bar_exact:
                plot_end_time += seconds_per_bar

        # Defines the start time of the plot in seconds
        if self._plot_bar_range_start is not None:
            plot_start_time = self._plot_bar_range_start * seconds_per_bar
        else:
            start_time = int(first_note_start / seconds_per_bar) * seconds_per_bar
            plot_max_length_time = self._plot_max_length_bar * seconds_per_bar
            plot_start_time = max(plot_end_time - plot_max_length_time, start_time)

        # Draws the vertical bar grid, with a different background color
        # for each bar
        if preset.show_bar:
            bar_count = 0
            for bar_time in pm.get_downbeats():
                fill_alpha_index = bar_count % len(self._bar_fill_alphas)
                fill_alpha = self._bar_fill_alphas[fill_alpha_index]
                box = BoxAnnotation(left=bar_time,
                                    right=bar_time + seconds_per_bar,
                                    fill_color="gray",
                                    fill_alpha=fill_alpha,
                                    line_color="black",
                                    line_width=2,
                                    line_alpha=0.5,
                                    level="underlay")
                plot.add_layout(box)
                bar_count += 1

        # Draws the vertical beat grid, those are only grid lines
        if preset.show_beat:
            for beat_time in pm.get_beats():
                box = BoxAnnotation(left=beat_time,
                                    right=beat_time + seconds_per_beat,
                                    fill_color=None,
                                    line_color="black",
                                    line_width=1,
                                    line_alpha=0.4,
                                    level="underlay")
                plot.add_layout(box)

        # Configure x axis
        plot.xaxis.bounds = (plot_start_time, plot_end_time)
        plot.xaxis.axis_label = "time (SEC)"
        plot.xaxis.axis_label_text_font_size = preset.axis_label_text_font_size
        plot.xaxis.ticker = bokeh.models.SingleIntervalTicker(interval=1)
        plot.xaxis.major_tick_line_alpha = 0.9
        plot.xaxis.major_tick_line_width = 1
        plot.xaxis.major_tick_out = preset.axis_x_major_tick_out
        plot.xaxis.minor_tick_line_alpha = 0
        plot.xaxis.major_label_text_font_size = preset.label_text_font_size
        plot.xaxis.major_label_text_font_style = preset.label_text_font_style

        # Configure y axis
        plot.yaxis.bounds = (pitch_min, pitch_max + 1)
        plot.yaxis.axis_label = "pitch (MIDI)"
        plot.yaxis.axis_label_text_font_size = preset.axis_label_text_font_size
        plot.yaxis.ticker = bokeh.models.SingleIntervalTicker(interval=1)
        plot.yaxis.major_label_text_alpha = 0
        plot.yaxis.major_tick_line_alpha = 0.9
        plot.yaxis.major_tick_line_width = 1
        plot.yaxis.major_tick_out = preset.axis_y_major_tick_out
        plot.yaxis.minor_tick_line_alpha = 0
        plot.yaxis.axis_label_standoff = preset.axis_y_label_standoff
        plot.outline_line_width = 1
        plot.outline_line_alpha = 1
        plot.outline_line_color = "black"

        # The x grid is deactivated because is draw by hand (see x grid code)
        plot.xgrid.grid_line_color = None

        # The y grid is deactivated because is draw by hand (see y grid code)
        plot.ygrid.grid_line_color = None

        # Configure the plot size and range
        if self._plot_title is None:
            plot_title_text = "Visual MIDI (%s QPM, %s/%s)" % (
                str(int(qpm)), time_signature.numerator, time_signature.denominator)
        else:
            plot_title_text = self._plot_title
        
        plot.title = Title(text=plot_title_text,
                           text_font_size=preset.title_text_font_size)
        plot.plot_width = preset.plot_width
        if preset.row_height:
            plot.plot_height = pitch_range * preset.row_height
        else:
            plot.plot_height = preset.plot_height
        plot.x_range = Range1d(plot_start_time, plot_end_time)
        plot.y_range = Range1d(pitch_min, pitch_max + 1)
        plot.min_border_right = 50

        if self._live_reload and preset.stop_live_reload_button:
            callback = CustomJS(code="clearInterval(liveReloadInterval)")
            button = Button(label="stop live reload")
            button.js_on_click(callback)
            layout = column(button, plot)
        else:
            layout = column(plot)

        return layout

    def save(self, pm: PrettyMIDI, filepath: str):

0 Source : plotting.py
with Apache License 2.0
from EPFL-LCSB

def summarize_model(model,time_data,groups,
                    output_path='.', model_tag='', backend ='png'):

    summary_plots = dict()
    detailed_plots = dict()
    cleaned_groups = dict()

    # Cleanup missing vars
    for key, varnames in groups.items():
        cleaned_groups[key] = [x for x in varnames if x in time_data.index or x == 'total']

    groups = cleaned_groups
    total_groups = {k:v for k,v in groups.items() if 'total' in v and 'pathway_enz' in k}

    for key,data_type in groups.items():
        summary_plots[key] = make_summary_plots(model,time_data,key,data_type)

        detailed_plots[key] = make_detailed_plots(model,time_data,data_type,backend)

    summary_plots['growth'] = make_growth_plot(model,time_data)

    summary_plots['mass_ratios'] = plot_mass(model,time_data)

    if model is not None:
        summary_plots['subsystems'] = plot_subsystems(model,time_data)

    summary_plots['total'] = make_total_plot(model, time_data, total_groups)

    output_folder = join(output_path)#,model_tag)#+'_'+get_timestr())

    if not exists(output_folder):
        makedirs(output_folder)

    bp.curdoc().clear()
    bp.output_file(join(output_folder,'summary.html'), title = model_tag)

    for p in summary_plots.values():
        p.output_backend = backend

    bp.show(column(list(summary_plots.values())))

    for key,this_dp in detailed_plots.items():
        bp.curdoc().clear()
        bp.output_file(join(output_folder,'{}.html'.format(key)))
        for p in this_dp.children:
            try:
                p.output_backend = backend
            except AttributeError:
                # Fails for gridplots
                pass
                # from bokeh.layouts import GridBox
                # if isinstance(p,GridBox):
                #     p.children[0][0].output_backend = backend
                # else: # Toolbox bar etc..
                #     pass
        bp.show(this_dp)



def make_summary_plots(model, time_data, key, data_type, total=False):

0 Source : plot_buffer.py
with GNU General Public License v3.0
from eqcorrscan

def define_plot(
    doc: Document,
    rt_client: _StreamingClient,
    channels: list,
    tribe: RealTimeTribe,
    inventory: Inventory,
    detections: list,
    map_options: dict,
    plot_options: dict,
    plot_length: float,
    update_interval: int,
    data_color: str = "grey",
    lowcut: float = 1.0,
    highcut: float = 10.0,
    offline: bool = False,
):
    """
    Set up a bokeh plot for real-time plotting.

    Defines a moving data stream and a map.

    Parameters
    ----------
    doc
        Bokeh document to edit - usually called as a partial
    rt_client
        RealTimeClient streaming data
    channels
        Channels to plot
    tribe
        Tribe to plot
    inventory
        Inventory to plot
    detections
        Detections to plot - should be a list that is updated in place.
    map_options
        Dictionary of options for the map
    plot_options
        Dictionary of options for plotting in general
    plot_length
        Length of data plot
    update_interval
        Update frequency in seconds
    data_color
        Colour to data stream
    lowcut
        Lowcut for filtering data stream
    highcut
        Highcut for filtering data stream
    offline
        Flag to set time-stamps to data time-stamps if True, else timestamps
        will be real-time
    """
    # Set up the data source
    Logger.info("Getting stream to define plot")
    stream = rt_client.stream.copy().split().detrend()
    if lowcut and highcut:
        stream.filter("bandpass", freqmin=lowcut, freqmax=highcut)
        title = "Streaming data: {0}-{1} Hz bandpass".format(lowcut, highcut)
    elif lowcut:
        stream.filter("highpass", lowcut)
        title = "Streaming data: {0} Hz highpass".format(lowcut)
    elif highcut:
        stream.filter("lowpass", highcut)
        title = "Streaming data: {0} Hz lowpass".format(highcut)
    else:
        title = "Raw streaming data"
    stream.merge()
    Logger.info(f"Have the stream: \n{stream}")

    template_lats, template_lons, template_alphas, template_ids = (
        [], [], [], [])
    for template in tribe:
        try:
            origin = (template.event.preferred_origin() or
                      template.event.origins[0])
        except IndexError:
            continue
        template_lats.append(origin.latitude)
        template_lons.append(origin.longitude % 360)
        template_alphas.append(0)
        template_ids.append(template.event.resource_id.id.split("/")[-1])

    station_lats, station_lons, station_ids = ([], [], [])
    for network in inventory:
        for station in network:
            station_lats.append(station.latitude)
            station_lons.append(station.longitude % 360)
            station_ids.append(station.code)

    # Get plot bounds in web mercator
    Logger.info("Defining map")
    transformer = Transformer.from_crs(
        "epsg:4326", "epsg:3857", always_xy=True)
    try:
        min_lat, min_lon, max_lat, max_lon = (
            min(template_lats + station_lats),
            min(template_lons + station_lons),
            max(template_lats + station_lats),
            max(template_lons + station_lons))
    except ValueError as e:
        Logger.error(e)
        Logger.info("Setting map bounds to NZ")
        min_lat, min_lon, max_lat, max_lon = (-47., 165., -34., 179.9)
    Logger.info(f"Map bounds: {min_lon}, {min_lat} - {max_lon}, {max_lat}")
    bottom_left = transformer.transform(min_lon, min_lat)
    top_right = transformer.transform(max_lon, max_lat)
    map_x_range = (bottom_left[0], top_right[0])
    map_y_range = (bottom_left[1], top_right[1])

    template_x, template_y = ([], [])
    for lon, lat in zip(template_lons, template_lats):
        _x, _y = transformer.transform(lon, lat)
        template_x.append(_x)
        template_y.append(_y)

    station_x, station_y = ([], [])
    for lon, lat in zip(station_lons, station_lats):
        _x, _y = transformer.transform(lon, lat)
        station_x.append(_x)
        station_y.append(_y)

    template_source = ColumnDataSource({
        'y': template_y, 'x': template_x,
        'lats': template_lats, 'lons': template_lons,
        'template_alphas': template_alphas, 'id': template_ids})
    station_source = ColumnDataSource({
        'y': station_y, 'x': station_x,
        'lats': station_lats, 'lons': station_lons, 'id': station_ids})

    Logger.info("Allocated data sources")
    trace_sources = {}
    trace_data_range = {}
    # Allocate empty arrays
    for channel in channels:
        tr = stream.select(id=channel)[0]
        times = np.arange(
            tr.stats.starttime.datetime,
            (tr.stats.endtime + tr.stats.delta).datetime,
            step=dt.timedelta(seconds=tr.stats.delta))
        data = tr.data
        trace_sources.update(
            {channel: ColumnDataSource({'time': times, 'data': data})})
        trace_data_range.update({channel: (data.min(), data.max())})

    # Set up the map to go on the left side
    Logger.info("Adding features to map")
    map_plot = figure(
        title="Template map", x_range=map_x_range, y_range=map_y_range,
        x_axis_type="mercator", y_axis_type="mercator", **map_options)
    url = 'http://a.basemaps.cartocdn.com/rastertiles/voyager/{Z}/{X}/{Y}.png'
    attribution = "Tiles by Carto, under CC BY 3.0. Data by OSM, under ODbL"
    map_plot.add_tile(WMTSTileSource(url=url, attribution=attribution))
    map_plot.circle(
        x="x", y="y", source=template_source, fill_color="firebrick",
        line_color="grey", line_alpha=.2,
        fill_alpha="template_alphas", size=10)
    map_plot.triangle(
        x="x", y="y", size=10, source=station_source, color="blue", alpha=1.0)

    # Set up the trace plots
    Logger.info("Setting up streaming plot")
    trace_plots = []
    if not offline:
        now = dt.datetime.utcnow()
    else:
        now = max([tr.stats.endtime for tr in stream]).datetime
    p1 = figure(
        y_axis_location="right", title=title,
        x_range=[now - dt.timedelta(seconds=plot_length), now],
        plot_height=int(plot_options["plot_height"] * 1.2),
        **{key: value for key, value in plot_options.items()
           if key != "plot_height"})
    p1.yaxis.axis_label = None
    p1.xaxis.axis_label = None
    p1.min_border_bottom = 0
    p1.min_border_top = 0
    if len(channels) != 1:
        p1.xaxis.major_label_text_font_size = '0pt'
    p1_line = p1.line(
        x="time", y='data', source=trace_sources[channels[0]],
        color=data_color, line_width=1)
    legend = Legend(items=[(channels[0], [p1_line])])
    p1.add_layout(legend, 'right')

    datetick_formatter = DatetimeTickFormatter(
        days=["%m/%d"], months=["%m/%d"],
        hours=["%m/%d %H:%M:%S"], minutes=["%m/%d %H:%M:%S"],
        seconds=["%m/%d %H:%M:%S"], hourmin=["%m/%d %H:%M:%S"],
        minsec=["%m/%d %H:%M:%S"])
    p1.xaxis.formatter = datetick_formatter

    # Add detection lines
    Logger.info("Adding detection artists")
    detection_source = _get_pick_times(detections, channels[0])
    detection_source.update(
        {"pick_values": [[
            int(min(stream.select(id=channels[0])[0].data) * .9),
            int(max(stream.select(id=channels[0])[0].data) * .9)]
            for _ in detection_source['picks']]})
    detection_sources = {channels[0]: ColumnDataSource(detection_source)}
    detection_lines = MultiLine(
        xs="picks", ys="pick_values", line_color="red", line_dash="dashed",
        line_width=1)
    p1.add_glyph(detection_sources[channels[0]], detection_lines)

    trace_plots.append(p1)

    if len(channels) > 1:
        for i, channel in enumerate(channels[1:]):
            p = figure(
                x_range=p1.x_range,
                y_axis_location="right", **plot_options)
            p.yaxis.axis_label = None
            p.xaxis.axis_label = None
            p.min_border_bottom = 0
            # p.min_border_top = 0
            p_line = p.line(
                x="time", y="data", source=trace_sources[channel],
                color=data_color, line_width=1)
            legend = Legend(items=[(channel, [p_line])])
            p.add_layout(legend, 'right')
            p.xaxis.formatter = datetick_formatter

            # Add detection lines
            detection_source = _get_pick_times(detections, channel)
            detection_source.update(
                {"pick_values": [[
                    int(min(stream.select(id=channel)[0].data) * .9),
                    int(max(stream.select(id=channel)[0].data) * .9)]
                    for _ in detection_source['picks']]})
            detection_sources.update({
                channel: ColumnDataSource(detection_source)})
            detection_lines = MultiLine(
                xs="picks", ys="pick_values", line_color="red",
                line_dash="dashed", line_width=1)
            p.add_glyph(detection_sources[channel], detection_lines)

            trace_plots.append(p)
            if i != len(channels) - 2:
                p.xaxis.major_label_text_font_size = '0pt'
    plots = gridplot([[map_plot, column(trace_plots)]])

    previous_timestamps = {
        channel: stream.select(id=channel)[0].stats.endtime
        for channel in channels}
    
    def update():
        Logger.debug("Plot updating")
        _stream = rt_client.stream.split().detrend()
        if lowcut and highcut:
            _stream.filter("bandpass", freqmin=lowcut, freqmax=highcut)
        elif lowcut:
            _stream.filter("highpass", lowcut)
        elif highcut:
            _stream.filter("lowpass", highcut)
        _stream.merge()

        for _i, _channel in enumerate(channels):
            try:
                _tr = _stream.select(id=_channel)[0]
            except IndexError:
                Logger.debug("No channel for {0}".format(_channel))
                continue
            new_samples = int(_tr.stats.sampling_rate * (
                    previous_timestamps[_channel] - _tr.stats.endtime))
            if new_samples == 0:
                Logger.debug("No new data for {0}".format(_channel))
                continue
            _new_data = _tr.slice(
                starttime=previous_timestamps[_channel])
            new_times = np.arange(
                _new_data.stats.starttime.datetime,
                (_tr.stats.endtime + _tr.stats.delta).datetime,
                step=dt.timedelta(seconds=_tr.stats.delta))
            new_data = {'time': new_times[1:], 'data': _new_data.data[1:]}
            Logger.debug("Channl: {0}\tNew times: {1}\t New data: {2}".format(
                _tr.id, new_data["time"].shape, new_data["data"].shape))
            trace_sources[_channel].stream(
                new_data=new_data,
                rollover=int(plot_length * _tr.stats.sampling_rate))
            new_picks = _get_pick_times(detections, _channel)
            new_picks.update({
                'pick_values': [
                    [int(np.nan_to_num(
                        trace_sources[_channel].data['data']).max() * .9),
                     int(np.nan_to_num(
                         trace_sources[_channel].data['data']).min() * .9)]
                    for _ in new_picks['picks']]})
            detection_sources[_channel].data = new_picks
            previous_timestamps.update({_channel: _tr.stats.endtime})
            Logger.debug("New data plotted for {0}".format(_channel))
        if not offline:
            now = dt.datetime.utcnow()
        else:
            try:
                now = max([tr.stats.endtime for tr in _stream]).datetime
            except ValueError:
                return
        trace_plots[0].x_range.start = now - dt.timedelta(seconds=plot_length)
        trace_plots[0].x_range.end = now
        _update_template_alphas(
            detections, tribe, decay=plot_length, now=now,
            datastream=template_source)
    Logger.info("Adding callback")
    doc.add_periodic_callback(update, update_interval)
    doc.title = "EQcorrscan Real-time plotter"
    doc.add_root(plots)
    Logger.info("Plot defined")


def _update_template_alphas(

See More Examples