Esempio n. 1
0
def test_Legend():
    legend = Legend()
    assert legend.location == 'top_right'
    assert legend.orientation == 'vertical'
    assert legend.title is None
    assert legend.title_standoff == 5
    assert legend.label_standoff == 5
    assert legend.label_height == 20
    assert legend.label_width == 20
    assert legend.glyph_height == 20
    assert legend.glyph_width == 20
    assert legend.padding == 10
    assert legend.spacing == 3
    assert legend.margin == 10
    assert legend.items == []
    check_line_properties(legend, "border_", "#e5e5e5", 1.0, 0.5)
    check_text_properties(legend, "label_", "10pt", "middle", scalar=True)
    check_fill_properties(legend, "background_", "#ffffff", 0.95)
    check_properties_existence(legend, [
        "visible", "location", "orientation", "title", "title_standoff",
        "label_standoff", "label_height", "label_width", "glyph_height",
        "glyph_width", "margin", "padding", "spacing", "items", "level",
        "click_policy"
    ], prefix('label_', TEXT), prefix('title_', TEXT), prefix('border_', LINE),
                               prefix('background_', FILL),
                               prefix('inactive_', FILL))
Esempio n. 2
0
def test_Legend():
    legend = Legend()
    assert legend.plot is None
    assert legend.location == 'top_right'
    assert legend.label_standoff == 15
    assert legend.label_height == 20
    assert legend.label_width == 50
    assert legend.glyph_height == 20
    assert legend.glyph_width == 20
    assert legend.legend_padding == 10
    assert legend.legend_spacing == 3
    assert legend.legends == []
    yield check_border, legend
    yield check_label, legend
    yield check_background, legend
    yield (check_props, legend, [
        "plot",
        "location",
        "label_standoff",
        "label_height",
        "label_width",
        "glyph_height",
        "glyph_width",
        "legend_padding",
        "legend_spacing",
        "legends",
        "level"
    ], LABEL, BORDER, BACKGROUND)
Esempio n. 3
0
def test_Legend():
    legend = Legend()
    assert legend.plot is None
    assert legend.location == 'top_right'
    assert legend.label_standoff == 15
    assert legend.label_height == 20
    assert legend.label_width == 50
    assert legend.glyph_height == 20
    assert legend.glyph_width == 20
    assert legend.legend_padding == 10
    assert legend.legend_spacing == 3
    assert legend.legends == []
    yield check_line, legend, "border_", "#e5e5e5", 1.0, 0.5
    yield check_text, legend, "label_", "10pt", "middle"
    yield check_fill, legend, "background_", "#ffffff", 0.95
    yield (check_props, legend, [
        "plot",
        "location",
        "orientation",
        "label_standoff",
        "label_height",
        "label_width",
        "glyph_height",
        "glyph_width",
        "legend_padding",
        "legend_spacing",
        "legends",
        "level"],
        prefix('label_', TEXT),
        prefix('border_', LINE),
        prefix('background_', FILL))
Esempio n. 4
0
def legend(fig, labels=None):
    '''
    Adds a legend to a Bokeh plot.
    fig: figure the legend will be plotted next to
    labels: list of labels for all lines (in order of plotting them). By default, uses the "name" of each line plotted.
    loc: location of legend relative to plot
    '''
    from bokeh.models.annotations import Legend
    from bokeh.models.renderers import GlyphRenderer
    from bokeh.models.glyphs import Line

    lines = []
    for r in fig.renderers:  # This finds all the lines or scatter plots
        if type(r) == GlyphRenderer:
            if r.glyph.__module__ == 'bokeh.models.markers' or r.glyph == 'bokeh.models.glyphs.Line':
                lines.append(r)

    if labels == None:
        labels = [l.name for l in lines]

    legends = [(labels[i], [lines[i]]) for i in range(len(labels))]
    leg = Legend(legends=legends,
                 location=(10, -30),
                 background_fill_color='mediumpurple',
                 background_fill_alpha=0.2,
                 label_text_font_size='12pt')

    fig.add_layout(leg, 'right')

    return leg
Esempio n. 5
0
    def legend(self, ax, plotted):
        """Add interactive legend with colorcoded model info."""
        legend_it = []
        for (model_name, glyphs) in plotted.items():
            legend_it.append((model_name, glyphs))

        legend = Legend(items=legend_it)
        ax.add_layout(legend, "right")
        ax.legend.click_policy = "hide"
Esempio n. 6
0
    def legend(self, ax, plotted):
        """Add interactive legend with colorcoded model info."""
        legend_it = []
        for (model_name, glyphs) in plotted.items():
            legend_it.append((model_name, glyphs))

        legend = Legend(items=legend_it,
                        orientation="vertical",
                        location="top_left")
        ax.add_layout(legend, "above")
        ax.legend.click_policy = "hide"
Esempio n. 7
0
def plot_categorical_column(contexts,
                            layer,
                            acts_tag,
                            color_col,
                            legend=False):
    """
    Given a layer and a categorical column in the contexts dataframe,
    plots all activations at the specified layer, colorized to visualize the specified column.
    TODO: document requirements of contexts dataframe.
    """
    p = empty_plot()
    if legend:  # add legend
        p.height += 200
        p.add_layout(
            Legend(orientation='horizontal',
                   label_text_font_size='6pt',
                   label_width=10), 'above')

    source = ColumnDataSource({
        'x':
        contexts[f'{layer} {acts_tag} x'],
        'y':
        contexts[f'{layer} {acts_tag} y'],
        'color':
        vis_util.categorical_list_to_color_list(contexts[color_col]),
        'legend label':
        contexts[color_col],
        'token':
        contexts['token'],
        'abbreviated context':
        contexts['abbreviated context'],
        'abbreviated context html':
        contexts['abbreviated context html'],
        'context html':
        contexts['context html']
    })
    if legend:
        p.circle('x',
                 'y',
                 color='color',
                 legend_group='legend label',
                 source=source)
    else:
        p.circle('x', 'y', color='color', source=source)

    p.tools = [
        PanTool(),
        WheelZoomTool(),
        BoxZoomTool(),
        ResetTool(),
        custom_hover_tool()
    ]
    return p
Esempio n. 8
0
def test_Legend():
    legend = Legend()
    assert legend.plot is None
    assert legend.location == 'top_right'
    assert legend.label_standoff == 5
    assert legend.label_height == 20
    assert legend.label_width == 20
    assert legend.glyph_height == 20
    assert legend.glyph_width == 20
    assert legend.legend_padding == 10
    assert legend.legend_spacing == 3
    assert legend.legends == []
    check_line_properties(legend, "border_", "#e5e5e5", 1.0, 0.5)
    check_text_properties(legend, "label_", "10pt", "middle")
    check_fill_properties(legend, "background_", "#ffffff", 0.95)
    check_properties_existence(legend, [
        "plot", "visible", "location", "orientation", "label_standoff",
        "label_height", "label_width", "glyph_height", "glyph_width",
        "legend_margin", "legend_padding", "legend_spacing", "legends", "level"
    ], prefix('label_', TEXT), prefix('border_', LINE),
                               prefix('background_', FILL))
Esempio n. 9
0
def plot_plain(contexts, layer, acts_tag, legend=False, darkmode=True):
    """
    Given a layer, and a list of binary columns in the contexts dataframe,
    plots all activations at the specified layer, colorized to visualize all the specified columns.
    TODO: document requirements of contexts dataframe.
    """
    p = empty_plot(darkmode=darkmode)
    if legend:  # add legend
        p.height += 200
        p.add_layout(
            Legend(orientation='vertical',
                   label_text_font_size='6pt',
                   label_width=10), 'above')
    # add all contexts in grey
    source = ColumnDataSource({
        'x':
        contexts[f'{layer} {acts_tag} x'],
        'y':
        contexts[f'{layer} {acts_tag} y'],
        'token':
        contexts['token'],
        'abbreviated context':
        contexts['abbreviated context'],
        'abbreviated context html':
        contexts['abbreviated context html'],
        'context html':
        contexts['context html']
    })
    p.circle('x', 'y', color='black', source=source)
    p.tools = [
        PanTool(),
        WheelZoomTool(),
        BoxZoomTool(),
        ResetTool(),
        custom_hover_tool()
    ]
    return p
Esempio n. 10
0
    output_file(output_filename)
    p = figure(x_axis_type="datetime",
               sizing_mode="stretch_both",
               active_scroll="wheel_zoom",
               title=args.title)
    p.xaxis.axis_label = 'Date'
    p.yaxis.axis_label = "Commit Count"

    p.extra_y_ranges = {
        'team_range': Range1d(start=0, end=team_size['authors_count'].max())
    }
    p.add_layout(LinearAxis(y_range_name="team_range", axis_label="Team Size"),
                 "right")

    p.add_layout(Legend(), "below")

    p.add_tools(
        HoverTool(tooltips=[("Date", "@date{%Y-w%V}"),
                            ("Team Size", "@authors_count"),
                            ("Commit Count", "@commit_count")],
                  formatters={'date': 'datetime'},
                  point_policy='snap_to_data'))

    p.circle("date",
             "commit_count",
             source=ColumnDataSource(team_size),
             color=Category10[3][0],
             fill_alpha=0.1,
             line_alpha=0.2)
    p.circle("date",
cline = p2.circle(df2['время формирования точки на БВ'], df2['Секция №1 Температура НП, t°'], line_width=2, color=Category10[2])
dline = p2.circle(df2['время формирования точки на БВ'], df2['Секция №3 Температура НП, t°'], line_width=2, color=Category10[6])

# p2 = figure(x_axis_type='datetime', plot_width=10000)
# eline = p1.circle(df['время прихода точки на сервере'], df['Скорость'], line_width=2, color=Viridis6[5])

p1.yaxis.axis_label = 'Ось 1'
p1.xaxis.axis_label = 'временная ось 1'
p2.yaxis.axis_label = 'Ось 2'
p2.xaxis.axis_label = 'временная ось 2'
# p2.yaxis.axis_label = 'Скорость'
# p2.xaxis.axis_label = 'время формирования точки на БВ'

legend1 = Legend(items=[
    ('Параметр 1', [aline]),
    ('Параметр 2', [bline]),
], location=(0, 250))

legend2 = Legend(items=[
    ('Параметр 3', [cline]),
    ('Параметр 4', [dline]),
], location=(0, 250))

t1 = Title()
t1.text = 'BOKEH_EXAMPLE_1_EMOTIONS'
p1.title = t1

t2 = Title()
t2.text = 'BOKEH_EXAMPLE_2_EMOTIONS'
p2.title = t2
# p2.title = t
Esempio n. 12
0
def plot_density(
    ax,
    all_labels,
    to_plot,
    colors,
    bw,
    circular,
    figsize,
    length_plotters,
    rows,
    cols,
    textsize,
    hdi_prob,
    point_estimate,
    hdi_markers,
    outline,
    shade,
    n_data,
    data_labels,
    backend_kwargs,
    show,
):
    """Bokeh density plot."""
    if backend_kwargs is None:
        backend_kwargs = {}

    backend_kwargs = {
        **backend_kwarg_defaults(),
        **backend_kwargs,
    }

    if colors == "cycle":
        colors = [
            prop
            for _, prop in zip(
                range(n_data), cycle(plt.rcParams["axes.prop_cycle"].by_key()["color"])
            )
        ]
    elif isinstance(colors, str):
        colors = [colors for _ in range(n_data)]
    colors = vectorized_to_hex(colors)

    (figsize, _, _, _, line_width, markersize) = _scale_fig_size(figsize, textsize, rows, cols)

    if ax is None:
        ax = create_axes_grid(
            length_plotters,
            rows,
            cols,
            figsize=figsize,
            squeeze=False,
            backend_kwargs=backend_kwargs,
        )
    else:
        ax = np.atleast_2d(ax)

    axis_map = {
        label: ax_
        for label, ax_ in zip(all_labels, (item for item in ax.flatten() if item is not None))
    }
    if data_labels is None:
        data_labels = {}

    legend_items = defaultdict(list)
    for m_idx, plotters in enumerate(to_plot):
        for var_name, selection, values in plotters:
            label = make_label(var_name, selection)

            if data_labels:
                data_label = data_labels[m_idx]
            else:
                data_label = None

            plotted = _d_helper(
                values.flatten(),
                label,
                colors[m_idx],
                bw,
                circular,
                line_width,
                markersize,
                hdi_prob,
                point_estimate,
                hdi_markers,
                outline,
                shade,
                axis_map[label],
            )
            if data_label is not None:
                legend_items[axis_map[label]].append((data_label, plotted))

    for ax1, legend in legend_items.items():
        legend = Legend(
            items=legend,
            location="center_right",
            orientation="horizontal",
        )
        ax1.add_layout(legend, "above")
        ax1.legend.click_policy = "hide"

    show_layout(ax, show)

    return ax
Esempio n. 13
0
def plot_density(
    ax,
    all_labels,
    to_plot,
    colors,
    bw,
    figsize,
    length_plotters,
    rows,
    cols,
    line_width,
    markersize,
    credible_interval,
    point_estimate,
    hpd_markers,
    outline,
    shade,
    data_labels,
    backend_kwargs,
    show,
):
    """Bokeh density plot."""
    if backend_kwargs is None:
        backend_kwargs = {}

    backend_kwargs = {
        **backend_kwarg_defaults(),
        **backend_kwargs,
    }

    if ax is None:
        _, ax = _create_axes_grid(
            length_plotters,
            rows,
            cols,
            figsize=figsize,
            squeeze=False,
            backend="bokeh",
            backend_kwargs=backend_kwargs,
        )
    else:
        ax = np.atleast_2d(ax)

    axis_map = {
        label: ax_
        for label, ax_ in zip(all_labels, (item for item in ax.flatten()
                                           if item is not None))
    }
    if data_labels is None:
        data_labels = {}

    legend_items = defaultdict(list)
    for m_idx, plotters in enumerate(to_plot):
        for var_name, selection, values in plotters:
            label = make_label(var_name, selection)

            if data_labels:
                data_label = data_labels[m_idx]
            else:
                data_label = None

            plotted = _d_helper(
                values.flatten(),
                label,
                colors[m_idx],
                bw,
                line_width,
                markersize,
                credible_interval,
                point_estimate,
                hpd_markers,
                outline,
                shade,
                axis_map[label],
            )
            if data_label is not None:
                legend_items[axis_map[label]].append((data_label, plotted))

    for ax1, legend in legend_items.items():
        legend = Legend(
            items=legend,
            location="center_right",
            orientation="horizontal",
        )
        ax1.add_layout(legend, "above")
        ax1.legend.click_policy = "hide"

    if backend_show(show):
        grid = gridplot(ax.tolist(), toolbar_location="above")
        bkp.show(grid)

    return ax
Esempio n. 14
0
    def __init__(self, api_key=None, precision=6, autohide=True, padding=0.05):
        """
        Instantiate the class.
        
        Parameters
        
        api_key (str): A Google Maps API key, which can be obtained at
            developers.google.com/maps/documentation/javascript/get-api-key.
            If None, only non-Google tile providers ('osm', 'esri', 
            'wikipedia', 'cartodb') will be available.

        precision (int): The number of decimals places that are meaningful for
            the plot. Defaults to 6, which is about as precise as phone's
            GPS signal can be expected to be. This precision will get automatically
            transformed in cases where latitude and longitude are projected
            to web Mercator maps.

        autohide (bool): if True, the toolbar on plots will be hidden unless the
            mouse is hovering over the plot itself.

        padding (float): the minimum amount of space that should exist between the
            plotted objects and the edge of the map, expressed as a percentage
            of the range of the relevant direction. So a padding factor of 0.05 (the
            default) will multiply the factor by the maximum latitude minus the minimum
            latitude and add that amount to the top and bottom edges of the graph, and
            then multiply the factor by the maximum longitude minus the minimum
            longitdue and add that amount to the right and left edges of the graph.
        
        """
        self.api_key = api_key
        self.precision = precision
        self.autohide = autohide
        self.padding = padding
        self.colorbar = None

        # removed 'x_coord_point', 'y_coord_point', 'raw_data'
        self.omit_columns = [
            'index', 'x_coords', 'y_coords', 'x_coords_transform',
            'y_coords_transform', 'x_coord_point_transform',
            'y_coord_point_transform'
        ]

        self.sources = dict()
        self.columndatasources = dict()
        self.views = dict()
        self.widgets = dict()
        self.data_tables = list()
        self.custom_js = None
        self.xmin = None
        self.ymin = None
        self.xmax = None
        self.ymax = None
        self.plot = None
        self.legend = Legend(location='bottom_center',
                             click_policy='hide',
                             background_fill_color='#fafafa')
        self.validation = {
            'add_source': False,
            'add_widget': False,
            'prepare_plot': False,
            'add_layer': False,
            'render_plot': False
        }
        self.remove_columns = dict()
Esempio n. 15
0
dum_fig = figure(plot_width=300,
                 plot_height=600,
                 outline_line_alpha=0,
                 toolbar_location=None)
# set the components of the figure invisible
for fig_component in [
        dum_fig.grid[0], dum_fig.ygrid[0], dum_fig.xaxis[0], dum_fig.yaxis[0]
]:
    fig_component.visible = False
# The points referred by the legend need to be present in the figure ,so add them to figure renderers
dum_fig.renderers += posneg_list
# set the figure range outside of the range of all glyphs
dum_fig.x_range.end = 1005
dum_fig.x_range.start = 1000
# add the legend
dum_fig.add_layout(
    Legend(click_policy='mute',
           location='top_left',
           border_line_alpha=0,
           items=legend_items))

# copy list to make it later possible to delete/ add items for the list without using original list (NOT YET USED)
show_figures = figures

splom = gridplot(show_figures, ncols=3, toolbar_location='right')
final = gridplot([[splom, dum_fig]], toolbar_location=None)

show(final)
# goals: scatter plots of the blood laboratory tests next to each other.
# With the color showing positive and negative test results.
Esempio n. 16
0
def plot_energy(
    ax,
    energy,
    kind,
    bfmi,
    figsize,
    textsize,
    fill_alpha,
    fill_color,
    fill_kwargs,
    plot_kwargs,
    bw,
    legend,
    backend_kwargs,
    show,
):
    """Bokeh energy plot."""
    if backend_kwargs is None:
        backend_kwargs = {}

    backend_kwargs = {
        **backend_kwarg_defaults(("dpi", "plot.bokeh.figure.dpi")),
        **backend_kwargs,
    }
    dpi = backend_kwargs.pop("dpi")

    figsize, _, _, _, line_width, _ = _scale_fig_size(figsize, textsize, 1, 1)

    fill_kwargs = {} if fill_kwargs is None else fill_kwargs
    plot_kwargs = {} if plot_kwargs is None else plot_kwargs
    plot_kwargs.setdefault("line_width", line_width)
    if kind == "hist":
        legend = False

    if ax is None:
        ax = create_axes_grid(
            1,
            figsize=figsize,
            squeeze=True,
            backend_kwargs=backend_kwargs,
        )

    _colors = [
        prop for _, prop in zip(
            range(10), cycle(mpl_rcParams["axes.prop_cycle"].by_key()
                             ["color"]))
    ]
    if (fill_color[0].startswith("C")
            and len(fill_color[0]) == 2) and (fill_color[1].startswith("C")
                                              and len(fill_color[1]) == 2):
        fill_color = tuple(
            (_colors[int(color[1:]) % 10] for color in fill_color))
    elif fill_color[0].startswith("C") and len(fill_color[0]) == 2:
        fill_color = tuple([_colors[int(fill_color[0][1:]) % 10]] +
                           list(fill_color[1:]))
    elif fill_color[1].startswith("C") and len(fill_color[1]) == 2:
        fill_color = tuple(
            list(fill_color[1:]) + [_colors[int(fill_color[0][1:]) % 10]])

    series = zip(
        fill_alpha,
        fill_color,
        ("Marginal Energy", "Energy transition"),
        (energy - energy.mean(), np.diff(energy)),
    )

    labels = []

    if kind == "kde":
        for alpha, color, label, value in series:
            fill_kwargs["fill_alpha"] = alpha
            fill_kwargs["fill_color"] = vectorized_to_hex(color)
            plot_kwargs["line_alpha"] = alpha
            plot_kwargs["line_color"] = vectorized_to_hex(color)
            _, glyph = plot_kde(
                value,
                bw=bw,
                label=label,
                fill_kwargs=fill_kwargs,
                plot_kwargs=plot_kwargs,
                ax=ax,
                legend=legend,
                backend="bokeh",
                backend_kwargs={},
                show=False,
                return_glyph=True,
            )
            labels.append((
                label,
                glyph,
            ))

    elif kind == "hist":
        hist_kwargs = plot_kwargs.copy()
        hist_kwargs.update(**fill_kwargs)

        for alpha, color, label, value in series:
            hist_kwargs["fill_alpha"] = alpha
            hist_kwargs["fill_color"] = vectorized_to_hex(color)
            hist_kwargs["line_color"] = None
            hist_kwargs["line_alpha"] = alpha
            _histplot_bokeh_op(
                value.flatten(),
                values2=None,
                rotated=False,
                ax=ax,
                hist_kwargs=hist_kwargs,
                is_circular=False,
            )

    else:
        raise ValueError("Plot type {} not recognized.".format(kind))

    if bfmi:
        for idx, val in enumerate(e_bfmi(energy)):
            bfmi_info = Label(
                x=int(figsize[0] * dpi * 0.58),
                y=int(figsize[1] * dpi * 0.73) - 20 * idx,
                x_units="screen",
                y_units="screen",
                text="chain {:>2} BFMI = {:.2f}".format(idx, val),
                render_mode="css",
                border_line_color=None,
                border_line_alpha=0.0,
                background_fill_color="white",
                background_fill_alpha=1.0,
            )

            ax.add_layout(bfmi_info)

    if legend and label is not None:
        legend = Legend(
            items=labels,
            location="center_right",
            orientation="horizontal",
        )
        ax.add_layout(legend, "above")
        ax.legend.click_policy = "hide"

    show_layout(ax, show)

    return ax
Esempio n. 17
0
    def _create_task_panels(self, data_frame):
        panels = {}
        top_left_x_range = None
        for i, t in enumerate(self.env.task_list):
            panels[t.name] = {}
            # Panel 1: Setpoint and command panel
            pCtrl = figure(plot_width=800, plot_height=300)
            ctrl_legend = []
            # Setting the second y axis range name and range
            pCtrl.extra_y_ranges = {
                t.name + '_cmd': Range1d(start=-1, end=1)
            }  # this should query the action space
            # Adding the second axis to the plot.
            pCtrl.add_layout(
                LinearAxis(y_range_name=t.name + '_cmd',
                           axis_label=t.name + '_cmd [norm.]'), 'right')
            try:
                name = self.panel_contents[
                    t.name]['panel1']['action_prop'].get_legal_name(
                    )  #maybe there are more entries in the future
                action_Line = pCtrl.line(data_frame.index * self.step_time,
                                         data_frame[name],
                                         line_width=1,
                                         y_range_name=t.name + '_cmd',
                                         color=Viridis4[1])
                ctrl_legend.append((t.name + ' Cmd.', [action_Line]))
            except KeyError:
                #we have no action prop, only setpoints to be evaluated
                pass
            try:
                name = self.panel_contents[
                    t.name]['panel1']['current_value_prop'].get_legal_name()
                current_value_line = pCtrl.line(data_frame.index *
                                                self.step_time,
                                                data_frame[name],
                                                line_width=2,
                                                color=Viridis4[0])
                ctrl_legend.append((name, [current_value_line]))
                name = self.panel_contents[
                    t.name]['panel1']['setpoint_value_prop'].get_legal_name()
                setpoint_value_line = pCtrl.line(data_frame.index *
                                                 self.step_time,
                                                 data_frame[name],
                                                 line_width=2,
                                                 color=Viridis4[3])
                ctrl_legend.append((name, [setpoint_value_line]))
            except KeyError:
                #there is no setpoint to be displayed, only actuations
                pass

            ctrl_lg = Legend(items=ctrl_legend,
                             location=(0, 10),
                             glyph_width=25,
                             label_width=190)
            ctrl_lg.click_policy = "hide"
            pCtrl.add_layout(ctrl_lg, 'right')
            pCtrl.toolbar.active_scroll = pCtrl.toolbar.tools[
                1]  #this selects the WheelZoomTool instance
            # Add the title...
            tCtrl = Title()
            tCtrl.text = 'Controlled Value over Time'
            pCtrl.title = tCtrl
            pCtrl.xaxis.axis_label = 'timestep [s]'
            pCtrl.yaxis[0].axis_label = 'Controlled Value'

            if not top_left_x_range:
                top_left_x_range = pCtrl.x_range
            else:
                pCtrl.x_range = top_left_x_range
            panels[t.name].update({'panel1': pCtrl})

            #Panel 2: Rewards and reward components
            pRwd = figure(plot_width=1057,
                          plot_height=300,
                          x_range=top_left_x_range)
            rwd_cmp_lines = []
            reward_legend = []

            cmp_names = self.panel_contents[
                t.name]['panel2']['reward_component_names']
            for idx, rwd_component in enumerate(cmp_names):
                rwd_cmp_lines.append(
                    pRwd.line(data_frame.index * self.step_time,
                              data_frame[rwd_component],
                              line_width=2,
                              color=Viridis7[idx % 6]))
                reward_legend.append((rwd_component, [rwd_cmp_lines[-1]]))

            name = self.panel_contents[
                t.name]['panel2']['reward_prop'].get_legal_name()
            reward_line = pRwd.line(data_frame.index * self.step_time,
                                    data_frame[name],
                                    line_width=2,
                                    color=Viridis7[6])
            reward_legend.append((name, [reward_line]))

            reward_lg = Legend(items=reward_legend,
                               location=(48, 10),
                               glyph_width=25,
                               label_width=190)
            reward_lg.click_policy = "hide"
            pRwd.add_layout(reward_lg, 'right')
            pRwd.toolbar.active_scroll = pRwd.toolbar.tools[
                1]  #this selects the WheelZoomTool instance
            #Add the title
            tReward = Title()
            tReward.text = f'{t.name}: last Reward over {data_frame[name].size-1} Timesteps (∑ = {data_frame[name].sum():.2f})'
            pRwd.title = tReward
            pRwd.xaxis.axis_label = 'timestep [s]'
            pRwd.yaxis[0].axis_label = 'actual Reward [norm.]'
            panels[t.name].update({'panel2': pRwd})

            #Panel 3: Presented Observations
            pState = figure(plot_width=1057,
                            plot_height=300,
                            x_range=top_left_x_range)
            # Setting the second y axis range name and range
            norm_state_extents = 10
            pState.extra_y_ranges = {
                "normalized_data":
                Range1d(start=-norm_state_extents, end=norm_state_extents)
            }
            # Adding the second axis to the plot.
            pState.add_layout(
                LinearAxis(y_range_name="normalized_data",
                           axis_label="normalized data"), 'right')
            state_lines = []
            state_legend = []
            normalized_state_lines = []
            obs_props_names = [
                o_prp.get_legal_name()
                for o_prp in self.panel_contents[t.name]['panel3']['obs_props']
            ]
            for idx, state_name in enumerate(obs_props_names):
                if (data_frame[state_name].max() <= norm_state_extents and
                        data_frame[state_name].min() >= -norm_state_extents):
                    normalized_state_lines.append(
                        pState.line(data_frame.index * self.step_time,
                                    data_frame[state_name],
                                    line_width=2,
                                    y_range_name="normalized_data",
                                    color=Inferno7[idx % 7],
                                    visible=False))
                    state_legend.append(
                        ("norm_" + state_name, [normalized_state_lines[-1]]))
                else:
                    state_lines.append(
                        pState.line(data_frame.index * self.step_time,
                                    data_frame[state_name],
                                    line_width=2,
                                    color=Inferno7[idx % 7],
                                    visible=False))
                    state_legend.append((state_name, [state_lines[-1]]))
            pState.y_range.renderers = state_lines
            pState.extra_y_ranges.renderers = normalized_state_lines  #this does not quite work: https://stackoverflow.com/questions/48631530/bokeh-twin-axes-with-datarange1d-not-well-scaling

            lg_state = Legend(items=state_legend,
                              location=(0, 10),
                              glyph_width=25,
                              label_width=190)
            lg_state.click_policy = "hide"
            pState.add_layout(lg_state, 'right')
            pState.toolbar.active_scroll = pState.toolbar.tools[
                1]  #this selects the WheelZoomTool instance
            #Add the title
            tState = Title()
            tState.text = 'Actual Observation presented to Agent'
            pState.title = tState
            pState.xaxis.axis_label = 'timestep [s]'
            pState.yaxis[0].axis_label = 'state data'

            panels[t.name].update({'panel3': pState})

        return panels
Esempio n. 18
0
                  color=Category10[10])
# p2 = figure(x_axis_type='datetime', plot_width=10000)
# eline = p1.circle(df['время прихода точки на сервере'], df['Скорость'], line_width=2, color=Viridis6[5])

p1.yaxis.axis_label = 'Открытие/Закрытие/Уровень НП'
p1.xaxis.axis_label = 'время формирования точки на БВ'
# p2.yaxis.axis_label = 'Скорость'
# p2.xaxis.axis_label = 'время формирования точки на БВ'

legend = Legend(items=[
    ("Секция №1 Заливная горловина", [aline]),
    ("Секция №1 Датчик на дне отсека", [bline]),
    ("Секция №1 Датчик в сливной магистрали", [cline]),
    ("Секция №1 Уровень НП", [dline]),
    ("Cекция №3 Заливная горловина", [eline]),
    ("Секция №3 Датчик на дне отсека", [fline]),
    ("Секция №3 Датчик в сливной магистрали", [gline]),
    ("Секция №3 Уровень НП", [hline]),
    ("Cекция №4 Заливная горловина", [iline]),
    ("Секция №4 Датчик на дне отсека", [jline]),
    ("Секция №4 Датчик в сливной магистрали", [kline]),
],
                location=(0, 250))

t = Title()
t.text = 'BV2_DUT_sensors'
p1.title = t
# p2.title = t
p1.add_layout(legend, 'left')
p1.add_layout(LinearAxis(y_range_name="binary"), 'right')
# p2.add_layout(legend, 'left')
checkboxes = CheckboxGroup(labels=list([
Esempio n. 19
0
 def create_plot_figure(self, active_tab):
     """
     create a new plot and insert it in given tab.
     """
     #find table name of active tab and its bokeh instances
     test = active_tab.name#contains csv filename
     x_sel=active_tab.select_one({'name':'x_sel'}) 
     y_sel=active_tab.select_one({'name':'y_sel'}) 
     y_sel2=active_tab.select_one({'name':'y_sel2'}) 
     plot_df = self.plot_dfs[test]
     source = ColumnDataSource(plot_df) 
      
     #Replace entirely p with a new plot 
     p = Plot( 
              x_range=DataRange1d(),  
              y_range=DataRange1d(),  
              plot_height=600, 
              plot_width=600, 
              title=Title(text=self.sel_csv), 
              name='plot')
     p.add_tools(BoxZoomTool(),
                 SaveTool(),
                 ResetTool(),
                 PanTool(),
                 HoverTool(tooltips=[('x','$x'),
                                     ('y','$y')]))
      
     #see https://bokeh.github.io/blog/2017/7/5/idiomatic_bokeh/ 
     x_axis = LinearAxis( 
             axis_label = x_sel.value, 
             ticker=BasicTicker(desired_num_ticks =10), 
             name='x_axis') 
     y_axis = LinearAxis( 
             axis_label = y_sel.value, 
             ticker=BasicTicker(desired_num_ticks =10), 
             name='y_axis') 
     
     #primary y-axis 
     ly = p.add_glyph(source, 
                Line(x=x_sel.value,  
                y=y_sel.value,  
                line_width=2,
                line_color='black'),
                name = 'ly'
                ) 
     
     p.add_layout(x_axis,'below') 
      
     p.add_layout(y_axis,'left') 
     p.y_range.renderers = [ly]
     #secondary y-axis          
     if y_sel2.value.strip() != 'None':#secondary y-axis             
         y_axis2 = LinearAxis( 
                 axis_label = y_sel2.value, 
                 ticker=BasicTicker(desired_num_ticks=10), 
                 name='y_axis2', 
                 y_range_name='right_axis') 
         p.add_layout(y_axis2,'right') 
         p.extra_y_ranges = {"right_axis": DataRange1d()} 
         ly2 = p.add_glyph(source, 
                            Line(x=x_sel.value, 
                                y=y_sel2.value, 
                                line_width=2, 
                                line_color='red'), 
                            y_range_name='right_axis', 
                            name = 'ly2'
                           ) 
         p.extra_y_ranges['right_axis'].renderers = [ly2] 
         leg_items = [LegendItem(label=y_sel.value, 
                                      renderers=[ly]),
                      LegendItem(label=y_sel2.value,
                                 renderers=[ly2])]
     else: 
         leg_items = [LegendItem(label=y_sel.value, 
                                              renderers=[ly])] 
     
     p.add_layout(Legend(items=leg_items, 
                             location='top_right') 
                  )
     active_tab.child.children[1] = p
     return p
Esempio n. 20
0
def plot_energy(
    ax,
    series,
    energy,
    kind,
    bfmi,
    figsize,
    line_width,
    fill_kwargs,
    plot_kwargs,
    bw,
    legend,
    backend_kwargs,
    show,
):
    """Bokeh energy plot."""
    if backend_kwargs is None:
        backend_kwargs = {}

    backend_kwargs = {
        **backend_kwarg_defaults(
            ("tools", "plot.bokeh.tools"),
            ("output_backend", "plot.bokeh.output_backend"),
            ("dpi", "plot.bokeh.figure.dpi"),
        ),
        **backend_kwargs,
    }
    dpi = backend_kwargs.pop("dpi")
    if ax is None:
        ax = bkp.figure(width=int(figsize[0] * dpi),
                        height=int(figsize[1] * dpi),
                        **backend_kwargs)

    labels = []
    if kind == "kde":
        for alpha, color, label, value in series:
            fill_kwargs["fill_alpha"] = alpha
            fill_kwargs["fill_color"] = color
            plot_kwargs["line_color"] = color
            plot_kwargs["line_alpha"] = alpha
            plot_kwargs.setdefault("line_width", line_width)
            _, glyph = plot_kde(
                value,
                bw=bw,
                label=label,
                fill_kwargs=fill_kwargs,
                plot_kwargs=plot_kwargs,
                ax=ax,
                legend=legend,
                backend="bokeh",
                backend_kwargs={},
                show=False,
                return_glyph=True,
            )
            labels.append((
                label,
                glyph,
            ))

    elif kind in {"hist", "histogram"}:
        hist_kwargs = plot_kwargs.copy()
        hist_kwargs.update(**fill_kwargs)

        for alpha, color, label, value in series:
            hist_kwargs["fill_alpha"] = alpha
            hist_kwargs["fill_color"] = color
            hist_kwargs["line_color"] = None
            hist_kwargs["line_alpha"] = alpha
            _histplot_bokeh_op(value.flatten(),
                               values2=None,
                               rotated=False,
                               ax=ax,
                               hist_kwargs=hist_kwargs)

    else:
        raise ValueError("Plot type {} not recognized.".format(kind))

    if bfmi:
        for idx, val in enumerate(e_bfmi(energy)):
            bfmi_info = Label(
                x=int(figsize[0] * dpi * 0.58),
                y=int(figsize[1] * dpi * 0.73) - 20 * idx,
                x_units="screen",
                y_units="screen",
                text="chain {:>2} BFMI = {:.2f}".format(idx, val),
                render_mode="css",
                border_line_color=None,
                border_line_alpha=0.0,
                background_fill_color="white",
                background_fill_alpha=1.0,
            )

            ax.add_layout(bfmi_info)

    if legend and label is not None:
        legend = Legend(
            items=labels,
            location="center_right",
            orientation="horizontal",
        )
        ax.add_layout(legend, "above")
        ax.legend.click_policy = "hide"

    if backend_show(show):
        bkp.show(ax, toolbar_location="above")

    return ax
Esempio n. 21
0
    def cones_bokeh(self, windows=[30, 60, 90, 120], quantiles=[0.25, 0.75]):
        """Plots volatility cones
        Parameters
        ----------
        windows : [int, int, ...]
            List of rolling windows for which to calculate the estimator cones
        quantiles : [lower, upper]
            List of lower and upper quantiles for which to plot the cones
        """
        top_q, median, bottom_q, realized, min, max, f, data = self.cones_prepare_data(
            windows, quantiles)
        colors_list = ['orange', 'blue', 'pink', 'black', 'red', 'green']
        methods_list = [
            'x', 'diamond', 'x', 'square', 'inverted_triangle',
            'inverted_triangle'
        ]
        line_dash_list = [
            'dotted', 'dotdash', 'dotted', 'solid', 'dashed', 'dashed'
        ]
        xs = [windows, windows, windows, windows, windows, windows]
        ys = [top_q, median, bottom_q, realized, min, max]
        legends_list = [
            str(int(quantiles[1] * 100)) + " Prctl", 'Median',
            str(int(quantiles[0] * 100)) + " Prctl", 'Realized', 'Min', 'Max'
        ]
        title = self._estimator + ' (' + self._symbol + ', daily from ' + self._last_date + ' days back ' + str(
            self._num_days_back) + ')'
        p = figure(title=title,
                   plot_width=700,
                   plot_height=500,
                   toolbar_sticky=False,
                   x_axis_label="Days",
                   y_axis_label="Volatility",
                   toolbar_location="below")
        legend_items = []
        for (colr, leg, x, y, method,
             line_dash) in zip(colors_list, legends_list, xs, ys, methods_list,
                               line_dash_list):
            # call dynamically the method to plot line, circle etc...
            renderers = []
            if method:
                renderers.append(getattr(p, method)(x, y, color=colr, size=4))
            renderers.append(p.line(x, y, color=colr, line_dash=line_dash))
            legend_items.append((leg, renderers))
        # doesnt work: legend = Legend(location=(0, -30), items=legend_items)
        legend = Legend(location=(0, -30), items=legend_items)
        p.add_layout(legend, 'right')

        from bokeh.charts import BoxPlot
        df = pandas.DataFrame({"data": data[0], "group": 0})
        df = df.append(pandas.DataFrame({"data": data[1], "group": 1}))
        df = df.append(pandas.DataFrame({"data": data[2], "group": 2}))
        df = df.append(pandas.DataFrame({"data": data[3], "group": 3}))
        p2 = BoxPlot(df,
                     values='data',
                     label='group',
                     title="Boxplot Summary (" + self._last_date + ") (" +
                     self._symbol + ")",
                     toolbar_location="below",
                     legend="bottom_right",
                     plot_width=600,
                     plot_height=400,
                     toolbar_sticky=False)
        from bokeh.models.ranges import DataRange1d
        p2.y_range = DataRange1d(np.min(df['data'] - 0.01),
                                 np.max(df['data'] + 0.01))

        layout1 = layout([[p, p2]])
        script, div = components(layout1)
        save_graph_to_db(script,
                         div,
                         self._symbol,
                         self._expiry,
                         self._last_date,
                         self._num_days_back,
                         self._resample,
                         self._estimator,
                         name="VOLEST")
        return layout1
# eline = p1.circle(df['время прихода точки на сервере'], df['Скорость'], line_width=2, color=Viridis6[5])

p1.yaxis.axis_label = 'Бинарные/Действительные значения'
p1.xaxis.axis_label = 'временная шкала'
# p2.yaxis.axis_label = 'Скорость'
# p2.xaxis.axis_label = 'время формирования точки на БВ'

legend = Legend(items=[
    ("Binary 1", [aline]),
    ("Binary 2", [bline]),
    ("Binary 3", [cline]),
    ("Binary 4", [ccline]),
    ("Real 1", [dline]),
    ("Binary 5", [ddline]),
    ("Binary 6", [eline]),
    ("Binary 7", [fline]),
    ("Binary 8", [gline]),
    ("Binary 9", [ggline]),
    ("Real 2", [hline]),
    ("Binary 10", [iline]),
    ("Binary 11", [jline]),
    ("Binary 12", [kline]),
    ("Binary 13", [kkline]),
],
                location=(0, 250))

t = Title()
t.text = 'BOKEH_TEMPLATE_EMOTION_REC'
p1.title = t
# p2.title = t
p1.add_layout(legend, 'left')
p1.add_layout(LinearAxis(y_range_name="binary"), 'right')
row1 = []
row2 = []

for i in range(0, len(categories_197)):
    plot_197 = figure(title=labels_197[i], x_axis_type='datetime')
    p_cat = plot_197.line(data_197['WEEK'],
                          data_197[categories_197[i]],
                          line_color='navy',
                          line_width=2.5,
                          alpha=0.3)
    p_ma = plot_197.line(data_197['WEEK'],
                         data_197[moving_avg_197[i]],
                         line_color='red',
                         line_width=2.5)
    legend = Legend(items=[('Weekly Total', [p_cat]), ('90 Day MA', [p_ma])],
                    location='top_center',
                    background_fill_color=None,
                    border_line_color=None)
    plot_197.xaxis.axis_line_color = None
    plot_197.yaxis.axis_line_color = None
    plot_197.yaxis.minor_tick_line_color = None
    plot_197.title.align = 'center'
    plot_197.title.text_font_size = '12pt'
    plot_197.outline_line_color = None
    plot_197.xgrid.grid_line_color = None
    plot_197.ygrid.grid_line_color = None
    # set up axes for the top left graph
    if i == 0:
        plot_197.yaxis.major_tick_line_width = 2.5
        plot_197.yaxis.major_label_text_font_size = '10pt'
        plot_197.yaxis.formatter = NumeralTickFormatter(format='$0,000')
        plot_197.y_range = Range1d(0, max_1_197)
Esempio n. 24
0
    def generate_graph(self):
        """
        Generate the graph; return a 2-tuple of strings, script to place in the
        head of the HTML document and div content for the graph itself.

        :return: 2-tuple (script, div)
        :rtype: tuple
        """
        logger.debug('Generating graph for %s', self._graph_id)
        # tools to use
        tools = [
            PanTool(),
            BoxZoomTool(),
            WheelZoomTool(),
            SaveTool(),
            ResetTool(),
            ResizeTool()
        ]

        # generate the stacked area graph
        try:
            g = Area(
                self._data, x='Date', y=self._y_series_names,
                title=self._title, stack=True, xlabel='Date',
                ylabel='Downloads', tools=tools,
                # note the width and height will be set by JavaScript
                plot_height=400, plot_width=800,
                toolbar_location='above', legend=False
            )
        except Exception as ex:
            logger.error("Error generating %s graph", self._graph_id)
            logger.error("Data: %s", self._data)
            logger.error("y=%s", self._y_series_names)
            raise ex

        lines = []
        legend_parts = []
        # add a line at the top of each Patch (stacked area) for hovertool
        for renderer in g.select(GlyphRenderer):
            if not isinstance(renderer.glyph, Patches):
                continue
            series_name = renderer.data_source.data['series'][0]
            logger.debug('Adding line for Patches %s (series: %s)', renderer,
                         series_name)
            line = self._line_for_patches(self._data, g, renderer, series_name)
            if line is not None:
                lines.append(line)
                legend_parts.append((series_name, [line]))

        # add the Hovertool, specifying only our line glyphs
        g.add_tools(
            HoverTool(
                tooltips=[
                    (self._y_name, '@SeriesName'),
                    ('Date', '@FmtDate'),
                    ('Downloads', '@Downloads'),
                ],
                renderers=lines,
                line_policy='nearest'
            )
        )

        # legend outside chart area
        legend = Legend(legends=legend_parts, location=(0, 0))
        g.add_layout(legend, 'right')
        return components(g)
Esempio n. 25
0
def plot_ess(
    ax,
    plotters,
    xdata,
    ess_tail_dataset,
    mean_ess,
    sd_ess,
    idata,
    data,
    text_x,
    text_va,
    kind,
    extra_methods,
    rows,
    cols,
    figsize,
    kwargs,
    extra_kwargs,
    text_kwargs,
    _linewidth,
    _markersize,
    n_samples,
    relative,
    min_ess,
    xt_labelsize,
    titlesize,
    ax_labelsize,
    ylabel,
    rug,
    rug_kind,
    rug_kwargs,
    hline_kwargs,
    backend_kwargs,
    show,
):
    """Bokeh essplot."""
    if backend_kwargs is None:
        backend_kwargs = {}

    backend_kwargs = {
        **backend_kwarg_defaults(("dpi", "plot.bokeh.figure.dpi"), ),
        **backend_kwargs,
    }
    if ax is None:
        _, ax = _create_axes_grid(
            len(plotters),
            rows,
            cols,
            figsize=figsize,
            squeeze=False,
            constrained_layout=True,
            backend="bokeh",
            backend_kwargs=backend_kwargs,
        )
    else:
        ax = np.atleast_2d(ax)

    for (var_name, selection,
         x), ax_ in zip(plotters,
                        (item for item in ax.flatten() if item is not None)):
        bulk_points = ax_.circle(np.asarray(xdata), np.asarray(x), size=6)
        if kind == "evolution":
            bulk_line = ax_.line(np.asarray(xdata), np.asarray(x))
            ess_tail = ess_tail_dataset[var_name].sel(**selection)
            tail_points = ax_.line(np.asarray(xdata),
                                   np.asarray(ess_tail),
                                   color="orange")
            tail_line = ax_.circle(np.asarray(xdata),
                                   np.asarray(ess_tail),
                                   size=6,
                                   color="orange")
        elif rug:
            if rug_kwargs is None:
                rug_kwargs = {}
            if not hasattr(idata, "sample_stats"):
                raise ValueError(
                    "InferenceData object must contain sample_stats for rug plot"
                )
            if not hasattr(idata.sample_stats, rug_kind):
                raise ValueError(
                    "InferenceData does not contain {} data".format(rug_kind))

            rug_kwargs.setdefault("space", 0.1)
            _rug_kwargs = {}
            _rug_kwargs.setdefault("size", 8)
            _rug_kwargs.setdefault("line_color",
                                   rug_kwargs.get("line_color", "black"))
            _rug_kwargs.setdefault("line_width", 1)
            _rug_kwargs.setdefault("line_alpha", 0.35)
            _rug_kwargs.setdefault("angle", np.pi / 2)

            values = data[var_name].sel(**selection).values.flatten()
            mask = idata.sample_stats[rug_kind].values.flatten()
            values = rankdata(values)[mask]
            rug_space = np.max(x) * rug_kwargs.pop("space")
            rug_x, rug_y = values / (len(mask) -
                                     1), np.zeros_like(values) - rug_space

            glyph = Dash(x="rug_x", y="rug_y", **_rug_kwargs)
            cds_rug = ColumnDataSource({
                "rug_x": np.asarray(rug_x),
                "rug_y": np.asarray(rug_y)
            })
            ax_.add_glyph(cds_rug, glyph)

            hline = Span(
                location=0,
                dimension="width",
                line_color="black",
                line_width=_linewidth,
                line_alpha=0.7,
            )

            ax_.renderers.append(hline)

        if extra_methods:
            mean_ess_i = mean_ess[var_name].sel(**selection).values.item()
            sd_ess_i = sd_ess[var_name].sel(**selection).values.item()

            hline = Span(
                location=mean_ess_i,
                dimension="width",
                line_color="black",
                line_width=2,
                line_dash="dashed",
                line_alpha=1.0,
            )

            ax_.renderers.append(hline)

            hline = Span(
                location=sd_ess_i,
                dimension="width",
                line_color="black",
                line_width=1,
                line_dash="dashed",
                line_alpha=1.0,
            )

            ax_.renderers.append(hline)

        hline = Span(
            location=400 / n_samples if relative else min_ess,
            dimension="width",
            line_color="red",
            line_width=3,
            line_dash="dashed",
            line_alpha=1.0,
        )

        ax_.renderers.append(hline)

        if kind == "evolution":
            legend = Legend(
                items=[("bulk", [bulk_points, bulk_line]),
                       ("tail", [tail_line, tail_points])],
                location="center_right",
                orientation="horizontal",
            )
            ax_.add_layout(legend, "above")
            ax_.legend.click_policy = "hide"

        title = Title()
        title.text = make_label(var_name, selection)
        ax_.title = title

        ax_.xaxis.axis_label = "Total number of draws" if kind == "evolution" else "Quantile"
        ax_.yaxis.axis_label = ylabel.format(
            "Relative ESS" if relative else "ESS")

    show_layout(ax, show)

    return ax
Esempio n. 26
0
    def _show_graph(self, data_frame):

        #create the plot panels for the Agent_Tasks
        panels = self._create_task_panels(data_frame)

        top_left_x_range = panels[list(panels.keys())[0]]['panel1'].x_range

        #Altitude over ground
        pAltitude = figure(plot_width=800,
                           plot_height=300,
                           x_range=top_left_x_range)
        alti_legend = []
        # Setting the second y axis range name and range
        pAltitude.extra_y_ranges = {"speed": Range1d(50, 120)}
        # Adding the second axis to the plot.
        pAltitude.add_layout(
            LinearAxis(y_range_name="speed", axis_label="IAS, TAS [Knots]"),
            'right')

        altitudeLine = pAltitude.line(data_frame.index * self.step_time,
                                      data_frame['position_h_sl_ft'],
                                      line_width=2,
                                      color=Viridis4[2])
        alti_legend.append(("Altitude [ftsl]", [altitudeLine]))
        kiasLine = pAltitude.line(data_frame.index * self.step_time,
                                  data_frame['velocities_vc_kts'],
                                  line_width=2,
                                  y_range_name="speed",
                                  color=Viridis4[1])
        alti_legend.append(("Indicated Airspeed [KIAS]", [kiasLine]))
        tasLine = pAltitude.line(data_frame.index * self.step_time,
                                 data_frame['velocities_vtrue_kts'],
                                 line_width=2,
                                 y_range_name="speed",
                                 color=Viridis4[0])
        alti_legend.append(("True Airspeed [KAS]", [tasLine]))
        pAltitude.extra_y_ranges.renderers = [
            kiasLine, tasLine
        ]  #this does not quite work: https://stackoverflow.com/questions/48631530/bokeh-twin-axes-with-datarange1d-not-well-scaling
        pAltitude.y_range.renderers = [altitudeLine]

        lg_alti = Legend(items=alti_legend,
                         location=(0, 10),
                         glyph_width=25,
                         label_width=190)
        lg_alti.click_policy = "hide"
        pAltitude.add_layout(lg_alti, 'right')

        tAlti = Title()
        tAlti.text = 'Altitude and Speed [IAS, TAS] over Timesteps'
        pAltitude.title = tAlti
        pAltitude.xaxis.axis_label = 'timestep [s]'
        pAltitude.yaxis[0].axis_label = 'Altitude [ftsl]'
        pAltitude.legend.location = "center_right"

        pSideslip = figure(plot_width=800,
                           plot_height=300,
                           x_range=top_left_x_range)
        slip_legend = []

        slip_skid_line = pSideslip.line(data_frame.index * self.step_time,
                                        data_frame['aero_beta_deg'],
                                        line_width=2,
                                        color=Viridis4[2])
        slip_legend.append(("Sideslip", [slip_skid_line]))
        pSideslip.y_range.renderers = [slip_skid_line]

        lg_slip = Legend(items=slip_legend,
                         location=(0, 10),
                         glyph_width=25,
                         label_width=190)
        lg_slip.click_policy = "hide"
        pSideslip.add_layout(lg_slip, 'right')

        tSlip = Title()
        tSlip.text = 'Sideslip'
        pSideslip.title = tSlip
        pSideslip.xaxis.axis_label = 'timestep [s]'
        pSideslip.yaxis[0].axis_label = 'Sideslip [deg]'
        pSideslip.legend.location = "center_right"

        #activate the zooming on all plots
        #this is not nice, but this not either: https://stackoverflow.com/questions/49282688/how-do-i-set-default-active-tools-for-a-bokeh-gridplot
        pAltitude.toolbar.active_scroll = pAltitude.toolbar.tools[
            1]  #this selects the WheelZoomTool instance
        pSideslip.toolbar.active_scroll = pSideslip.toolbar.tools[
            1]  #this selects the WheelZoomTool instance

        reset_output()

        # if self.env.meta_dict['model_type'] == 'trained':
        #     discriminator = self.env.meta_dict['model_base_name']+"_%+.2f" % (data_frame['reward'].sum())
        #     self.env.meta_dict['model_discriminator'] = discriminator
        # else:
        #     discriminator = self.env.meta_dict['model_discriminator']

        ts = time.time()
        overshoot_frames_per_task = self._analyze_overshoot(data_frame)
        overshoot_divs = [
            Div(text=ovs_fr.round(3).to_html(), width=600)
            for ovs_fr in overshoot_frames_per_task
        ]
        print("Overshoot analysis done in %.2f sec" % (time.time() - ts))

        ts = time.time()
        settlement_times_per_task = self._analyze_settle_times(data_frame)
        settlement_divs = [
            Div(text=settle_fr.round(3).to_html(), width=600)
            for settle_fr in settlement_times_per_task
        ]
        print("Settlement analysis done in %.2f sec" % (time.time() - ts))

        panel_grid = []
        panel_grid.append([
            Div(text='<h3>' + t.name + '</h3>', id='div_' + t.name)
            for t in self.env.task_list
        ])

        # to switch on and off the statistics panels, this is unfortuntely the best, I could achive
        # https://stackoverflow.com/a/52416676/2682209
        cols = []
        checkbox = CheckboxGroup(
            labels=["show stats"], active=[],
            width=100)  #checkbox is added to header_col later on

        for i, t in enumerate(self.env.task_list):
            # overshoot_stat = overshoot_divs[i]
            c = column(Div())  #empty for the beginning
            cols.append(c)

        callback = CustomJS(args=dict(overshoot_divs=overshoot_divs,
                                      settlement_divs=settlement_divs,
                                      cols=cols,
                                      checkbox=checkbox),
                            code="""
                    for (var j = 0; j < cols.length; j++) {
                        console.log('col', j)
                        const children = []
                        for (const i of checkbox.active) {
                            console.log('active', i)
                            children.push(overshoot_divs[j])
                            children.push(settlement_divs[j])
                        } 
                        console.log('children', children)
                        cols[j].children = children
                    }
                    """)
        checkbox.js_on_change('active', callback)

        # show_stats_btn = [Div(text="""
        # <button onclick="display_event(%s)">Try it</button>
        # """ %t.name for t in self.env.task_list]
        # for t, b in zip(self.env.task_list, show_stats_btn):
        #     b.tags = ['id', 'btn_'+t.name]
        # panel_grid.append(show_stats_btn)
        # [b.js_on_event(events.ButtonClick, display_event(b, t.name)) for t, b in zip(self.env.task_list, show_stats_btn)]

        # panel_grid.append(chkbxs)
        panel_grid.append(cols)

        panel_grid_t = [[
            panels[name]['panel1'], panels[name]['panel2'],
            panels[name]['panel3']
        ] for name in self.task_names]
        [panel_grid.append(fig) for fig in list(zip(*panel_grid_t))]

        # add the additional plots
        panel_grid.append([pAltitude, pSideslip])

        panel_grid_plot = gridplot(panel_grid,
                                   toolbar_location='right',
                                   sizing_mode='stretch_width')

        #for string formatting look here: https://pyformat.info/
        titleString = ''
        if 'experiment_name' in self.env.meta_dict:
            titleString += "{}: ".format(self.env.meta_dict['experiment_name'])
        titleString += "Run Date: {}; ".format(
            datetime.datetime.now().strftime("%c"))

        if 'train_step' in self.env.meta_dict:
            titleString += "Training Step: {}; ".format(
                self.env.meta_dict['train_step'])
        if 'episode_number' in self.env.meta_dict:
            titleString += "Episode: {}; ".format(
                self.env.meta_dict['episode_number'])
        if 'csv_line_nr' in self.env.meta_dict:
            titleString += "Env in CSV line: {}; ".format(
                self.env.meta_dict['csv_line_nr'])
        # titleString += "Total Reward: {:.2f}; ".format(data_frame['reward'].sum())
        # titleString += "Model Discriminator: {};".format(self.env.meta_dict['model_discriminator'])
        header_col = column(
            Div(text="<h1>" + self.env.unwrapped.spec.id +
                (" - " + self.env.meta_dict['env_info']) if 'env_info' in
                self.meta_dict else "" + "</h1>"),
            row(Div(text="<h2>" + titleString + "</h2>", width=1200),
                checkbox))

        webpage = gridplot([[header_col], [panel_grid_plot]],
                           toolbar_location=None,
                           sizing_mode='stretch_width')

        base_filename = 'Run_' + '_'.join([tsk.name for tsk in self.task_list])
        html_output_name = os.path.join(self.save_path, 'plots',
                                        base_filename + '_latest.html')
        os.makedirs(os.path.dirname(html_output_name), exist_ok=True)

        if self.showNextPlotFlag:
            output_file(
                html_output_name, mode='inline'
            )  #mode='absolute') #use mode='absolute' to make it work offline with the js and css installed in the bokeh package locally
            if self.firstRun:
                show(webpage)  #opens up a new browser window
                self.firstRun = False
            else:
                save(
                    webpage
                )  #just updates the HTML; Manual F5 in browser required :-(, (There must be a way to push...)

        if self.exportNextPlotFlag and self.save_path:
            #build the filename including the individual rewards
            task_rewards = [
                self.reward_variables[i].get_legal_name()
                for i in range(len(self.task_list))
            ]
            task_names_with_rewards = [
                t.name + '_' + f'{data_frame[task_rewards[i]].sum():.2f}'
                for i, t in enumerate(self.task_list)
            ]
            name_with_rewards = 'Run_' + '_'.join(
                task_names_with_rewards) + 'time_{}'.format(
                    datetime.datetime.now().strftime("%H-%M-%S"))
            base_filename = os.path.join(
                self.save_path, 'plots', name_with_rewards
            )  # 'glideAngle_Elevator_Reward_{:.2f}_time_{}'.format(data_frame['reward'].sum(), datetime.datetime.now().strftime("%H-%M-%S")))
            if self.showNextPlotFlag:
                #we keep the html as well for easy exploration
                shutil.copyfile(html_output_name, base_filename + '.html')

            def export(webpage):
                png_filename = base_filename + '.png'
                webpage.width = 1800  #set the width of the page instead of passing a width parameter to the export; https://stackoverflow.com/a/61563173/2682209
                export_png(
                    webpage, filename=png_filename
                )  #TODO: the width parameter is ignored in bokeh/io/export.py get_layout_html() as webpage isn't a Plot

            export(
                gridplot([[header_col], [panel_grid_plot]],
                         toolbar_location=None))

        self.showNextPlotFlag = False  #only show the plot once and then reset
        self.exportNextPlotFlag = False
        print("Output Plot generated: " + titleString)
Esempio n. 27
0
def plot_ppc(
    ax,
    length_plotters,
    rows,
    cols,
    figsize,
    animated,
    obs_plotters,
    pp_plotters,
    predictive_dataset,
    pp_sample_ix,
    kind,
    alpha,
    colors,
    textsize,
    mean,
    observed,
    jitter,
    total_pp_samples,
    legend,  # pylint: disable=unused-argument
    labeller,
    group,  # pylint: disable=unused-argument
    animation_kwargs,  # pylint: disable=unused-argument
    num_pp_samples,
    backend_kwargs,
    show,
):
    """Bokeh ppc plot."""
    if backend_kwargs is None:
        backend_kwargs = {}

    backend_kwargs = {
        **backend_kwarg_defaults(("dpi", "plot.bokeh.figure.dpi"), ),
        **backend_kwargs,
    }

    colors = vectorized_to_hex(colors)

    (figsize, *_, linewidth,
     markersize) = _scale_fig_size(figsize, textsize, rows, cols)
    if ax is None:
        axes = create_axes_grid(
            length_plotters,
            rows,
            cols,
            figsize=figsize,
            backend_kwargs=backend_kwargs,
        )
    else:
        axes = np.atleast_2d(ax)

        if len([item for item in axes.ravel() if not None]) != length_plotters:
            raise ValueError(
                "Found {} variables to plot but {} axes instances. They must be equal."
                .format(length_plotters, len(axes)))

    if alpha is None:
        if animated:
            alpha = 1
        else:
            if kind.lower() == "scatter":
                alpha = 0.7
            else:
                alpha = 0.2

    if jitter is None:
        jitter = 0.0
    if jitter < 0.0:
        raise ValueError("jitter must be >=0.")

    for i, ax_i in enumerate(
        (item for item in axes.flatten() if item is not None)):
        var_name, sel, isel, obs_vals = obs_plotters[i]
        pp_var_name, _, _, pp_vals = pp_plotters[i]
        dtype = predictive_dataset[pp_var_name].dtype.kind
        legend_it = []

        if dtype not in ["i", "f"]:
            raise ValueError(
                f"The data type of the predictive data must be one of 'i' or 'f', but is '{dtype}'"
            )

        # flatten non-specified dimensions
        obs_vals = obs_vals.flatten()
        pp_vals = pp_vals.reshape(total_pp_samples, -1)
        pp_sampled_vals = pp_vals[pp_sample_ix]

        if kind == "kde":
            plot_kwargs = {
                "line_color": colors[0],
                "line_alpha": alpha,
                "line_width": 0.5 * linewidth,
            }

            pp_densities = []
            pp_xs = []
            for vals in pp_sampled_vals:
                vals = np.array([vals]).flatten()
                if dtype == "f":
                    pp_x, pp_density = kde(vals)
                    pp_densities.append(pp_density)
                    pp_xs.append(pp_x)
                else:
                    bins = get_bins(vals)
                    _, hist, bin_edges = histogram(vals, bins=bins)
                    hist = np.concatenate((hist[:1], hist))
                    pp_densities.append(hist)
                    pp_xs.append(bin_edges)

            if dtype == "f":
                multi_line = ax_i.multi_line(pp_xs, pp_densities,
                                             **plot_kwargs)
                legend_it.append(
                    (f"{group.capitalize()} predictive", [multi_line]))
            else:
                all_steps = []
                for x_s, y_s in zip(pp_xs, pp_densities):
                    step = ax_i.step(x_s, y_s, **plot_kwargs)
                    all_steps.append(step)
                legend_it.append(
                    (f"{group.capitalize()} predictive", all_steps))

            if observed:
                label = "Observed"
                if dtype == "f":
                    _, glyph = plot_kde(
                        obs_vals,
                        plot_kwargs={
                            "line_color": colors[1],
                            "line_width": linewidth
                        },
                        fill_kwargs={"alpha": 0},
                        ax=ax_i,
                        backend="bokeh",
                        backend_kwargs={},
                        show=False,
                        return_glyph=True,
                    )
                    legend_it.append((label, glyph))
                else:
                    bins = get_bins(obs_vals)
                    _, hist, bin_edges = histogram(obs_vals, bins=bins)
                    hist = np.concatenate((hist[:1], hist))
                    step = ax_i.step(
                        bin_edges,
                        hist,
                        line_color=colors[1],
                        line_width=linewidth,
                        mode="center",
                    )
                    legend_it.append((label, [step]))

            if mean:
                label = f"{group.capitalize()} predictive mean"
                if dtype == "f":
                    rep = len(pp_densities)
                    len_density = len(pp_densities[0])

                    new_x = np.linspace(np.min(pp_xs), np.max(pp_xs),
                                        len_density)
                    new_d = np.zeros((rep, len_density))
                    bins = np.digitize(pp_xs, new_x, right=True)
                    new_x -= (new_x[1] - new_x[0]) / 2
                    for irep in range(rep):
                        new_d[irep][bins[irep]] = pp_densities[irep]
                    line = ax_i.line(
                        new_x,
                        new_d.mean(0),
                        color=colors[2],
                        line_dash="dashed",
                        line_width=linewidth,
                    )
                    legend_it.append((label, [line]))
                else:
                    vals = pp_vals.flatten()
                    bins = get_bins(vals)
                    _, hist, bin_edges = histogram(vals, bins=bins)
                    hist = np.concatenate((hist[:1], hist))
                    step = ax_i.step(
                        bin_edges,
                        hist,
                        line_color=colors[2],
                        line_width=linewidth,
                        line_dash="dashed",
                        mode="center",
                    )
                    legend_it.append((label, [step]))
            ax_i.yaxis.major_tick_line_color = None
            ax_i.yaxis.minor_tick_line_color = None
            ax_i.yaxis.major_label_text_font_size = "0pt"

        elif kind == "cumulative":
            if observed:
                label = "Observed"
                if dtype == "f":
                    glyph = ax_i.line(
                        *_empirical_cdf(obs_vals),
                        line_color=colors[1],
                        line_width=linewidth,
                    )
                    glyph.level = "overlay"
                    legend_it.append((label, [glyph]))

                else:
                    step = ax_i.step(
                        *_empirical_cdf(obs_vals),
                        line_color=colors[1],
                        line_width=linewidth,
                        mode="center",
                    )
                    legend_it.append((label, [step]))
            pp_densities = np.empty(
                (2 * len(pp_sampled_vals), pp_sampled_vals[0].size))
            for idx, vals in enumerate(pp_sampled_vals):
                vals = np.array([vals]).flatten()
                pp_x, pp_density = _empirical_cdf(vals)
                pp_densities[2 * idx] = pp_x
                pp_densities[2 * idx + 1] = pp_density
            multi_line = ax_i.multi_line(
                list(pp_densities[::2]),
                list(pp_densities[1::2]),
                line_alpha=alpha,
                line_color=colors[0],
                line_width=linewidth,
            )
            legend_it.append(
                (f"{group.capitalize()} predictive", [multi_line]))
            if mean:
                label = f"{group.capitalize()} predictive mean"
                line = ax_i.line(
                    *_empirical_cdf(pp_vals.flatten()),
                    color=colors[2],
                    line_dash="dashed",
                    line_width=linewidth,
                )
                legend_it.append((label, [line]))

        elif kind == "scatter":
            if mean:
                label = f"{group.capitalize()} predictive mean"
                if dtype == "f":
                    _, glyph = plot_kde(
                        pp_vals.flatten(),
                        plot_kwargs={
                            "line_color": colors[2],
                            "line_dash": "dashed",
                            "line_width": linewidth,
                        },
                        ax=ax_i,
                        backend="bokeh",
                        backend_kwargs={},
                        show=False,
                        return_glyph=True,
                    )
                    legend_it.append((label, glyph))
                else:
                    vals = pp_vals.flatten()
                    bins = get_bins(vals)
                    _, hist, bin_edges = histogram(vals, bins=bins)
                    hist = np.concatenate((hist[:1], hist))
                    step = ax_i.step(
                        bin_edges,
                        hist,
                        color=colors[2],
                        line_width=linewidth,
                        line_dash="dashed",
                        mode="center",
                    )
                    legend_it.append((label, [step]))

            jitter_scale = 0.1
            y_rows = np.linspace(0, 0.1, num_pp_samples + 1)
            scale_low = 0
            scale_high = jitter_scale * jitter

            if observed:
                label = "Observed"
                obs_yvals = np.zeros_like(obs_vals, dtype=np.float64)
                if jitter:
                    obs_yvals += np.random.uniform(low=scale_low,
                                                   high=scale_high,
                                                   size=len(obs_vals))
                glyph = ax_i.circle(
                    obs_vals,
                    obs_yvals,
                    line_color=colors[1],
                    fill_color=colors[1],
                    size=markersize,
                    line_alpha=alpha,
                )
                glyph.level = "overlay"
                legend_it.append((label, [glyph]))

            all_scatter = []
            for vals, y in zip(pp_sampled_vals, y_rows[1:]):
                vals = np.ravel(vals)
                yvals = np.full_like(vals, y, dtype=np.float64)
                if jitter:
                    yvals += np.random.uniform(low=scale_low,
                                               high=scale_high,
                                               size=len(vals))
                scatter = ax_i.scatter(
                    vals,
                    yvals,
                    line_color=colors[0],
                    fill_color=colors[0],
                    size=markersize,
                    fill_alpha=alpha,
                )
                all_scatter.append(scatter)

            legend_it.append((f"{group.capitalize()} predictive", all_scatter))
            ax_i.yaxis.major_tick_line_color = None
            ax_i.yaxis.minor_tick_line_color = None
            ax_i.yaxis.major_label_text_font_size = "0pt"

        if legend:
            legend = Legend(
                items=legend_it,
                location="top_left",
                orientation="vertical",
            )
            ax_i.add_layout(legend)
            if textsize is not None:
                ax_i.legend.label_text_font_size = f"{textsize}pt"
            ax_i.legend.click_policy = "hide"
        ax_i.xaxis.axis_label = labeller.make_pp_label(var_name, pp_var_name,
                                                       sel, isel)

    show_layout(axes, show)

    return axes
Esempio n. 28
0
def plot_binary_columns(contexts, layer, acts_tag, color_cols, legend=False):
    """
    Given a layer, and a list of binary columns in the contexts dataframe,
    plots all activations at the specified layer, colorized to visualize all the specified columns.
    TODO: document requirements of contexts dataframe.
    """
    p = empty_plot()
    if legend:  # add legend
        p.height += 200
        p.add_layout(
            Legend(orientation='vertical',
                   label_text_font_size='6pt',
                   label_width=10), 'above')

    # add all contexts in grey
    source = ColumnDataSource({
        'x':
        contexts[f'{layer} {acts_tag} x'],
        'y':
        contexts[f'{layer} {acts_tag} y'],
        'token':
        contexts['token'],
        'abbreviated context':
        contexts['abbreviated context'],
        'abbreviated context html':
        contexts['abbreviated context html'],
        'context html':
        contexts['context html']
    })
    p.circle('x', 'y', color='lightgrey', source=source)
    # add each column's contexts in a color
    for col_idx, col in enumerate(color_cols):
        selected_contexts = contexts[contexts[col]]
        source = ColumnDataSource({
            'x':
            selected_contexts[f'{layer} {acts_tag} x'],
            'y':
            selected_contexts[f'{layer} {acts_tag} y'],
            'token':
            selected_contexts['token'],
            'abbreviated context':
            selected_contexts['abbreviated context'],
            'abbreviated context html':
            selected_contexts['abbreviated context html'],
            'context html':
            selected_contexts['context html'],
        })
        if legend:
            p.circle('x',
                     'y',
                     color=DEFAULT_PALETTE[col_idx],
                     legend_label=col,
                     source=source)
        else:
            p.circle('x', 'y', color=DEFAULT_PALETTE[col_idx], source=source)

    p.tools = [
        PanTool(),
        WheelZoomTool(),
        BoxZoomTool(),
        ResetTool(),
        custom_hover_tool()
    ]
    return p
                  line_width=2,
                  color=Category10[6])

# p2 = figure(x_axis_type='datetime', plot_width=10000)
# eline = p1.circle(df['время прихода точки на сервере'], df['Скорость'], line_width=2, color=Viridis6[5])

p1.yaxis.axis_label = 'Температура НП'
p1.xaxis.axis_label = 'время формирования точки на БВ'
p2.yaxis.axis_label = 'Температура НП'
p2.xaxis.axis_label = 'время формирования точки на БВ'
# p2.yaxis.axis_label = 'Скорость'
# p2.xaxis.axis_label = 'время формирования точки на БВ'

legend1 = Legend(items=[
    ('Секция №1 Температура НП, БВ1', [aline]),
    ('Секция №3 Температура НП, БВ1', [bline]),
],
                 location=(0, 250))

legend2 = Legend(items=[
    ('Секция №1 Температура НП, БВ2', [cline]),
    ('Секция №3 Температура НП, БВ2', [dline]),
],
                 location=(0, 250))

t1 = Title()
t1.text = 'Temperatures_BV1'
p1.title = t1

t2 = Title()
t2.text = 'Temperatures_BV1'
Esempio n. 30
0
def plot_lm(
    x,
    y,
    y_model,
    y_hat,
    num_samples,
    kind_pp,
    kind_model,
    length_plotters,
    xjitter,
    rows,
    cols,
    y_kwargs,
    y_hat_plot_kwargs,
    y_hat_fill_kwargs,
    y_model_plot_kwargs,
    y_model_fill_kwargs,
    y_model_mean_kwargs,
    backend_kwargs,
    show,
    figsize,
    textsize,
    axes,
    legend,
    grid,  # pylint: disable=unused-argument
):
    """Bokeh linreg plot."""
    if backend_kwargs is None:
        backend_kwargs = {}

    backend_kwargs = {
        **backend_kwarg_defaults(),
        **backend_kwargs,
    }

    figsize, *_ = _scale_fig_size(figsize, textsize, rows, cols)
    if axes is None:
        axes = create_axes_grid(length_plotters, rows, cols, backend_kwargs=backend_kwargs)

    if y_kwargs is None:
        y_kwargs = {}
    y_kwargs.setdefault("fill_color", "red")
    y_kwargs.setdefault("line_width", 0)
    y_kwargs.setdefault("size", 3)

    if y_hat_plot_kwargs is None:
        y_hat_plot_kwargs = {}
    y_hat_plot_kwargs.setdefault("fill_color", "orange")
    y_hat_plot_kwargs.setdefault("line_width", 0)

    if y_hat_fill_kwargs is None:
        y_hat_fill_kwargs = {}
    y_hat_fill_kwargs.setdefault("color", "orange")

    if y_model_plot_kwargs is None:
        y_model_plot_kwargs = {}
    y_model_plot_kwargs.setdefault("line_color", "black")
    y_model_plot_kwargs.setdefault("line_alpha", 0.5)
    y_model_plot_kwargs.setdefault("line_width", 0.5)

    if y_model_fill_kwargs is None:
        y_model_fill_kwargs = {}
    y_model_fill_kwargs.setdefault("color", "black")
    y_model_fill_kwargs.setdefault("alpha", 0.5)

    if y_model_mean_kwargs is None:
        y_model_mean_kwargs = {}
    y_model_mean_kwargs.setdefault("line_color", "yellow")
    y_model_mean_kwargs.setdefault("line_width", 2)

    for i, ax_i in enumerate((item for item in axes.flatten() if item is not None)):

        _, _, _, y_plotters = y[i]
        _, _, _, x_plotters = x[i]
        legend_it = []
        observed_legend = ax_i.circle(x_plotters, y_plotters, **y_kwargs)
        legend_it.append(("Observed", [observed_legend]))

        if y_hat is not None:
            _, _, _, y_hat_plotters = y_hat[i]
            if kind_pp == "samples":
                posterior_legend = []
                for j in range(num_samples):
                    if xjitter is True:
                        jitter_scale = x_plotters[1] - x_plotters[0]
                        scale_high = jitter_scale * 0.2
                        x_plotters_jitter = x_plotters + np.random.uniform(
                            low=-scale_high, high=scale_high, size=len(x_plotters)
                        )
                        posterior_circle = ax_i.circle(
                            x_plotters_jitter,
                            y_hat_plotters[..., j],
                            alpha=0.2,
                            **y_hat_plot_kwargs,
                        )
                    else:
                        posterior_circle = ax_i.circle(
                            x_plotters, y_hat_plotters[..., j], alpha=0.2, **y_hat_plot_kwargs
                        )
                    posterior_legend.append(posterior_circle)
                legend_it.append(("Posterior predictive samples", posterior_legend))

            else:
                plot_hdi(
                    x_plotters,
                    y_hat_plotters,
                    ax=ax_i,
                    backend="bokeh",
                    fill_kwargs=y_hat_fill_kwargs,
                    show=False,
                )

        if y_model is not None:
            _, _, _, y_model_plotters = y_model[i]
            if kind_model == "lines":

                model_legend = ax_i.multi_line(
                    [np.tile(x_plotters, (num_samples, 1))],
                    [np.transpose(y_model_plotters)],
                    **y_model_plot_kwargs,
                )
                legend_it.append(("Uncertainty in mean", [model_legend]))

                y_model_mean = np.mean(y_model_plotters, axis=1)
                x_plotters_edge = [min(x_plotters), max(x_plotters)]
                y_model_mean_edge = [min(y_model_mean), max(y_model_mean)]
                mean_legend = ax_i.line(x_plotters_edge, y_model_mean_edge, **y_model_mean_kwargs)
                legend_it.append(("Mean", [mean_legend]))

            else:
                plot_hdi(
                    x_plotters,
                    y_model_plotters,
                    fill_kwargs=y_model_fill_kwargs,
                    ax=ax_i,
                    backend="bokeh",
                    show=False,
                )

                y_model_mean = np.mean(y_model_plotters, axis=(0, 1))
                x_plotters_edge = [min(x_plotters), max(x_plotters)]
                y_model_mean_edge = [min(y_model_mean), max(y_model_mean)]
                mean_legend = ax_i.line(
                    x_plotters_edge,
                    y_model_mean_edge,
                    **y_model_mean_kwargs,
                )
                legend_it.append(("Mean", [mean_legend]))

        if legend:
            legend = Legend(
                items=legend_it,
                location="top_left",
                orientation="vertical",
            )
            ax_i.add_layout(legend)
            if textsize is not None:
                ax_i.legend.label_text_font_size = f"{textsize}pt"
            ax_i.legend.click_policy = "hide"

    show_layout(axes, show)
    return axes