bokeh.models.LinearAxis

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

27 Examples 7

3 Source : test_plots.py
with MIT License
from rthorst

def test_plot_add_layout_adds_axis_to_renderers_and_side_renderers():
    plot = figure()
    axis = LinearAxis()
    plot.add_layout(axis, 'left')
    assert axis in plot.left


def test_sizing_mode_property_is_fixed_by_default():

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

def std_distance_time_plot(nx, ny, source, x_range=None, output_backend=DEFAULT_BACKEND):
    # avoid range errors
    if len(source[N.ACTIVE_TIME_S].dropna())   <   2:
        return None
    groups = [group for statistic, group in related_statistics(source, N.ACTIVE_TIME)]
    if not groups:
        # original monochrome plot
        return multi_dot_plot(nx, ny, N.TIME, [N.ACTIVE_TIME_H, N.ACTIVE_DISTANCE_KM], source,
                              ['black', 'grey'], alphas=[1, 0.5], x_range=x_range, rescale=True)
    times = [f'{N.ACTIVE_TIME}:{group}' for group in groups]
    distances = [f'{N.ACTIVE_DISTANCE}:{group}' for group in groups]
    time_y_range = make_range(source[N.ACTIVE_TIME_H])
    distance_y_range = make_range(source[N.ACTIVE_DISTANCE_KM])
    colours = list(evenly_spaced_hues(len(groups)))
    tooltip_names = [N.ACTIVE_TIME_H, N.ACTIVE_DISTANCE_KM, N.ACTIVITY_GROUP, N.LOCAL_TIME]
    tooltip_names += [name for name in like(N._delta(N.FITNESS_ANY), source.columns) if ':' not in name]
    tooltip_names += [name for name in like(N._delta(N.FATIGUE_ANY), source.columns) if ':' not in name]
    tools = [PanTool(dimensions='width'),
             ZoomInTool(dimensions='width'), ZoomOutTool(dimensions='width'),
             ResetTool(),
             HoverTool(tooltips=[tooltip(name) for name in tooltip_names], names=['with_hover'])]
    f = figure(output_backend=output_backend, plot_width=nx, plot_height=ny, x_axis_type='datetime', tools=tools)
    f.yaxis.axis_label = f'lines - {N.ACTIVE_TIME_H}'
    f.y_range = time_y_range
    f.extra_y_ranges = {N.ACTIVE_DISTANCE: distance_y_range}
    f.add_layout(LinearAxis(y_range_name=N.ACTIVE_DISTANCE, axis_label=f'dots - {N.ACTIVE_DISTANCE_KM}'), 'right')
    plotter = comb_plotter()
    for time, colour, group in zip(times, colours, groups):
        time_h = N._slash(time, U.H)
        source[time_h] = source[time] / 3600
        source[N.ACTIVITY_GROUP] = group
        plotter(f, x=N.TIME, y=time_h, source=source, color=colour, alpha=1)
    plotter = dot_plotter()
    for distance, colour, group in zip(distances, colours, groups):
        distance_km = N._slash(distance, U.KM)
        source[distance_km] = source[distance]
        source[N.ACTIVITY_GROUP] = group
        plotter(f, x=N.TIME, y=distance_km, source=source, color=colour, alpha=1, name='with_hover',
                y_range_name=N.ACTIVE_DISTANCE)
    f.xaxis.axis_label = N.TIME
    f.toolbar.logo = None
    if ny  <  300: f.toolbar_location = None
    if x_range: f.x_range = x_range
    return f

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

def multi_plot(nx, ny, x, ys, source, colors, alphas=None, x_range=None, y_label=None, rescale=False,
               plotters=None, output_backend=DEFAULT_BACKEND):
    if not ys or not present(source, x, *ys): return None
    tools = [PanTool(dimensions='width'),
             ZoomInTool(dimensions='width'), ZoomOutTool(dimensions='width'),
             ResetTool(),
             HoverTool(tooltips=[tooltip(x) for x in ys + [N.LOCAL_TIME]], names=['with_hover'])]
    f = figure(output_backend=output_backend, plot_width=nx, plot_height=ny,
               x_axis_type='datetime' if N.TIME in x else 'linear', tools=tools)
    if y_label:
        f.yaxis.axis_label = y_label
    elif rescale:
        f.yaxis.axis_label = ys[0]
    else:
        f.yaxis.axis_label = ', '.join(ys)
    if rescale: f.extra_y_ranges = {}
    if alphas is None: alphas = [1 for _ in ys]
    while len(plotters)   <   len(ys): plotters += plotters
    for y, color, alpha, plotter in zip(ys, colors, alphas, plotters):
        y_range = make_range(source[y])
        if rescale and y != ys[0]:
            f.extra_y_ranges[y] = y_range
            f.add_layout(LinearAxis(y_range_name=y, axis_label=y), 'right')
            plotter(f, x=x, y=y, source=source, color=color, alpha=alpha, y_range_name=y, name='with_hover')
        else:
            f.y_range = y_range
            plotter(f, x=x, y=y, source=source, color=color, alpha=alpha, name='with_hover')
    f.xaxis.axis_label = x
    f.toolbar.logo = None
    if ny  <  300: f.toolbar_location = None
    if x_range: f.x_range = x_range
    return f


def add_multi_line_at_index(f, x, ys, source, colors, alphas=None, dash='dotted', index=-1):

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

def plot_growth(p,t,time_data):

    plot_var(p,t,time_data, 'X', color='black')
    p.yaxis.axis_label = "Cell concentration $[g.L^{-1}]$"
    p.y_range.start = 0.9 * time_data.loc['X'].min()
    p.y_range.end =  1.09 * time_data.loc['X'].max()

    # Setting the second y axis range name and range
    p.extra_y_ranges = {"mu": Range1d()}

    # Adding the second axis to the plot.
    p.add_layout(LinearAxis(y_range_name="mu",
                            axis_label='growth rate $[h^{-1}]$'), 'right')

    plot_var(p,t,time_data, 'mu', color='gray', y_range_name='mu')

    return p


def plot_dynamics(model, time_data):

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

def make_growth_plot(model,time_data):
    t = time_data.loc['t']
    y1 = time_data.loc['X']
    y2 = time_data.loc['mu']

    p = bp.figure(width=1000)
    p.title.text = 'Growth, Cell concentration over time'
    p.line(t,y1, color='black', line_width=LINE_WIDTH)

    p.y_range.start = -0.05 * y1.min()
    p.y_range.end   =  1.05 * y1.max()

    # Setting the second y axis range name and range
    p.extra_y_ranges = {"mu": Range1d(start=-0.05*y2.min(), end = 1.05*y2.max())}

    # Adding the second axis to the plot.
    p.add_layout(LinearAxis(y_range_name="mu",
                            axis_label='growth rate $[h^{-1}]$'), 'right')

    p.line(t,y2, color='grey',  line_width=LINE_WIDTH,
           line_dash = 'dashed', y_range_name='mu')

    p.xaxis.major_label_text_font_size = AXIS_FONT_SIZE
    p.yaxis.major_label_text_font_size = AXIS_FONT_SIZE
    # p.legend.label_text_font_size = LEGEND_FONT_SIZE

    return p

def get_y(the_var, time_data):

0 Source : viz.py
with MIT License
from fancompute

def _plot_twinx_bokeh(plot, _):
    """Hook to plot data on a secondary (twin) axis on a Holoviews Plot with Bokeh backend.

    Args:
        plot: Holoviews plot object to hook for twinx

    See Also:
        The code was copied from a comment in https://github.com/holoviz/holoviews/issues/396.
        - http://holoviews.org/user_guide/Customizing_Plots.html#plot-hooks
        - https://docs.bokeh.org/en/latest/docs/user_guide/plotting.html#twin-axes

    """
    fig: Figure = plot.state
    glyph_first: GlyphRenderer = fig.renderers[0]  # will be the original plot
    glyph_last: GlyphRenderer = fig.renderers[-1]  # will be the new plot
    right_axis_name = "twiny"
    # Create both axes if right axis does not exist
    if right_axis_name not in fig.extra_y_ranges.keys():
        # Recreate primary axis (left)
        y_first_name = glyph_first.glyph.y
        y_first_min = glyph_first.data_source.data[y_first_name].min()
        y_first_max = glyph_first.data_source.data[y_first_name].max()
        y_first_offset = (y_first_max - y_first_min) * 0.1
        fig.y_range = Range1d(
            start=y_first_min - y_first_offset,
            end=y_first_max + y_first_offset
        )
        fig.y_range.name = glyph_first.y_range_name
        # Create secondary axis (right)
        y_last_name = glyph_last.glyph.y
        y_last_min = glyph_last.data_source.data[y_last_name].min()
        y_last_max = glyph_last.data_source.data[y_last_name].max()
        y_last_offset = (y_last_max - y_last_min) * 0.1
        fig.extra_y_ranges = {right_axis_name: Range1d(
            start=y_last_min - y_last_offset,
            end=y_last_max + y_last_offset
        )}
        fig.add_layout(LinearAxis(y_range_name=right_axis_name, axis_label=glyph_last.glyph.y), "right")
    # Set right axis for the last glyph added to the figure
    glyph_last.y_range_name = right_axis_name


def get_extent_2d(shape, spacing: Optional[float] = None):

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

def getSimpleFigure(df, vars, tools, extra_y=None, extra_y_vars=None, x_range=None):
    WIDTH = 800
    TOOLS = "crosshair,pan,reset,save,wheel_zoom"

    # create a new plot with a title and axis labels
    p = figure(plot_height=400, plot_width=WIDTH, tools=TOOLS,
               x_range=x_range, x_axis_label='Dist [m]')

    y_range_name = lambda x: None
    if extra_y:
        # Setting the second y axis range name and range
        p.extra_y_ranges = extra_y

        def y_range_name(var):
            # create mapping of variable to axis
            if extra_y_vars is None:
                vars = list(zip(extra_y.keys(), extra_y.keys()))
            else:
                vars = [(var, ax) for ax, sublist in extra_y_vars.items() for var in sublist]

            # check if a variable in the vars list matches the argument
            k = [k for k in vars if k[0] in var]
            if len(k)==1:
                return k[0][1]
            return 'default'

        for name in extra_y:
            # Adding the second axis to the plot.
            p.add_layout(LinearAxis(
                y_range_name=name,
                axis_label=name), 'right')


    colors = itertools.cycle(palette)
    ds = ColumnDataSource(df)
    for i in vars:
        p.line(x='dist_lap', y=i, source=ds,
               legend_label='m = {}'.format(i),
               line_width=2, line_alpha=0.6,
               line_color=next(colors),
               y_range_name=y_range_name(i)
               )

    p.toolbar_location="above"
    p.add_tools(createHoverTool(tools))

    return p


def getSuspFigure(df):

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

def getTrackMap(target, reference=None, mode='speed', view='lapsdelta'):
    if reference is None:
        df_, df_r = target, None
    else:
        df_, df_r = acctelemetry.lapdelta(reference, target)

    ds = ColumnDataSource(df_)
    p0 = figure(plot_height=400, plot_width=800,
                tools="crosshair,pan,reset,save,wheel_zoom")

    colors = itertools.cycle(palette)
    col0, col1 = next(colors), next(colors)

    # create the velo vs dist plot
    r0 = p0.line(x='dist_lap', y='speedkmh', source=ds, color=col0, line_width=2)

    # overwrite the (non)selection glyphs with the base line style
    # the style for the hover will be set below
    nonselected_ = Line(line_alpha=1, line_color=col0, line_width=2)
    r0.selection_glyph = nonselected_
    r0.nonselection_glyph = nonselected_

    if reference is not None:
        # create the dt vs dist plot with extra y axis, set the (non)selection glyphs
        lim = max(df_.dt.abs())
        lim += lim*.2
        p0.extra_y_ranges = {"dt": Range1d(start=-lim, end=lim)}
        p0.add_layout(LinearAxis(
            y_range_name='dt',
            axis_label='dt [s]'), 'right')
        r1 = p0.line(x='dist_lap', y='dt', source=ds, y_range_name='dt', color=col1, line_width=2)
        r1.selection_glyph = Line(line_alpha=1, line_color='red', line_width=5)
        r1.nonselection_glyph = Line(line_alpha=1, line_color=col1, line_width=2)

        # create reference velo vs dist plot
        p0.line(df_r.dist_lap, df_r.speedkmh, color=next(colors), line_width=2)

    # create an invisible renderer for velo vs dist
    # this is used to trigger the hover, thus the size is large
    c0 = p0.circle(x='dist_lap', y='speedkmh', source=ds, size=10, fill_alpha=0.0, alpha=0.0)
    c0.selection_glyph = Circle(fill_color='red', fill_alpha=1., line_color=None)
    c0.nonselection_glyph = Circle(fill_alpha=0, line_color=None)

    # create figure for track map
    p1 = figure(plot_height=400, plot_width=800, tools="crosshair,pan,reset,save,wheel_zoom")

    # create map of the track
    c1 = getLapFigure(p1, df_, ds, mode, hasref=(reference is not None))

    # add some lap tangents to guide the eye when comparing map and refmap
    if reference is not None and mode not in ['absolut', 'gainloss']:
        x0 = df_.x.values
        y0 = df_.y.values
        h = df_.heading.values
        x1 = x0 + 30*np.cos(h+np.pi/2)
        y1 = y0 + 30*np.sin(h+np.pi/2)
        p1.segment(x0=x0, y0=y0, x1=x1, y1=y1, color="#F4A582", line_width=1)

        # calculate points for the reference map drawn 'outside' of the other track map
        getLapFigure(p1, df_, ds , mode, ref=True)

    # Toooltips that show some information for each point, triggered via slider.onchange JS
    tools = ['time','dist','speedkmh']
    if reference is not None:
        tools.append('speedkmh_r')
        if mode not in ['absolut', 'gainloss', 'pedals', 'speed']:
            tools.extend([mode, '%s_r'%mode])
        elif mode in ['pedals']:
            tools.extend(['throttle', 'throttle_r', 'brake', 'brake_r'])
        tools.append('dt')
    elif mode == 'pedals':
        tools.extend(['throttle', 'brake'])
    elif mode != 'speed':
        tools.append(mode)

    hover0 = createHoverTool(tools)
    # a small hack to show only one tooltip (hover selects multiple points)
    # TODO: doesn't work anymore with recent bokeh
    # hover0.tooltips[-1] = (hover0.tooltips[-1][0], hover0.tooltips[-1][1]+"""
    #       <  style>
    #         .bk-tooltip>div:not(:first-child) {display:none;}
    #      < /style>""")
    hover0.renderers = [r0]
    hover0.mode = 'vline'
    hover0.line_policy='interp'

    # selection change via button and slider. Tooltips 'hover0' will be rendered in 'p0' using rederer 'r0'
    slider = getLapSlider(ds, p0, r0, hover0, view=view)
    btns = getLapControls(ds, slider)

    # Hovertools, that emit a selection change by modifying the slider value
    callback = CustomJS(args=dict(slider=slider), code=
    """
    let val = cb_data['index'].indices[0]
    if (val!=0 && !isNaN(val))
        slider.value = cb_data['index'].indices[0];
    """)
    p0.add_tools(HoverTool(tooltips=None, renderers=[c0],
                           callback=callback,
                           line_policy='interp', mode='vline'))
    p1.add_tools(HoverTool(tooltips=None, renderers=[c1],
                           callback=callback,
                           line_policy='interp', mode='mouse', point_policy='snap_to_data'))

    p0.add_tools(hover0)
    # p1.add_tools(hover1)

    return column(btns, slider, p0, p1, sizing_mode='scale_width')




def getTrackMapPanel(df):

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

    def plot_volume(self, data, alpha=1.0, extra_axis=False):
        '''
        Plot method for volume
        extra_axis: displays a second axis (for overlay on data plotting)
        '''
        source_id = get_source_id(data)
        self.set_cds_col(source_id + 'volume')
        # create color columns
        volup = convert_color(self._scheme.volup)
        voldown = convert_color(self._scheme.voldown)
        self.set_cds_col((
            source_id + 'colors_volume',
            source_id + 'open',
            source_id + 'close',
            partial(cds_op_color,
                    color_up=volup,
                    color_down=voldown)))

        # prepare bar kwargs
        kwargs = {
            'x': 'index',
            'width': self._bar_width,
            'top': source_id + 'volume',
            'bottom': 0,
            'fill_color': source_id + 'colors_volume',
            'line_color': source_id + 'colors_volume',
            'fill_alpha': alpha,
            'line_alpha': alpha,
            'name': 'Volume',
            'legend_label': 'Volume'}

        # set axis
        ax_formatter = NumeralTickFormatter(format=self._scheme.number_format)
        if extra_axis:
            source_data_axis = 'axvol'
            # use colorup
            ax_color = convert_color(self._scheme.volup)
            # use only one additional axis to prevent multiple axis being added
            # to a single figure
            ax = self.figure.select_one({'name': source_data_axis})
            if ax is None:
                # create new axis if not already available
                self.figure.extra_y_ranges = {source_data_axis: DataRange1d(
                    range_padding=1.0 / self._scheme.volscaling,
                    start=0)}
                ax = LinearAxis(
                    name=source_data_axis,
                    y_range_name=source_data_axis,
                    formatter=ax_formatter,
                    axis_label_text_color=ax_color,
                    axis_line_color=ax_color,
                    major_label_text_color=ax_color,
                    major_tick_line_color=ax_color,
                    minor_tick_line_color=ax_color)
                self.figure.add_layout(ax, self._scheme.vol_axis_location)
            kwargs['y_range_name'] = source_data_axis
        else:
            self.figure.yaxis.formatter = ax_formatter

        # append renderer
        self._figure_append_renderer(self.figure.vbar, **kwargs)
        # set hover label
        self._fp.hover.add_hovertip(
            'Volume',
            f'@{source_id}volume{{({self._scheme.number_format})}}',
            data)

    def plot_observer(self, obj):

0 Source : exercise.py
with MIT License
from karlicoss

def _plot_manual_exercise(df):
    pallete = palletes[max(palletes)] # get last

    # todo one axis for count, one for seconds? although not really gonna work for
    # maybe on separate plots?
    has_err = df['error'].notna()
    errs = df[has_err].copy()
    errs['reps'] = 1 # meh
    some_dt = df['dt'].dropna().iloc[-1]
    errs['dt'].fillna(some_dt, inplace=True)
    # not sure? some errs have reps.. errs['reps'].fillna(-5) # meh
    df  = df[~has_err]
    # TODO would be nice to reuse stuff to display errors as a table

    # FIXME handle none carefully here, otherwise they aren't displayed
    plots = []
    # todo hmm, reuse group hints somehow? not sure..

    # TODO helper groupby to check for None (to make sure they are handled)
    groups = list(df.groupby('kind'))
    # sort by the most recent
    groups = list(sorted(groups, key=lambda kind_d: max(unlocalize(kind_d[1]['dt'])), reverse=True))

    kinds = [kind for kind, _ in groups]
    # make colors stable
    colors = {kind: c for kind, c in zip(kinds, cycle(pallete))}
    colors['errors'] = 'red'

    x_range = None
    for k, edf in chain(
            [('errors', errs)],
            groups,
    ):
        color = colors[k]
        # TODO add some x jitter to declutter?
        # need to preserve the order though? I guess need to group
        p = date_figure(df, height=150, x_range=x_range)
        p.scatter(x='dt', y='reps'  , source=CDS(edf), legend_label='reps'  , color=color)

        from bokeh.models import LinearAxis, Range1d
        maxy = np.nanmax(edf['volume'] * 1.1) # TODO meh
        if not np.isnan(maxy): # I guess doesn't have volume?
            p.extra_y_ranges = {'volume': Range1d(start=0.0, end=maxy)}
            # add the second axis to the plot.
            p.add_layout(LinearAxis(y_range_name='volume'), 'right')
            p.scatter(x='dt', y='volume', source=CDS(edf), legend_label='volume', color='black', size=2, y_range_name='volume')

        p.title.text = k

        p.y_range.start = 0

        if x_range is None:
            x_range = p.x_range
        plots.append(p)
        # TODO not sure if I want sliding averages?
    return column(plots)


def _plot_strength_volume(df) -> RollingResult:

0 Source : sleep.py
with MIT License
from karlicoss

def _plot_sleep(df):
    df = _sleep_df(df)

    # TODO https://github.com/bokeh/bokeh/blob/master/examples/app/sliders.py

    # todo naming: plot vs figure vs graph?
    r = rolling(x='date', y='avg_hr', df=df, color='blue', legend_label='HR')
    [g, g7, g30] = r
    g7 .glyph.line_width = 2
    g30.glyph.line_color = 'lightblue'
    g30.glyph.line_width = 2
    p = r.figure

    p.extra_y_ranges = {'resp': Range1d(start=10, end=25)}
    # Add the second axis to the plot.
    p.add_layout(LinearAxis(y_range_name='resp'), 'right')
    rolling(
        df=df,
        x='date', y='respiratory_rate_avg',
        color='orange',
        legend_label='Respiration',
        avgs=['7D'],
        y_range_name='resp',
        context=r,
    )
    # TODO hmm, it appends error twice? not sure about it...
    add_daysoff(p)
    return r

# todo always set output_file("xx.html")? so the latest html is always dumped?


# todo what's the benefit of having date index at all?
# todo think of better naming
def plot_sleep_hrv(df):

0 Source : whole_productivity_per_date.py
with MIT License
from kurusugawa-computer

    def plot(self, output_file: Path):
        """
        全体の生産量や生産性をプロットする


        Args:
            df:

        Returns:

        """

        def add_velocity_columns(df: pandas.DataFrame):
            for denominator in ["input_data_count", "annotation_count"]:
                for category in [
                    "actual",
                    "monitored",
                    "monitored_annotation",
                    "monitored_inspection",
                    "monitored_acceptance",
                    "unmonitored",
                ]:
                    df[f"{category}_worktime_minute/{denominator}"] = (
                        df[f"{category}_worktime_hour"] * 60 / df[denominator]
                    )
                    df[f"{category}_worktime_minute/{denominator}{WEEKLY_MOVING_AVERAGE_COLUMN_SUFFIX}"] = (
                        get_weekly_sum(df[f"{category}_worktime_hour"]) * 60 / get_weekly_sum(df[denominator])
                    )

            df[f"actual_worktime_hour/task_count{WEEKLY_MOVING_AVERAGE_COLUMN_SUFFIX}"] = get_weekly_sum(
                df["actual_worktime_hour"]
            ) / get_weekly_sum(df["task_count"])
            df[f"monitored_worktime_hour/task_count{WEEKLY_MOVING_AVERAGE_COLUMN_SUFFIX}"] = get_weekly_sum(
                df["monitored_worktime_hour"]
            ) / get_weekly_sum(df["task_count"])

            for column in ["task_count", "input_data_count", "actual_worktime_hour", "monitored_worktime_hour"]:
                df[f"{column}{WEEKLY_MOVING_AVERAGE_COLUMN_SUFFIX}"] = get_weekly_moving_average(df[column])

        def create_figure(title: str, y_axis_label: str) -> bokeh.plotting.Figure:
            return figure(
                plot_width=1200,
                plot_height=600,
                title=title,
                x_axis_label="日",
                x_axis_type="datetime",
                y_axis_label=y_axis_label,
            )

        def plot_and_moving_average(fig, y_column_name: str, legend_name: str, source, color, **kwargs):
            x_column_name = "dt_date"

            # 値をプロット
            plot_line_and_circle(
                fig,
                x_column_name=x_column_name,
                y_column_name=y_column_name,
                source=source,
                color=color,
                legend_label=legend_name,
                **kwargs,
            )

            # 移動平均をプロット
            plot_moving_average(
                fig,
                x_column_name=x_column_name,
                y_column_name=f"{y_column_name}{WEEKLY_MOVING_AVERAGE_COLUMN_SUFFIX}",
                source=source,
                color=color,
                legend_label=f"{legend_name}の1週間移動平均",
                **kwargs,
            )

        def create_task_figure():
            y_range_name = "worktime_axis"
            fig_task = create_figure(title="日ごとのタスク数と作業時間", y_axis_label="タスク数")
            fig_task.add_layout(
                LinearAxis(
                    y_range_name=y_range_name,
                    axis_label="作業時間[hour]",
                ),
                "right",
            )
            y_overlimit = 0.05
            fig_task.extra_y_ranges = {
                y_range_name: DataRange1d(
                    end=max(df["actual_worktime_hour"].max(), df["monitored_worktime_hour"].max()) * (1 + y_overlimit)
                )
            }
            plot_and_moving_average(
                fig=fig_task,
                y_column_name="task_count",
                legend_name="タスク数",
                source=source,
                color=get_color_from_small_palette(0),
            )
            plot_and_moving_average(
                fig=fig_task,
                y_column_name="actual_worktime_hour",
                legend_name="実績作業時間",
                source=source,
                color=get_color_from_small_palette(1),
                y_range_name=y_range_name,
            )
            plot_and_moving_average(
                fig=fig_task,
                y_column_name="monitored_worktime_hour",
                legend_name="計測作業時間",
                source=source,
                color=get_color_from_small_palette(2),
                y_range_name=y_range_name,
            )
            return fig_task

        def create_input_data_figure():
            y_range_name = "worktime_axis"
            fig_input_data = create_figure(title="日ごとの入力データ数と作業時間", y_axis_label="入力データ数")
            fig_input_data.add_layout(
                LinearAxis(
                    y_range_name=y_range_name,
                    axis_label="作業時間[hour]",
                ),
                "right",
            )
            y_overlimit = 0.05
            fig_input_data.extra_y_ranges = {
                y_range_name: DataRange1d(
                    end=max(df["actual_worktime_hour"].max(), df["monitored_worktime_hour"].max()) * (1 + y_overlimit)
                )
            }
            plot_and_moving_average(
                fig=fig_input_data,
                y_column_name="input_data_count",
                legend_name="入力データ数",
                source=source,
                color=get_color_from_small_palette(0),
            )
            plot_and_moving_average(
                fig=fig_input_data,
                y_column_name="actual_worktime_hour",
                legend_name="実績作業時間",
                source=source,
                color=get_color_from_small_palette(1),
                y_range_name=y_range_name,
            )
            plot_and_moving_average(
                fig=fig_input_data,
                y_column_name="monitored_worktime_hour",
                legend_name="計測作業時間",
                source=source,
                color=get_color_from_small_palette(2),
                y_range_name=y_range_name,
            )
            return fig_input_data

        if not self._validate_df_for_output(output_file):
            return

        df = self.df.copy()
        df["dt_date"] = df["date"].map(lambda e: parse(e).date())

        add_velocity_columns(df)

        logger.debug(f"{output_file} を出力します。")

        phase_prefix = [
            ("actual_worktime", "実績作業時間"),
            ("monitored_worktime", "計測作業時間"),
            ("monitored_annotation_worktime", "計測作業時間(教師付)"),
            ("monitored_inspection_worktime", "計測作業時間(検査)"),
            ("monitored_acceptance_worktime", "計測作業時間(受入)"),
        ]
        if df["actual_worktime_hour"].sum() > 0:
            # 条件分岐の理由:実績作業時間がないときは、非計測作業時間がマイナス値になり、分かりづらいグラフになるため。必要なときのみ非計測作業時間をプロットする
            phase_prefix.append(("unmonitored_worktime", "非計測作業時間"))

        fig_info_list = [
            {
                "figure": create_figure(title="日ごとの作業時間", y_axis_label="作業時間[hour]"),
                "y_info_list": [
                    {"column": "actual_worktime_hour", "legend": "実績作業時間"},
                    {"column": "monitored_worktime_hour", "legend": "計測作業時間"},
                ],
            },
            {
                "figure": create_figure(title="日ごとのタスクあたり作業時間", y_axis_label="タスクあたり作業時間[hour/task]"),
                "y_info_list": [
                    {"column": "actual_worktime_hour/task_count", "legend": "タスクあたり実績作業時間"},
                    {"column": "monitored_worktime_hour/task_count", "legend": "タスクあたり計測作業時間"},
                ],
            },
            {
                "figure": create_figure(title="日ごとの入力データあたり作業時間", y_axis_label="入力データあたり作業時間[minute/input_data]"),
                "y_info_list": [
                    {"column": f"{e[0]}_minute/input_data_count", "legend": f"入力データあたり{e[1]}"} for e in phase_prefix
                ],
            },
            {
                "figure": create_figure(title="日ごとのアノテーションあたり作業時間", y_axis_label="アノテーションあたり作業時間[minute/annotation]"),
                "y_info_list": [
                    {"column": f"{e[0]}_minute/annotation_count", "legend": f"アノテーションあたり{e[1]}"} for e in phase_prefix
                ],
            },
        ]

        source = ColumnDataSource(data=df)

        for fig_info in fig_info_list:
            y_info_list: list[dict[str, str]] = fig_info["y_info_list"]  # type: ignore
            for index, y_info in enumerate(y_info_list):
                color = get_color_from_small_palette(index)

                plot_and_moving_average(
                    fig=fig_info["figure"],
                    y_column_name=y_info["column"],
                    legend_name=y_info["legend"],
                    source=source,
                    color=color,
                )

        tooltip_item = [
            "date",
            "task_count",
            "input_data_count",
            "actual_worktime_hour",
            "monitored_worktime_hour",
            "cumsum_task_count",
            "cumsum_input_data_count",
            "cumsum_actual_worktime_hour",
            "actual_worktime_hour/task_count",
            "actual_worktime_minute/input_data_count",
            "actual_worktime_minute/annotation_count",
            "monitored_worktime_hour/task_count",
            "monitored_worktime_minute/input_data_count",
            "monitored_worktime_minute/annotation_count",
        ]
        hover_tool = create_hover_tool(tooltip_item)

        figure_list = [
            create_task_figure(),
            create_input_data_figure(),
        ]
        figure_list.extend([info["figure"] for info in fig_info_list])

        for fig in figure_list:
            fig.add_tools(hover_tool)
            add_legend_to_figure(fig)

        div_element = self._create_div_element()
        write_bokeh_graph(bokeh.layouts.column([div_element] + figure_list), output_file)

    def plot_cumulatively(self, output_file: Path):

0 Source : whole_productivity_per_date.py
with MIT License
from kurusugawa-computer

    def plot_cumulatively(self, output_file: Path):
        """
        全体の生産量や作業時間の累積折れ線グラフを出力する
        """

        def create_figure(title: str, y_axis_label: str) -> bokeh.plotting.Figure:
            return figure(
                plot_width=1200,
                plot_height=600,
                title=title,
                x_axis_label="日",
                x_axis_type="datetime",
                y_axis_label=y_axis_label,
            )

        def create_task_figure():
            x_column_name = "dt_date"
            y_range_name = "worktime_axis"
            fig = create_figure(title="日ごとの累積タスク数と累積作業時間", y_axis_label="タスク数")
            fig.add_layout(
                LinearAxis(
                    y_range_name=y_range_name,
                    axis_label="作業時間[hour]",
                ),
                "right",
            )
            y_overlimit = 0.05
            fig.extra_y_ranges = {
                y_range_name: DataRange1d(
                    end=max(df["cumsum_actual_worktime_hour"].max(), df["cumsum_monitored_worktime_hour"].max())
                    * (1 + y_overlimit)
                )
            }

            # 値をプロット
            plot_line_and_circle(
                fig,
                x_column_name=x_column_name,
                y_column_name="cumsum_task_count",
                source=source,
                color=get_color_from_small_palette(0),
                legend_label="タスク数",
            )

            # 値をプロット
            plot_line_and_circle(
                fig,
                x_column_name=x_column_name,
                y_column_name="cumsum_actual_worktime_hour",
                source=source,
                color=get_color_from_small_palette(1),
                legend_label="実績作業時間",
                y_range_name=y_range_name,
            )
            plot_line_and_circle(
                fig,
                x_column_name=x_column_name,
                y_column_name="cumsum_monitored_worktime_hour",
                source=source,
                color=get_color_from_small_palette(2),
                legend_label="計測作業時間",
                y_range_name=y_range_name,
            )

            return fig

        def create_input_data_figure():
            x_column_name = "dt_date"
            y_range_name = "worktime_axis"
            fig = create_figure(title="日ごとの累積入力データ数と累積作業時間", y_axis_label="入力データ数")
            fig.add_layout(
                LinearAxis(
                    y_range_name=y_range_name,
                    axis_label="作業時間[hour]",
                ),
                "right",
            )
            y_overlimit = 0.05
            fig.extra_y_ranges = {
                y_range_name: DataRange1d(
                    end=max(df["cumsum_actual_worktime_hour"].max(), df["cumsum_monitored_worktime_hour"].max())
                    * (1 + y_overlimit)
                )
            }

            # 値をプロット
            plot_line_and_circle(
                fig,
                x_column_name=x_column_name,
                y_column_name="cumsum_input_data_count",
                source=source,
                color=get_color_from_small_palette(0),
                legend_label="入力データ数",
            )

            # 値をプロット
            plot_line_and_circle(
                fig,
                x_column_name=x_column_name,
                y_column_name="cumsum_actual_worktime_hour",
                source=source,
                color=get_color_from_small_palette(1),
                legend_label="実績作業時間",
                y_range_name=y_range_name,
            )

            # 値をプロット
            plot_line_and_circle(
                fig,
                x_column_name=x_column_name,
                y_column_name="cumsum_monitored_worktime_hour",
                source=source,
                color=get_color_from_small_palette(2),
                legend_label="計測作業時間",
                y_range_name=y_range_name,
            )

            return fig

        if not self._validate_df_for_output(output_file):
            return

        df = self.df.copy()
        df["dt_date"] = df["date"].map(lambda e: parse(e).date())
        df["cumsum_monitored_worktime_hour"] = df["monitored_worktime_hour"].cumsum()

        logger.debug(f"{output_file} を出力します。")

        source = ColumnDataSource(data=df)

        tooltip_item = [
            "date",
            "task_count",
            "input_data_count",
            "actual_worktime_hour",
            "monitored_worktime_hour",
            "cumsum_task_count",
            "cumsum_input_data_count",
            "cumsum_actual_worktime_hour",
            "cumsum_monitored_worktime_hour",
        ]
        hover_tool = create_hover_tool(tooltip_item)

        fig_list = [create_task_figure(), create_input_data_figure()]

        for fig in fig_list:
            fig.add_tools(hover_tool)
            add_legend_to_figure(fig)

        div_element = self._create_div_element()
        write_bokeh_graph(bokeh.layouts.column([div_element] + fig_list), output_file)

    def to_csv(self, output_file: Path) -> None:

0 Source : whole_productivity_per_date.py
with MIT License
from kurusugawa-computer

    def plot(self, output_file: Path):
        """
        全体の生産量や生産性をプロットする
        """

        def add_velocity_and_weekly_moving_average_columns(df):
            for column in [
                "input_data_count",
                "worktime_hour",
                "annotation_worktime_hour",
                "inspection_worktime_hour",
                "acceptance_worktime_hour",
            ]:
                df[f"{column}{WEEKLY_MOVING_AVERAGE_COLUMN_SUFFIX}"] = get_weekly_moving_average(df[column])

            for denominator in ["input_data_count", "annotation_count"]:
                for numerator in ["worktime", "annotation_worktime", "inspection_worktime", "acceptance_worktime"]:
                    df[f"{numerator}_minute/{denominator}"] = df[f"{numerator}_hour"] * 60 / df[denominator]
                    df[f"{numerator}_minute/{denominator}{WEEKLY_MOVING_AVERAGE_COLUMN_SUFFIX}"] = (
                        get_weekly_sum(df[f"{numerator}_hour"]) * 60 / get_weekly_sum(df[denominator])
                    )

        def create_div_element() -> bokeh.models.Div:
            """
            HTMLページの先頭に付与するdiv要素を生成する。
            """
            return bokeh.models.Div(
                text="""  <  h4>注意 < /h4>
                 < p>「X日の作業時間」とは、「X日に教師付開始したタスクにかけた作業時間」です。
                「X日に作業した時間」ではありません。
                 < /p>
                """
            )

        def create_figure(title: str, y_axis_label: str) -> bokeh.plotting.Figure:
            return figure(
                plot_width=1200,
                plot_height=600,
                title=title,
                x_axis_label="教師開始日",
                x_axis_type="datetime",
                y_axis_label=y_axis_label,
            )

        def create_input_data_figure():
            y_range_name = "worktime_axis"
            fig_input_data = create_figure(title="日ごとの入力データ数と作業時間", y_axis_label="入力データ数")
            fig_input_data.add_layout(
                LinearAxis(
                    y_range_name=y_range_name,
                    axis_label="作業時間[hour]",
                ),
                "right",
            )
            y_overlimit = 0.05
            fig_input_data.extra_y_ranges = {
                y_range_name: DataRange1d(end=df["worktime_hour"].max() * (1 + y_overlimit))
            }
            self._plot_and_moving_average(
                fig=fig_input_data,
                x_column_name="dt_first_annotation_started_date",
                y_column_name="input_data_count",
                legend_name="入力データ数",
                source=source,
                color=get_color_from_small_palette(0),
            )
            self._plot_and_moving_average(
                fig=fig_input_data,
                x_column_name="dt_first_annotation_started_date",
                y_column_name="worktime_hour",
                legend_name="作業時間",
                source=source,
                color=get_color_from_small_palette(1),
                y_range_name=y_range_name,
            )
            return fig_input_data

        if not self._validate_df_for_output(output_file):
            return

        df = self.df.copy()
        df["dt_first_annotation_started_date"] = df["first_annotation_started_date"].map(lambda e: parse(e).date())
        add_velocity_and_weekly_moving_average_columns(df)

        logger.debug(f"{output_file} を出力します。")

        fig_list = [
            create_figure(title="教師付開始日ごとの作業時間", y_axis_label="作業時間[hour]"),
            create_figure(title="教師付開始日ごとの入力データあたり作業時間", y_axis_label="入力データあたり作業時間[minute/input_data]"),
            create_figure(title="教師付開始日ごとのアノテーションあたり作業時間", y_axis_label="アノテーションあたり作業時間[minute/annotation]"),
        ]

        fig_info_list = [
            {
                "x": "dt_first_annotation_started_date",
                "y_info_list": [
                    {"column": "worktime_hour", "legend": "作業時間"},
                    {"column": "annotation_worktime_hour", "legend": "教師付作業時間"},
                    {"column": "inspection_worktime_hour", "legend": "検査作業時間"},
                    {"column": "acceptance_worktime_hour", "legend": "受入作業時間"},
                ],
            },
            {
                "x": "dt_first_annotation_started_date",
                "y_info_list": [
                    {"column": "worktime_minute/input_data_count", "legend": "入力データあたり作業時間"},
                    {"column": "annotation_worktime_minute/input_data_count", "legend": "入力データあたり教師付作業時間"},
                    {"column": "inspection_worktime_minute/input_data_count", "legend": "入力データあたり検査作業時間"},
                    {"column": "acceptance_worktime_minute/input_data_count", "legend": "入力データあたり受入作業時間"},
                ],
            },
            {
                "x": "dt_date",
                "y_info_list": [
                    {"column": "worktime_minute/annotation_count", "legend": "アノテーション作業時間"},
                    {"column": "annotation_worktime_minute/annotation_count", "legend": "アノテーションあたり教師付作業時間"},
                    {"column": "inspection_worktime_minute/annotation_count", "legend": "アノテーションあたり検査作業時間"},
                    {"column": "acceptance_worktime_minute/annotation_count", "legend": "アノテーションあたり受入作業時間"},
                ],
            },
        ]

        source = ColumnDataSource(data=df)

        for fig, fig_info in zip(fig_list, fig_info_list):
            y_info_list: list[dict[str, str]] = fig_info["y_info_list"]  # type: ignore
            for index, y_info in enumerate(y_info_list):
                color = get_color_from_small_palette(index)

                self._plot_and_moving_average(
                    fig=fig,
                    x_column_name="dt_first_annotation_started_date",
                    y_column_name=y_info["column"],
                    legend_name=y_info["legend"],
                    source=source,
                    color=color,
                )

        tooltip_item = [
            "first_annotation_started_date",
            "task_count",
            "input_data_count",
            "annotation_count",
            "worktime_hour",
            "annotation_worktime_hour",
            "inspection_worktime_hour",
            "acceptance_worktime_hour",
            "worktime_minute/input_data_count",
            "annotation_worktime_minute/input_data_count",
            "inspection_worktime_minute/input_data_count",
            "acceptance_worktime_minute/input_data_count",
            "worktime_minute/annotation_count",
            "annotation_worktime_minute/annotation_count",
            "inspection_worktime_minute/annotation_count",
            "acceptance_worktime_minute/annotation_count",
        ]
        hover_tool = create_hover_tool(tooltip_item)

        fig_list.insert(0, create_input_data_figure())

        for fig in fig_list:
            fig.add_tools(hover_tool)
            add_legend_to_figure(fig)

        output_file.parent.mkdir(exist_ok=True, parents=True)
        bokeh.plotting.reset_output()
        bokeh.plotting.output_file(output_file, title=output_file.stem)

        bokeh.plotting.save(bokeh.layouts.column([create_div_element()] + fig_list))

0 Source : compare_tab.py
with Apache License 2.0
from nancyyanyu

def compare_plot():

    stats = PreText(text='', width=500)
    corr = PreText(text='', width=500)
    def _ma(series,n):
        return series.rolling(window=n).mean()
    
    # connect to Cassandra database
    def make_dataset(start='2014-01-01'):
        df=pd.DataFrame()
        for comp in symbol_list:
            database=CassandraStorage(comp)
            database.session.row_factory = pandas_factory
            database.session.default_fetch_size = None
            
            query="SELECT * FROM {} WHERE time>'{}' ALLOW FILTERING;".format(database.symbol+'_historical',start)
            rslt = database.session.execute(query, timeout=None)
            df_comp = rslt._current_rows
            df_comp['ma5']=_ma(df_comp.adjusted_close,5)
            df_comp['ma10']=_ma(df_comp.adjusted_close,10)
            df_comp['ma30']=_ma(df_comp.adjusted_close,30)
            df=df.append(df_comp)
        return df
    
    
    df_all=make_dataset(start='2014-01-01')
    df_init=df_all[df_all.symbol==symbol_list[0]]
    source=ColumnDataSource(data= df_init.to_dict('list'))
    
    # hover setting
    TOOLTIPS = [
            ("time", "@time{%F}"),
            ("adjusted close", "$@adjusted_close"),
             ("close", "$@close"),
            ("open", "$@open"),
            ("high", "$@high"),
            ("low", "$@low"),
            ("volume","@volume")]
    formatters={
        'time'      : 'datetime'}
    hover = HoverTool(tooltips=TOOLTIPS,formatters=formatters,mode='vline')
    
    # create plot
    p = figure(title='{} (Click on legend entries to hide the corresponding lines)'.format(symbol_list[0]),
                plot_height=300,  
                tools="crosshair,save,undo,xpan,xwheel_zoom,ybox_zoom,reset", 
                active_scroll='xwheel_zoom',
                x_axis_type="datetime", 
                y_axis_location="left")
    
    p.add_tools(hover)
    palte=all_palettes['Set2'][8]
    p.line('time', 'adjusted_close', alpha=1.0, line_width=2, color=palte[3], legend='Adjusted Close',source=source)
    p.line('time', 'ma5', line_width=1, color=palte[0], alpha=0.8, muted_color='navy', muted_alpha=0.1, legend='MA5',source=source)
    p.line('time', 'ma10', line_width=1, color=palte[1], alpha=0.8, muted_color='navy', muted_alpha=0.1, legend='MA10',source=source)
    p.line('time', 'ma30', line_width=1, color=palte[2], alpha=0.8, muted_color='navy', muted_alpha=0.1, legend='MA30',source=source)
    p.y_range = Range1d(min(source.data['adjusted_close'])*0.3, max(source.data['adjusted_close'])*1.05)
    p.extra_y_ranges = {"volumes": Range1d(start=min(source.data['volume'])/2, 
                                           end=max(source.data['volume'])*2)}
    p.add_layout(LinearAxis(y_range_name="volumes"), 'right')
    p.vbar('time', width=3,top='volume', color=choice(all_palettes['Set2'][8]),alpha=0.5, y_range_name="volumes",source=source)
    p.legend.location = "top_left"
    p.legend.click_policy="hide"
        
    def callback(attr,old,new):
        symbol1, symbol2=compare_select1.value, compare_select2.value
        df_init1=df_all[df_all.symbol==symbol1]
        df_init2=df_all[df_all.symbol==symbol2]

        source.data.update( df_init1.to_dict('list'))
        p.title.text =symbol1+' (Click on legend entries to hide the corresponding lines)'
        p.y_range.start=min(source.data['adjusted_close'])*0.3
        p.y_range.end=max(source.data['adjusted_close'])*1.05
        p.extra_y_ranges['volumes'].start=min(source.data['volume'])/2.
        p.extra_y_ranges['volumes'].end=max(source.data['volume'])*2.

        source2.data.update( df_init2.to_dict('list'))
        p2.title.text =symbol2+' (Click on legend entries to hide the corresponding lines)'
        p2.y_range.start=min(source2.data['adjusted_close'])*0.3
        p2.y_range.end=max(source2.data['adjusted_close'])*1.05
        p2.extra_y_ranges['volumes'].start=min(source2.data['volume'])/2.
        p2.extra_y_ranges['volumes'].end=max(source2.data['volume'])*2.

        update_stat(symbol1,symbol2)
    
        
    
    def update_stat(symbol1,symbol2):
        des=pd.DataFrame()
        des[symbol1]=df_all[df_all.symbol==symbol1]['adjusted_close']
        des[symbol2]=df_all[df_all.symbol==symbol2]['adjusted_close']
        des[symbol1+'_return']=des[symbol1].pct_change()
        des[symbol2+'_return']=des[symbol2].pct_change()
        stats.text = "Statistics \n"+str(des.describe())
        
        correlation=des[[symbol1+'_return',symbol2+'_return']].corr()
        corr.text="Correlation \n"+str(correlation)
    
    update_stat(symbol_list[0],symbol_list[1])
    compare_select1=Select(value=symbol_list[0],options=symbol_list)
    compare_select1.on_change('value', callback)
    
    
    
    
    """
    Tab2-plot2: 
        
    """
    
    df_init2=df_all[df_all.symbol==symbol_list[1]]
    source2=ColumnDataSource(data= df_init2.to_dict('list'))
    
    # create plot
    # hover setting
    p2 = figure(title='{}  (Click on legend entries to hide the corresponding lines)'.format(symbol_list[1]),plot_height=300,  
                tools="crosshair,save,undo,xpan,xwheel_zoom,ybox_zoom,reset", 
                active_scroll='xwheel_zoom',
                x_axis_type="datetime", 
                y_axis_location="left")
    
    p2.add_tools(hover)
    p2.line('time', 'adjusted_close', alpha=1.0, line_width=2, color=palte[4], legend='Adjusted Close',source=source2)
    p2.line('time', 'ma5', line_width=1, color=palte[5], alpha=0.8, muted_color='navy', muted_alpha=0.1, legend='MA5',source=source2)
    p2.line('time', 'ma10', line_width=1, color=palte[6], alpha=0.8, muted_color='navy', muted_alpha=0.1, legend='MA10',source=source2)
    p2.line('time', 'ma30', line_width=1, color=palte[7], alpha=0.8, muted_color='navy', muted_alpha=0.1, legend='MA30',source=source2)

    p2.y_range = Range1d(min(source2.data['adjusted_close'])*0.3, max(source2.data['adjusted_close'])*1.05)

    
    p2.extra_y_ranges = {"volumes": Range1d(start=min(source2.data['volume'])/2, 
                                           end=max(source2.data['volume'])*2)}
    p2.add_layout(LinearAxis(y_range_name="volumes"), 'right')
    p2.vbar('time', width=3,top='volume', color=choice(all_palettes['Set2'][8]),alpha=0.5, y_range_name="volumes",source=source2)


    p2.legend.location = "top_left"
    p2.legend.click_policy="hide"
    
    compare_select2=Select(value=symbol_list[1],options=symbol_list)
    compare_select2.on_change('value', callback)
    
    widget=column(compare_select1,compare_select2)
    
    return p,p2,widget,stats,corr



0 Source : single_tab.py
with Apache License 2.0
from nancyyanyu

def candlestick():
    if '^GSPC' in symbol_list:
        symbol_list.remove('^GSPC')
    stock_select=Select(value=symbol_list[0],options=symbol_list)
    summaryText = Div(text="",width=400)
    financialText=Div(text="",width=180)
    
    def update_summary(symbol):
        company,buzzsummary,officerString,institution_df=read_company(symbol)
        summaryText.text ="""  <  b> < p style="color:blue;">Overview:  < /p> < /b>
                              < b>Company: < /b> {} < br>
                              < b>Address: < /b> {}  < br>
                              < b>City: < /b> {}  < br>
                              < b>State: < /b> {}  < br>
                              < b>Website: < /b>  < a href="{}">{} < /a>  < br>
                              < b>Industry: < /b> {}  < br>
                              < b>Sector: < /b> {}  < br>
                              < b>Company Officers: < /b> {}  < br>                             
                              < b>Summary: < /b> {}  < br>""".format(company['price']['longName'],
                                                     company['summaryProfile']['address1'],
                                                     company['summaryProfile']['city'],
                                                     company['summaryProfile']['state'],
                                                     company['summaryProfile']['website'],
                                                     company['summaryProfile']['website'],
                                                     company['summaryProfile']['industry'],
                                                     company['summaryProfile']['sector'],
                                                     officerString,
                                                     buzzsummary)
        financialText.text=""" < b> < p style="color:blue;">Financial:  < /p> < /b>
                               < b>Recommendation: {} < /b>  < br>
                               < b>Enterprise Value: < /b> {}  < br>
                               < b>Profit Margins: < /b> {}  < br>
                               < b>Beta: < /b> {}  < br>
                               < b>EBITDA: < /b> {}  < br>
                               < b>Total Debt: < /b> {}  < br>
                               < b>Total Revenue: < /b> {} < br>
                               < b>DebtToEquity: < /b> {} < br>
                               < b>Revenue Growth: < /b> {}  < br>
                               < b>Current Ratio: < /b> {}  < br>
                               < b>ROE: < /b> {}  < br>
                               < b>ROA: < /b> {}  < br>
                               < b>Gross Profits: < /b> {}  < br>
                               < b>Quick Ratio: < /b> {}  < br>
                               < b>Free Cashflow: < /b> {}  < br>
                              """.format(company['financialData']['recommendationKey'].upper(),
                                         company['defaultKeyStatistics']['enterpriseValue']['fmt'],
                                         company['defaultKeyStatistics']['profitMargins']['fmt'],
                                         company['defaultKeyStatistics']['beta']['fmt'],
                                         company['financialData']['ebitda']['fmt'],
                                         company['financialData']['totalDebt']['fmt'],
                                         company['financialData']['totalRevenue']['fmt'],
                                         company['financialData']['debtToEquity']['fmt'],
                                         company['financialData']['revenueGrowth']['fmt'],
                                         company['financialData']['currentRatio']['fmt'],
                                         company['financialData']['returnOnAssets']['fmt'],
                                         company['financialData']['returnOnEquity']['fmt'],
                                         company['financialData']['grossProfits']['fmt'],
                                         company['financialData']['quickRatio']['fmt'],
                                         company['financialData']['freeCashflow']['fmt'])

    update_summary(stock_select.value)
    # connect to Cassandra database
    database=CassandraStorage(symbol_list[0])
    database.session.row_factory = pandas_factory
    database.session.default_fetch_size = None
    
    query="SELECT * FROM {} WHERE time>'2015-01-01'  ALLOW FILTERING;".format('{}_historical'.format(symbol_list[0]))
    rslt = database.session.execute(query, timeout=None)
    df = rslt._current_rows
    
    # create color list
    color=df.close>df.open
    color=color.replace(True,'green')
    color=color.replace(False,'red')

    # set data source
    source = ColumnDataSource(data=dict(close=list(df.close.values),
                                        adjusted_close=list(df.adjusted_close.values),
                                        open=list(df.open.values),
                                        high=list(df.high.values),
                                        low=list(df.low.values),
                                        volume=list(df.volume.values),
                                        time=list(df.time.dt.date.values),
                                        color=list(color.values)))
    
    

    # hover setting
    TOOLTIPS = [
            ("time", "@time{%F}"),
            ("adjusted close", "$@adjusted_close"),
            ("close", "$@close"),
            ("open", "$@open"),
            ("high", "$@high"),
            ("low", "$@low"),
            ("volume","@volume")]
    formatters={
        'time'      : 'datetime'}
    hover = HoverTool(tooltips=TOOLTIPS,formatters=formatters,mode='vline')
    
    # create figure
    p = figure(title='{} Candlestick'.format(stock_select.value),plot_height=400, 
               tools="crosshair,save,undo,xpan,xwheel_zoom,xbox_zoom,reset", 
               active_scroll='xwheel_zoom',
               x_axis_type="datetime")  
    p.add_tools(hover)
    


    p.line('time', 'close', alpha=0.2, line_width=1, color='navy', source=source)
    p.segment('time', 'high', 'time', 'low', line_width=1,color="black", source=source)
    p.segment('time', 'open', 'time', 'close', line_width=3, color='color', source=source)
    p.y_range = Range1d(min(source.data['close'])*0.3, max(source.data['close'])*1.05)

    
    p.extra_y_ranges = {"volumes": Range1d(start=min(source.data['volume'])/2, 
                                           end=max(source.data['volume'])*2)}
    p.add_layout(LinearAxis(y_range_name="volumes"), 'right')
    p.vbar('time', width=3,top='volume', color=choice(all_palettes['Set2'][8]),alpha=0.5, y_range_name="volumes",source=source)

    p.xaxis.axis_label = 'Time'
    
    # set data source
    _,_,_,institution_df=read_company(symbol_list[0])
    source_ins = ColumnDataSource(data=dict(organization=list(institution_df.organization.values),
                                            pctHeld=list(institution_df.pctHeld.values),
                                            position=list(institution_df.position.values),
                                            color=Set3[12][:len(institution_df)]))
    s1=figure(x_range=source_ins.data['organization'],plot_height=300,plot_width=700,title='Institution Ownership')
    s1.vbar(x='organization', top='position', width=0.8, color='color', source=source_ins)
    s1.xaxis.major_label_orientation = pi/7
    labels = LabelSet(x='organization', y='position', text='pctHeld', level='glyph',
              x_offset=-15, y_offset=-10, source=source_ins, render_mode='canvas',text_font_size="8pt")
    s1.add_layout(labels)
    # callback funtion for Select tool 'stock_select'
    def callback(attr,old,new):
        symbol=stock_select.value
        _,_,_,institution=read_company(symbol)

        if symbol=='S&P500':
            symbol='^GSPC'
        database=CassandraStorage(symbol)
        database.session.row_factory = pandas_factory
        database.session.default_fetch_size = None
        if symbol=='^GSPC':
            symbol='GSPC'
        query="SELECT * FROM {} WHERE time>'2015-01-01'  ALLOW FILTERING;".format(symbol+'_historical')
        rslt = database.session.execute(query, timeout=None)
        df = rslt._current_rows
    
        color=df.close>df.open
        color=color.replace(True,'green')
        color=color.replace(False,'red')
        
        # update source data 
        source.data=dict(close=list(df.close.values),
                                        adjusted_close=list(df.adjusted_close.values),
                                        open=list(df.open.values),
                                        high=list(df.high.values),
                                        low=list(df.low.values),
                                        volume=list(df.volume.values),
                                        time=list(df.time.dt.date.values),
                                        color=list(color.values))
        source_ins.data=dict(organization=list(institution.organization.values),
                                        pctHeld=list(institution.pctHeld.values),
                                        position=list(institution.position.values),
                                        color=Set3[12][:len(institution)])
        
        p.title.text=symbol+' Candlestick'
        p.y_range.start=min(source.data['close'])*0.3
        p.y_range.end=max(source.data['close'])*1.05
        p.extra_y_ranges['volumes'].start=min(source.data['volume'])/2.
        p.extra_y_ranges['volumes'].end=max(source.data['volume'])*2.

        s1.x_range.factors=source_ins.data['organization']
        update_summary(symbol)
        
    stock_select.on_change('value', callback)
    
    return p,stock_select,summaryText,financialText,s1

def stream_price():

0 Source : single_tab.py
with Apache License 2.0
from nancyyanyu

def stream_price():
    
    # connect to s&p500's database
    plot_symbol='^GSPC'
    database=CassandraStorage(plot_symbol)
    database.session.row_factory = pandas_factory
    database.session.default_fetch_size = None
    
#    if datetime.datetime.now(timezone('US/Eastern')).time()  <  datetime.time(9,30):
#        query_time=str(datetime.datetime.now().date())
    
    
    last_trading_day= datetime.datetime.now(timezone(timeZone)).date()
    
    query="SELECT * FROM {} WHERE time>='{}'  ALLOW FILTERING;".format(plot_symbol[1:]+'_tick',last_trading_day)
    rslt = database.session.execute(query, timeout=None)
    df = rslt._current_rows

        # wrangle timezone (Cassandra will change datetime to UTC time)
    trans_time=pd.DatetimeIndex(pd.to_datetime(df.time,unit='ms')).tz_localize('GMT').tz_convert('US/Pacific').to_pydatetime()
    trans_time=[i.replace(tzinfo=None) for i in trans_time]
    source= ColumnDataSource()
    
    # hover setting
    TOOLTIPS = [
            ("time", "@time{%F %T}"),
            ("close", "$@close"),
            ("volume","@volume")]
    formatters={
        'time'      : 'datetime'}
    hover = HoverTool(tooltips=TOOLTIPS,formatters=formatters,mode='vline')

    # create plot
    p = figure(title='S&P500 Realtime Price',
                plot_height=200,  
                tools="crosshair,save,undo,xpan,xwheel_zoom,ybox_zoom,reset", 
                x_axis_type="datetime", 
                y_axis_location="left")
    p.add_tools(hover)
    p.x_range.follow = "end"
    p.x_range.follow_interval = 1000000
    p.x_range.range_padding = 0

    # during trading
    if len(df)>0 \
        and datetime.datetime.now(timezone(timeZone)).time() < datetime.time(16,0,0) \
        and datetime.datetime.now(timezone(timeZone)).time()>datetime.time(9,30,0):
        # init source data to those already stored in Cassandra dataase - '{}_tick', so that streaming plot will not start over after refreshing
        source= ColumnDataSource(dict(time=list(trans_time),  
                                       close=list(df.close.values),
                                       volume=list(df.volume.values)))
        p.y_range = Range1d(min(source.data['close'])/1.005, max(source.data['close'])*1.005)
        p.extra_y_ranges = {"volumes": Range1d(start=min(source.data['volume'])*0.5, 
                                               end=max(source.data['volume'])*2)}
    # no trading history or not during trading hour
    else:
        source= ColumnDataSource(dict(time=[],  
                                       close=[],
                                       volume=[]))
    
        p.y_range = Range1d(0,1e4)
        p.extra_y_ranges = {"volumes": Range1d(start=0, 
                                               end=1e10)}
        
    p.line(x='time', y='close', alpha=0.2, line_width=3, color='blue', source=source)    
    p.add_layout(LinearAxis(y_range_name="volumes"), 'right')    
    p.vbar('time', width=3,top='volume', color=choice(all_palettes['Set2'][8]),alpha=0.5, y_range_name="volumes",source=source)
    
    
    # get update data from a json file overwritter every ~18 seconds
    def _create_prices():
        with open(path+'cache/data.json','r') as f:
            dict_data = json.load(f)
        return float(dict_data['close']),dict_data['volume'],dict_data['time']
    
    # update function for stream plot
    def update():
        close,volume,time=_create_prices()
        new_data = dict(
            time=[datetime.datetime.strptime(time[:19], "%Y-%m-%d %H:%M:%S")],
            close=[close],
            volume=[volume]
        )
        #print(new_data)
        source.stream(new_data)
        #print ('update source data',str(time))
    return p,update

0 Source : visualization.py
with MIT License
from pedromartins4

def plot_macd(stock):
    p = figure(x_axis_type="datetime", plot_width=WIDTH_PLOT, plot_height=200, title="MACD (line + histogram)",
               tools=TOOLS, toolbar_location='above')

    up = [True if val > 0 else False for val in stock.data['macd_histogram']]
    down = [True if val   <   0 else False for val in stock.data['macd_histogram']]

    view_upper = CDSView(source=stock, filters=[BooleanFilter(up)])
    view_lower = CDSView(source=stock, filters=[BooleanFilter(down)])
    p.vbar(x='date', top='macd_histogram', bottom='zeros', width=30000000, color=GREEN, source=stock, view=view_upper)
    p.vbar(x='date', top='zeros', bottom='macd_histogram', width=30000000, color=RED, source=stock, view=view_lower)

    # Adding an extra range for the MACD lines, because using the same axis as the histogram
    # sometimes flattens them too much
    p.extra_y_ranges = {'macd': DataRange1d()}
    p.add_layout(LinearAxis(y_range_name='macd'), 'right')

    p.line(x='date', y='macd', line_width=2, color=BLUE, source=stock, legend='MACD', muted_color=BLUE,
           muted_alpha=0, y_range_name='macd')
    p.line(x='date', y='macd_signal', line_width=2, color=BLUE_LIGHT, source=stock, legend='Signal',
           muted_color=BLUE_LIGHT, muted_alpha=0, y_range_name='macd')

    p.legend.location = "bottom_left"
    p.legend.border_line_alpha = 0
    p.legend.background_fill_alpha = 0
    p.legend.click_policy = "mute"

    p.yaxis.ticker = []
    p.yaxis.axis_line_alpha = 0

    return p


# RSI
def plot_rsi(stock):

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

def make_plot(info, outfile):
    # prepare some data
    (wall_times, pyglet_times, audio_times,
     current_times, frame_nums, rescheds,
     x_vnones, y_vnones,
     x_anones, y_anones) = info

    # output to static HTML file
    output_file(outfile)

    # main plot
    p = figure(
       tools="pan,wheel_zoom,reset,save",
       y_axis_type="linear", y_range=[0.000, wall_times[-1]], title="timeline",
       x_axis_label='wall_time', y_axis_label='time',
       plot_width=600, plot_height=600
    )

    # add some renderers
    p.line(wall_times, wall_times, legend="wall_time")
    #p.line(wall_times, pyglet_times, legend="pyglet_time", line_width=3)
    p.line(wall_times, current_times, legend="current_times", line_color="red")
    p.line(wall_times, audio_times, legend="audio_times", line_color="orange", line_dash="4 4")

    p.circle(x_vnones, y_vnones, legend="current time nones", fill_color="green", size=8)
    p.circle(x_anones, y_anones, legend="audio time nones", fill_color="red", size=6)

    # secondary y-axis for frame_num
    p.extra_y_ranges = {"frame_num": Range1d(start=0, end=frame_nums[-1])}
    p.line(wall_times, frame_nums, legend="frame_num",
           line_color="black", y_range_name="frame_num")
    p.add_layout(LinearAxis(y_range_name="frame_num", axis_label="frame num"), 'left')

    p.legend.location = "bottom_right"
    # show the results
    #show(p)

    # secondary plot for rescheduling times
    q = figure(
       tools="pan,wheel_zoom,reset,save",
       y_axis_type="linear", y_range=[-0.3, 0.3], title="rescheduling time",
       x_axis_label='wall_time', y_axis_label='rescheduling time',
       plot_width=600, plot_height=150
    )
    q.line(wall_times, rescheds)

    show(column(p, q))


def usage():

0 Source : test_query.py
with MIT License
from rthorst

def large_plot():
    source = ColumnDataSource(data=dict(x=[0, 1], y=[0, 1]))

    xdr = Range1d(start=0, end=1)
    xdr.tags.append("foo")
    xdr.tags.append("bar")

    ydr = Range1d(start=10, end=20)
    ydr.tags.append("foo")
    ydr.tags.append(11)

    plot = Plot(x_range=xdr, y_range=ydr)

    ydr2 = Range1d(start=0, end=100)
    plot.extra_y_ranges = {"liny": ydr2}

    circle = Circle(x="x", y="y", fill_color="red", size=5, line_color="black")
    plot.add_glyph(source, circle, name="mycircle")

    line = Line(x="x", y="y")
    plot.add_glyph(source, line, name="myline")

    rect = Rect(x="x", y="y", width=1, height=1, fill_color="green")
    plot.add_glyph(source, rect, name="myrect")

    plot.add_layout(DatetimeAxis(), 'below')
    plot.add_layout(LogAxis(), 'left')
    plot.add_layout(LinearAxis(y_range_name="liny"), 'left')

    plot.add_layout(Grid(dimension=0), 'left')
    plot.add_layout(Grid(dimension=1), 'left')

    plot.add_tools(
        BoxZoomTool(), PanTool(), SaveTool(), ResetTool(), WheelZoomTool(),
    )

    return plot

plot = large_plot()

0 Source : test_figure.py
with MIT License
from rthorst

    def test_xaxis(self):
        p = bpf.figure()
        p.circle([1, 2, 3], [1, 2, 3])
        assert len(p.xaxis) == 1

        expected = set(p.xaxis)

        ax = LinearAxis()
        expected.add(ax)
        p.above.append(ax)
        assert set(p.xaxis) == expected

        ax2 = LinearAxis()
        expected.add(ax2)
        p.above.append(ax2)
        assert set(p.xaxis) == expected

        p.left.append(LinearAxis())
        assert set(p.xaxis) == expected

        p.right.append(LinearAxis())
        assert set(p.xaxis) == expected

    def test_yaxis(self):

0 Source : test_figure.py
with MIT License
from rthorst

    def test_yaxis(self):
        p = bpf.figure()
        p.circle([1, 2, 3], [1, 2, 3])
        assert len(p.yaxis) == 1

        expected = set(p.yaxis)

        ax = LinearAxis()
        expected.add(ax)
        p.right.append(ax)
        assert set(p.yaxis) == expected

        ax2 = LinearAxis()
        expected.add(ax2)
        p.right.append(ax2)
        assert set(p.yaxis) == expected

        p.above.append(LinearAxis())
        assert set(p.yaxis) == expected

        p.below.append(LinearAxis())
        assert set(p.yaxis) == expected

    def test_axis(self):

0 Source : test_figure.py
with MIT License
from rthorst

    def test_axis(self):
        p = bpf.figure()
        p.circle([1, 2, 3], [1, 2, 3])
        assert len(p.axis) == 2

        expected = set(p.axis)

        ax = LinearAxis()
        expected.add(ax)
        p.above.append(ax)
        assert set(p.axis) == expected

        ax2 = LinearAxis()
        expected.add(ax2)
        p.below.append(ax2)
        assert set(p.axis) == expected

        ax3 = LinearAxis()
        expected.add(ax3)
        p.left.append(ax3)
        assert set(p.axis) == expected

        ax4 = LinearAxis()
        expected.add(ax4)
        p.right.append(ax4)
        assert set(p.axis) == expected

    def test_log_axis(self):

0 Source : test_objects.py
with MIT License
from rthorst

def large_plot(n):
    from bokeh.models import (
        Plot, LinearAxis, Grid, GlyphRenderer,
        ColumnDataSource, DataRange1d, PanTool, ZoomInTool, ZoomOutTool, WheelZoomTool, BoxZoomTool,
        BoxSelectTool, SaveTool, ResetTool
    )
    from bokeh.models.layouts import Column
    from bokeh.models.glyphs import Line

    col = Column()
    objects = set([col])

    for i in xrange(n):
        source = ColumnDataSource(data=dict(x=[0, i + 1], y=[0, i + 1]))
        xdr = DataRange1d()
        ydr = DataRange1d()
        plot = Plot(x_range=xdr, y_range=ydr)
        xaxis = LinearAxis()
        plot.add_layout(xaxis, "below")
        yaxis = LinearAxis()
        plot.add_layout(yaxis, "left")
        xgrid = Grid(dimension=0)
        plot.add_layout(xgrid, "center")
        ygrid = Grid(dimension=1)
        plot.add_layout(ygrid, "center")
        tickers = [xaxis.ticker, xaxis.formatter, yaxis.ticker, yaxis.formatter]
        glyph = Line(x='x', y='y')
        renderer = GlyphRenderer(data_source=source, glyph=glyph)
        plot.renderers.append(renderer)
        pan = PanTool()
        zoom_in = ZoomInTool()
        zoom_out = ZoomOutTool()
        wheel_zoom = WheelZoomTool()
        box_zoom = BoxZoomTool()
        box_select = BoxSelectTool()
        save = SaveTool()
        reset = ResetTool()
        tools = [pan, zoom_in, zoom_out, wheel_zoom, box_zoom, box_select, save, reset]
        plot.add_tools(*tools)
        col.children.append(plot)
        objects |= set([
            xdr, ydr,
            xaxis, yaxis,
            xgrid, ygrid,
            renderer, renderer.view, glyph,
            source, source.selected, source.selection_policy,
            plot, plot.x_scale, plot.y_scale, plot.toolbar, plot.title,
            box_zoom.overlay, box_select.overlay,
        ] + tickers + tools)

    return col, objects


class TestMetaModel(object):

0 Source : widgets.py
with MIT License
from smartyal

    def build_second_y_axis(self):
        mi = self.server.get_mirror()
        if "hasY2Axis" in mi and mi["hasY2Axis"][".properties"]["value"]:
            self.hasY2 = True
            self.plot.extra_y_ranges = {"y2": Range1d(start=0, end=1)}
            self.y2Axis = LinearAxis(y_range_name="y2",
                                     axis_line_width=globalY2width*2,
                                     major_tick_line_width=globalY2width*2,
                                     minor_tick_line_width=globalY2width*2,
                                     major_tick_line_color = themes.darkTickColor,
                                     minor_tick_line_color = themes.darkTickColor,
                                     axis_line_color = themes.darkTickColor,
                                     #major_label_standoff = 10,
                                     major_label_text_align = "left",
                                     major_label_text_color = themes.darkTickColor,
                                     major_label_text_font_style = "bold",
                                     #major_label_text_font_size = "100%"
                                      )
            self.y2Axis.visible = True
            self.plot.add_layout(self.y2Axis, 'right')
            self.plot.min_border_right=50

            self.plot.yaxis.major_label_text_color = themes.darkTickColor
    def debug_button_2_cb(self):

0 Source : energy_env.py
with MIT License
from tsaoyu

def bokeh_simple_result_plot(result_df):
    C = ["#9b59b6", "#3498db", "#95a5a6", "#e74c3c", "#34495e", "#2ecc71"]
    fig = figure(plot_width=1400, plot_height=300, x_axis_type='datetime')
    fig.xaxis.axis_label = 'Date'
    fig.yaxis.axis_label = 'Power (generation / demand/ supply) W'
    fig.extra_y_ranges['SOC'] = Range1d(start=0, end=1)
    fig.extra_y_ranges['Reward'] = Range1d(start=-50, end=20)
    fig.add_layout(LinearAxis(y_range_name='SOC', axis_label='SOC'), 'right')
    fig.add_layout(LinearAxis(y_range_name='Reward', axis_label='Reward'), 'right')
    fig.line(result_df.index, result_df['Load_demand'], color=C[0],
             legend=['Demand'])
    fig.line(result_df.index, result_df['Supply'], color=C[1],
             legend=['Supply'])
    fig.line(result_df.index, result_df['Planned'], color=C[2],
             legend=['Planned'])
    fig.line(result_df.index,
             result_df['solar_power'] + result_df['wind_power'],
             color=C[5], legend=['Generation'])
    fig.line(result_df.index, result_df['SOC'], legend='SOC',
             y_range_name='SOC',
             color=C[3], alpha=0.5)
    fig.line(result_df.index, result_df['Reward'], legend='Reward',
             y_range_name='Reward',
             color=C[4], alpha=0.5)
    try:
        fig.title.text = result_df.name
    except  AttributeError:
        pass

    fig.legend.click_policy="hide"
    return fig


# def show_single_bokeh(task_name):
#     prepared_env = task_name + '.pkl'
#     with open(prepared_env, 'rb') as f:
#         env_pack = cloudpickle.load(f)
#     _, task_df, _ = env_pack
#     figs = []
#
#     history = pd.read_pickle('./running_0.pkl'.format(t=task_name))
#     history.name = 'Testing'
#     assembled_df = management_result_to_power_report(history, task_df)
#     figs.append(bokeh_simple_result_plot(assembled_df))
#
#     plot = column(figs)
#     html_output = file_html(plot, CDN, "Example plot")
#     with open('./{t}.html'.format(t=task_name), 'w') as f:
#         f.write(html_output)
#
#     show(plot)


class EnergyEnv(gym.Env):

0 Source : experimental.py
with MIT License
from uberdeveloper

def twin_plot(data, y_axis, x_axis="timestamp"):
    """
    Create a bokeh plot with twin axes
    """
    from bokeh.plotting import figure
    from bokeh.models import LinearAxis, Range1d

    TOOLTIPS = [("datetime", "@x{%F %H:%M}"), ("value", "$y{0.00}")]

    y1, y2 = y_axis[0], y_axis[1]
    h0 = data[y1].max()
    l0 = data[y1].min()
    h1 = data[y2].max()
    l1 = data[y2].min()
    p = figure(
        x_axis_type="datetime",
        y_range=(l0, h0),
        tooltips=TOOLTIPS,
        height=240,
        width=600,
    )
    p.line(data[x_axis].values, data[y1].values, color="red", legend=y1)
    p.extra_y_ranges = {"foo": Range1d(l1, h1)}
    p.line(data[x_axis], data[y2].values, color="blue", y_range_name="foo", legend=y2)
    p.add_layout(LinearAxis(y_range_name="foo", axis_label=y2), "left")
    p.hover.formatters = {"x": "datetime"}
    p.legend.location = "top_center"
    p.legend.click_policy = "hide"
    return p


def conditional(data, c1, c2, out=None):