def test_js_on_change_executes(self, bokeh_model_page):
        group = CheckboxGroup(labels=LABELS, css_classes=["foo"])
        group.js_on_click(CustomJS(code=RECORD("active", "cb_obj.active")))

        page = bokeh_model_page(group)

        el = page.driver.find_element_by_css_selector('.foo input[value="2"]')
        el.click()

        results = page.results
        assert results['active'] == [2]

        el = page.driver.find_element_by_css_selector('.foo input[value="0"]')
        el.click()

        results = page.results
        assert results['active'] == [0, 2]

        el = page.driver.find_element_by_css_selector('.foo input[value="2"]')
        el.click()

        results = page.results
        assert results['active'] == [0]

        assert page.has_no_console_errors()
    def test_js_on_change_executes(self,
                                   bokeh_model_page: BokehModelPage) -> None:
        group = CheckboxGroup(labels=LABELS)
        group.js_on_click(CustomJS(code=RECORD("active", "cb_obj.active")))

        page = bokeh_model_page(group)

        el = find_element_for(page.driver, group, 'input[value="2"]')
        el.click()

        results = page.results
        assert results['active'] == [2]

        el = find_element_for(page.driver, group, 'input[value="0"]')
        el.click()

        results = page.results
        assert results['active'] == [0, 2]

        el = find_element_for(page.driver, group, 'input[value="2"]')
        el.click()

        results = page.results
        assert results['active'] == [0]

        assert page.has_no_console_errors()
Example #3
0
def one_filter(plot, filter_col, filter_vals, filters_state, max_items):
    # Remove (FX) from column name; probaby temporary
    title = re.sub(r'\s*[(]F[0-9]+[)]\s*', '', filter_col)

    # Deduplicate and turn into name-value pairs, as required by MultiSelect.
    #options = [(opt,) * 2 for opt in sorted(filter_vals)]
    options = list(filter_vals)
    multi_select = CheckboxGroup(name=title, labels=options, active=[0, 1])

    # The state of each multi-select is stored in an intermediate
    # table; when a given multi-select is changed, the table is updated.
    # The change to the table triggers a second update, defined below
    # in `point_plot`. That second update modifies the map based on
    # the state of all multi-selects simultaneously. This way, individual
    # multi-select widgets can operate independently without knowing
    # anything about one another.
    multi_select.js_on_click(
        CustomJS(args=dict(filter_col=filter_col, filters_state=filters_state),
                 code="""
        console.log(this.active);
        let select_vals = this.active;
        let state_col = filters_state.data[filter_col];
        for (let i = 0; i < state_col.length; i++) {
            if (i < select_vals.length) {
                state_col[i] = select_vals[i];
            } else {
                state_col[i] = '';
            }
        }
        filters_state.properties.data.change.emit();
        """))
    return multi_select
    def trend_chart(self, target_stock: str):
        """Trend chart of the result using Bokeh."""

        result = self.__check_result(target_stock)

        tabs = []
        for i in result.keys():
            label_name = i
            tickers = result[i]
            cumprod = (self.daily_return[tickers] + 1).cumprod()
            source = ColumnDataSource(data=cumprod)

            p = figure(x_axis_type="datetime",
                       title="Trend Line",
                       plot_height=350,
                       plot_width=800)
            p.xgrid.grid_line_color = None
            p.ygrid.grid_line_alpha = 0.5
            p.xaxis.axis_label = 'Time'
            p.yaxis.axis_label = 'Total Return'
            lines = []
            for i in range(len(cumprod.columns)):
                lines.append(
                    p.line("Date",
                           cumprod.columns[i],
                           source=source,
                           line_width=2,
                           line_alpha=0.8,
                           line_color=Spectral10[i % 10],
                           legend_label=cumprod.columns[i],
                           muted_color=Spectral10[i % 10],
                           muted_alpha=0.1))

            p.legend.location = "top_left"
            p.legend.click_policy = "mute"

            LABELS = list(cumprod.columns)
            checkbox_group = CheckboxGroup(labels=LABELS)
            checkbox_group.active = list(range(len(LABELS)))

            code = """ for (var i = 0; i < lines.length; i++) {
                            lines[i].visible = false;
                            if (cb_obj.active.includes(i)){lines[i].visible = true;}
                        }
                   """
            callback = CustomJS(code=code, args={'lines': lines})
            checkbox_group.js_on_click(callback)

            layout = row(p, checkbox_group)
            tabs.append(Panel(child=layout, title=label_name))

        tabs = Tabs(tabs=tabs)
        show(tabs)
Example #5
0
def one_filter(plot, filter_col, filter_vals, filters_state, max_items):
    # Remove (FX) from column name; probaby temporary
    title = re.sub(r'\s*[(]F[0-9]+[)]\s*', '', filter_col)
    title = title.replace(" ", "")

    options = list(filter_vals)
    multi_select = CheckboxGroup(
        name=title,
        labels=options,
        css_classes=[title],
        default_size=150,
        height_policy='min',
        visible=True
    )

    # The state of each multi-select is stored in an intermediate
    # table; when a given multi-select is changed, the table is updated.
    # The change to the table triggers a second update, defined below
    # in `point_plot`. That second update modifies the map based on
    # the state of all multi-selects simultaneously. This way, individual
    # multi-select widgets can operate independently without knowing
    # anything about one another.
    multi_select.js_on_click(CustomJS(
        args=dict(filter_col=filter_col,
                  filters_state=filters_state),
        code="""

        // Turn the list of active indices into a list of labels.
        let select_vals = this.active.map((act) => this.labels[act]);

        let state_col = filters_state.data[filter_col];

        for (let i = 0; i < state_col.length; i++) {
            if (i < select_vals.length) {
                state_col[i] = select_vals[i];
            } else {
                state_col[i] = '';
            }
        }
        filters_state.properties.data.change.emit();
        """)
    )
    return multi_select
    def trend_chart(self,
                    policy_names: list,
                    compounding: bool = False,
                    height: int = 350,
                    width: int = 800):
        """Trend chart of the result using Bokeh.
        
        Parameters
        ----------
        policy_names : list
            List of selected policy names
            
        compounding : bool, default False
            Whether returns are reinvested back into the account.
            
        height : int
            Height of the plot
            
        width : int
            Width of the plot
            
        Returns
        -------
        None
        """

        selected_rst_dict = {key: self.rst_dict[key] for key in policy_names}
        data = pd.DataFrame(selected_rst_dict)
        data["strategy_return"] = self.strategy_return

        if compounding:
            cum = (data + 1).cumprod()
        else:
            cum = data.cumsum() + 1

        if compounding:
            mdd = (cum / cum.cummax() - 1)
        else:
            mdd = cum - cum.cummax()

        source = ColumnDataSource(data=cum)
        source_mdd = ColumnDataSource(data=mdd)

        p = figure(x_axis_type="datetime",
                   title="Trend Line",
                   plot_height=height,
                   plot_width=width)
        p.xgrid.grid_line_color = None
        p.ygrid.grid_line_alpha = 0.5
        p.xaxis.axis_label = 'Time'
        p.yaxis.axis_label = 'Total Return'

        p_mdd = figure(x_axis_type="datetime",
                       title="Max Drawdown",
                       plot_height=height,
                       plot_width=width,
                       x_range=p.x_range)
        p_mdd.xgrid.grid_line_color = None
        p_mdd.ygrid.grid_line_alpha = 0.5
        p_mdd.xaxis.axis_label = 'Time'
        p_mdd.yaxis.axis_label = 'MDD'

        lines = []
        for i in range(len(cum.columns)):
            lines.append(
                p.line("Date",
                       cum.columns[i],
                       source=source,
                       line_width=2,
                       line_alpha=0.8,
                       line_color=Spectral10[i % 10],
                       legend_label=cum.columns[i],
                       muted_color=Spectral10[i % 10],
                       muted_alpha=0.1))

        lines_mdd = []
        for i in range(len(mdd.columns)):
            lines_mdd.append(
                p_mdd.line("Date",
                           mdd.columns[i],
                           source=source_mdd,
                           line_width=2,
                           line_alpha=0.8,
                           line_color=Spectral10[i % 10],
                           legend_label=mdd.columns[i],
                           muted_color=Spectral10[i % 10],
                           muted_alpha=0.1))

        p.legend.location = "top_left"
        p.legend.click_policy = "mute"

        p_mdd.legend.location = "bottom_left"
        p_mdd.legend.click_policy = "mute"

        LABELS = list(cum.columns)
        checkbox_group = CheckboxGroup(labels=LABELS)
        checkbox_group.active = list(range(len(LABELS)))

        code = """ for (var i = 0; i < lines.length; i++) {
                        lines[i].visible = false;
                        if (cb_obj.active.includes(i)){lines[i].visible = true;}
                    }
               """
        callback = CustomJS(code=code, args={'lines': lines})
        checkbox_group.js_on_click(callback)

        callback = CustomJS(code=code, args={'lines': lines_mdd})
        checkbox_group.js_on_click(callback)

        grid = gridplot([[p, checkbox_group], [p_mdd]])
        show(grid)
def create_water_tanks_iplot(data_df, logger):

    columns = ['L_T' + str(i) for i in range(1, 8)]
    max_y = max([data_df[col].max() for col in columns])

    source = ColumnDataSource({
        'x_t1': data_df.index,
        'y_t1': data_df['L_T1'],
        'x_t2': data_df.index,
        'y_t2': data_df['L_T2'],
        'x_t3': data_df.index,
        'y_t3': data_df['L_T3'],
        'x_t4': data_df.index,
        'y_t4': data_df['L_T4'],
        'x_t5': data_df.index,
        'y_t5': data_df['L_T5'],
        'x_t6': data_df.index,
        'y_t6': data_df['L_T6'],
        'x_t7': data_df.index,
        'y_t7': data_df['L_T7'],
    })

    p = figure(plot_width=1000,
               plot_height=750,
               title="Water tanks",
               tools="pan,wheel_zoom,save,reset",
               x_axis_type="datetime",
               y_range=[0, max_y + 2.5],
               x_axis_label="Time",
               y_axis_label="Water level (m)")
    p.xaxis.axis_label_text_font_size = "18pt"
    p.yaxis.axis_label_text_font_size = "18pt"

    p_t1 = p.line('x_t1',
                  'y_t1',
                  source=source,
                  color='red',
                  alpha=0.9,
                  line_width=2,
                  legend="Tank1")
    p_t2 = p.line('x_t2',
                  'y_t2',
                  source=source,
                  color='gold',
                  alpha=0.9,
                  line_width=2,
                  legend="Tank2")
    p_t3 = p.line('x_t3',
                  'y_t3',
                  source=source,
                  color='blue',
                  alpha=0.9,
                  line_width=2,
                  legend="Tank3")
    p_t4 = p.line('x_t4',
                  'y_t4',
                  source=source,
                  color='black',
                  alpha=0.9,
                  line_width=2,
                  legend="Tank4")
    p_t5 = p.line('x_t5',
                  'y_t5',
                  source=source,
                  color='mediumspringgreen',
                  alpha=0.9,
                  line_width=2,
                  legend="Tank5")
    p_t6 = p.line('x_t6',
                  'y_t6',
                  source=source,
                  color='salmon',
                  alpha=0.9,
                  line_width=2,
                  legend="Tank6")
    p_t7 = p.line('x_t7',
                  'y_t7',
                  source=source,
                  color='navy',
                  alpha=0.9,
                  line_width=2,
                  legend="Tank7")

    p.legend.location = "top_left"

    tanks = ['Tank ' + str(i) for i in range(1, 8)]
    checkboxes = CheckboxGroup(labels=tanks, active=[i for i in range(7)])
    callback = CustomJS(args=dict(p_t1=p_t1,
                                  p_t2=p_t2,
                                  p_t3=p_t3,
                                  p_t4=p_t4,
                                  p_t5=p_t5,
                                  p_t6=p_t6,
                                  p_t7=p_t7),
                        code="""
    f = cb_obj.active;
    p_t1.visible = false;
    p_t2.visible = false;
    p_t3.visible = false;
    p_t4.visible = false;
    p_t5.visible = false;
    p_t6.visible = false;
    p_t7.visible = false;
    if (f.includes(0)) { p_t1.visible = true; }
    if (f.includes(1)) { p_t2.visible = true; }
    if (f.includes(2)) { p_t3.visible = true; }
    if (f.includes(3)) { p_t4.visible = true; }
    if (f.includes(4)) { p_t5.visible = true; }
    if (f.includes(5)) { p_t6.visible = true; }
    if (f.includes(6)) { p_t7.visible = true; }
    """)
    checkboxes.js_on_click(callback)

    output_file(logger.get_output_file("tanks.html"))
    save(row(checkboxes, p))
def trend_chart(returns_series,
                compounding: bool = False,
                height: int = 350,
                width: int = 800):
    """Trend chart of the result using Bokeh.
    
    Parameters
    ----------
    returns_series : Pandas Series
        Series contains returns.
    
    compounding : bool, default False
        Whether returns are reinvested back into the account.
        
    height : int
        Height of the plot
        
    width : int
        Width of the plot
        
    Returns
    -------
    None
    """

    data = returns_series

    if compounding:
        cum = (data + 1).cumprod()
    else:
        cum = data.cumsum() + 1

    cum = pd.DataFrame(cum)
    source = ColumnDataSource(data=cum)

    p = figure(x_axis_type="datetime",
               title="Trend Line",
               plot_height=height,
               plot_width=width)
    p.xgrid.grid_line_color = None
    p.ygrid.grid_line_alpha = 0.5
    p.xaxis.axis_label = 'Time'
    p.yaxis.axis_label = 'Total Return'
    lines = []
    for i in range(len(cum.columns)):
        lines.append(
            p.line("Date",
                   cum.columns[i],
                   source=source,
                   line_width=2,
                   line_alpha=0.8,
                   line_color=Spectral10[i % 10],
                   legend_label=cum.columns[i],
                   muted_color=Spectral10[i % 10],
                   muted_alpha=0.1))

    p.legend.location = "top_left"
    p.legend.click_policy = "mute"

    LABELS = list(cum.columns)
    checkbox_group = CheckboxGroup(labels=LABELS)
    checkbox_group.active = list(range(len(LABELS)))

    code = """ for (var i = 0; i < lines.length; i++) {
                    lines[i].visible = false;
                    if (cb_obj.active.includes(i)){lines[i].visible = true;}
                }
           """
    callback = CustomJS(code=code, args={'lines': lines})
    checkbox_group.js_on_click(callback)

    layout = row(p, checkbox_group)
    show(layout)