예제 #1
0
def prediction_plot(data_prev, data_pred, target_col, date_col):
    """
    Creates a plotwith prediction and true values for 60 days ahead


    Args:
    data_prev: historic true values of variable
    data_pred: predictions of variable
    target_col: column from which data will be displayed in format (column name, name to display in hoover tool)
    data_col: coulmn with datetime data
    """

    data_prev.rename({"date_x": "date"}, axis=1, inplace=True)

    # function used to plot values supplied in per_million format, multiplying values by 37.9 to get real values
    data_prev[target_col[0]] = data_prev[target_col[0]] * 37.9
    data_pred[target_col[0]] = data_pred[target_col[0]] * 37.9

    # defining tooltips for hover tool and data source for bokeh to use
    source_prev = ColumnDataSource(data=data_prev)
    source_preds = ColumnDataSource(data=data_pred)

    # defining fgure, scaling enabled
    p = figure(plot_width=900,
               plot_height=400,
               x_axis_type="datetime",
               sizing_mode="scale_width")
    # historic line and it's hover tool
    historic = p.line(x="date",
                      y=target_col[0],
                      source=source_prev,
                      color="grey",
                      line_width=2,
                      legend_label="Dane historyczne")
    hover = HoverTool(tooltips=[(target_col[1], f"@{target_col[0]}" + "{0.0}")
                                ],
                      mode='vline',
                      point_policy='follow_mouse',
                      renderers=[historic])
    hover.formatters = {"@date": "datetime"}
    p.tools.append(hover)
    #  predictions line and it's hover tool
    pred = p.line(x="date",
                  y=target_col[0],
                  source=source_preds,
                  line_width=2,
                  color="#2422bb",
                  legend_label="Prognoza")
    hover1 = HoverTool(tooltips=[(target_col[1], f"@{target_col[0]}" + "{0.0}")
                                 ],
                       mode='vline',
                       point_policy='follow_mouse',
                       renderers=[pred])
    hover1.formatters = {"@date": "datetime"}
    p.tools.append(hover1)

    # creating hover tool

    p.legend.location = "top_left"
    return p
예제 #2
0
    def plot_time_series(data, fig, fig_size=[800, 350], title="", legend="", labels=["Date", ""],
                         linewidth=1, color="blue", linestyle="solid", alpha=1):

        fig.plot_width = fig_size[0]
        fig.plot_height = fig_size[1]

        source = ColumnDataSource()
        source.add(data.index, name="date")
        source.add(data.values, name="values")
        source.add(data.index.strftime("%Y-%m-%d %H:%M:%S"), "date_formatted")

        # create a line plot
        fig.line(source=source, x="date", y="values",
                 legend=legend, line_color=color, line_dash=linestyle, line_alpha=alpha, line_width=linewidth)

        fig.title.text = title
        fig.title.text_font = 'Helvetica'
        fig.title.text_font_size = '18px'
        fig.title.align = 'center'

        fig.legend.background_fill_alpha = 0.6
        fig.legend.label_text_font = 'Helvetica'
        fig.legend.location = 'bottom_right'

        fig.xaxis.axis_label = labels[0]
        fig.yaxis.axis_label = labels[1]

        hover = HoverTool(tooltips=[("Value: ", "@values"), ("Timestamp: ", "@date_formatted")])
        hover.formatters = {'Timestamp': "datetime"}
        fig.add_tools(hover)
        fig.toolbar_location = "above"

        return fig
예제 #3
0
def areaplot(p, source, data_cols, colormap, hovertool, xlabelname,
             x_axis_type, stacked, **kwargs):
    """Adds areaplot to figure p for each data_col."""

    # Add element to start and end of each x and y column for vertical lines at
    # end of areaplots:
    for key in source.keys():
        if key == "x":
            source[key] = [source[key][0]] + list(
                source[key]) + [source[key][-1]]
        else:
            source[key] = np.array([0] + list(source[key]) + [0])
    N_source = len(source[key])

    # Stack data if <stacked>=True:
    if stacked:
        baseline = np.zeros(N_source)
        for col in data_cols:
            source[col] = baseline + source[col]
            baseline = source[col]
        if "alpha" not in kwargs:
            kwargs["alpha"] = 1
    elif "alpha" not in kwargs:
        kwargs["alpha"] = 0.5

    # Add line (and optional scatter glyphs) to figure:
    for j, name, color in list(zip(range(len(data_cols)), data_cols,
                                   colormap))[::-1]:
        p.patch(x="x",
                y=str(name),
                legend=" " + str(name),
                source=source,
                color=color,
                **kwargs)

        glyph = p.line(
            x="x",
            y=str(name),
            legend=" " + str(name),
            source=source,
            color=color,
            alpha=0,
        )

        if hovertool and int(len(data_cols) / 2) == j:
            my_hover = HoverTool(mode="vline", renderers=[glyph])
            if x_axis_type == "datetime":
                my_hover.tooltips = [(xlabelname, "@x{%F}")
                                     ] + [(str(name), "@{%s}" % str(name))
                                          for name in data_cols[::-1]]
                my_hover.formatters = {"x": "datetime"}
            else:
                my_hover.tooltips = [
                    (xlabelname, "@x"),
                    (str(name), "@{%s}" % str(name)),
                ]
            p.add_tools(my_hover)

    return p
예제 #4
0
def plot_graph(timestamps, arrays_to_plot, array_labels, graph_title, save=True):
    """

        This is a utility function to plot out any set of NumPy arrays you pass into it using the Bokeh library.
        The precondition of this function is that the length of arrays_to_plot and array_labels are equal.

        This is because there be a 1:1 mapping of each entry of arrays_to_plot to array_labels such that:
            arrays_to_plot[n] has label array_labels[n]

        Another precondition of this function is that each of the arrays within arrays_to_plot also have the
        same length. This is each of them will share the same time axis.

        Args:
            timestamps: An array of timestamps for the race
            arrays_to_plot: An array of NumPy arrays to plot
            array_labels: An array of strings for the individual plot titles
            graph_title: A string that serves as the plot's main title
            save: Boolean flag to contorl whether to save an .html file

        Result:
            Produces a 3 x ceil(len(arrays_to_plot) / 3) plot
            If save is enabled, save html file

        """
    compress_constant = int(timestamps.shape[0] / 5000)

    for index, array in enumerate(arrays_to_plot):
        arrays_to_plot[index] = array[::compress_constant]

    figures = list()

    hover_tool = HoverTool()
    hover_tool.formatters = {"x": "datetime"}
    hover_tool.tooltips = [
        ("time", "$x"),
        ("data", "$y")
    ]

    for (index, data_array) in enumerate(arrays_to_plot):
        # create figures and put them in list
        figures.append(figure(title=array_labels[index], x_axis_label="Time (hr)",
                              y_axis_label=array_labels[index], x_axis_type="datetime"))

        # add line renderers to each figure
        figures[index].line(timestamps[::compress_constant] * 1000, data_array, line_color=Bokeh8[index],
                            line_width=2)

        figures[index].add_tools(hover_tool)

    grid = gridplot(figures, sizing_mode="scale_both",
                    ncols=3, plot_height=200, plot_width=300)

    if save:
        output_file(filename=graph_title + '.html', title=graph_title)

    show(grid)

    return
예제 #5
0
 def _create_hover(tooltips=[('date', '$x{%F}'), ('value', '@y{0.000}')],
                   formatters={'$x': 'datetime'},
                   mode='vline',
                   **kwargs):
     hover = HoverTool(**kwargs)
     hover.tooltips = tooltips
     hover.formatters = formatters
     hover.mode = mode
     return hover
def make_plot(df):
    #Make the plot, save on .HTML file
    fig = figure(x_axis_label='Date',
                 y_axis_label='Price',
                 x_axis_type='datetime',
                 plot_width=1024,
                 plot_height=768)
    #datetime
    formatted_date = []
    date = df['datetime'].tolist()
    for f in date:
        formatted_date.append(datetime.strptime(f, "%Y-%m-%d %H:%M:%S"))
    #Making the source
    source = ColumnDataSource(
        data={
            'price': df['daiusd_price'].tolist(),
            'date': formatted_date,
            'price_selling': df['daiusd_selling'].tolist(),
            'price_purchase': df['daiusd_purchase'].tolist()
        })
    #Drawing the lines
    fig.line(x='date',
             y='price',
             line_width=3,
             color='red',
             source=source,
             legend_label='DAI/USD price')
    fig.line(x='date',
             y='price_selling',
             line_width=3,
             color='blue',
             source=source,
             legend_label='DAI/USD selling price')
    fig.line(x='date',
             y='price_purchase',
             line_width=3,
             color='green',
             source=source,
             legend_label='DAI/USD purchase price')
    #Configuring hovers
    hover = HoverTool()
    hover.tooltips = [('DAI price', '$@{price}{%0.2f}'), ('Date', '@date{%F}'),
                      ('DAI selling price', '$@{price_selling}{%0.2f}'),
                      ('DAI purchase price', '$@{price_purchase}{%0.2f}')]
    hover.mode = 'vline'
    hover.formatters = {
        '@{price}': 'printf',
        '@date': 'datetime',
        '@{price_selling}': 'printf',
        '@{price_purchase}': 'printf'
    }
    #Quiting toolbar
    fig.toolbar_location = None
    #Adding hovers
    fig.add_tools(hover)
    #Save
    save(obj=fig, title='Dai price - Beta')
예제 #7
0
def fill_under_plot_stacked(data, target_col, date_col, span=500):
    """
    Creates a plot with two lines and fills spaces between them. Stacks values
    Data - dataframe with datta to use in plotting
    target_columns - columns to include on the plot. Date is always included as x axis values. Columns supplied in format:
    (column name,name to display on hover tool)
    span - how much data to view on the plot [negative indexed]
    """
    # calculating values of the higher plot
    data[target_col[0][0]] = data[target_col[0][0]] + data[target_col[1][0]]
    # defining data range
    data = data.iloc[-span:, :]
    # defining tooltips
    tooltips = [("Data", "@date{%F}"),
                (target_col[0][1], f"@{target_col[0][0]}" + "{0.0}"),
                (target_col[1][1], f"@{target_col[1][0]}" + "{0.0}")]
    # defining data source
    source = ColumnDataSource(data=data)

    # defining plot
    p = figure(plot_width=900,
               plot_height=400,
               x_axis_type="datetime",
               sizing_mode="scale_both")
    # plotting lines and areas
    line_1 = p.line(x="date",
                    y=target_col[0][0],
                    source=source,
                    color="grey",
                    line_width=2)
    line_2 = p.line(x="date",
                    y=target_col[1][0],
                    source=source,
                    line_width=2,
                    color="#2422bb")
    area_1 = p.varea(x="date",
                     y1=target_col[0][0],
                     y2=target_col[1][0],
                     fill_color='grey',
                     alpha=0.2,
                     source=source)
    area_2 = p.varea(x="date",
                     y1=0,
                     y2=target_col[1][0],
                     fill_color="#2422bb",
                     alpha=0.2,
                     source=source)
    # defining hover tools
    hover = HoverTool(tooltips=tooltips,
                      mode='vline',
                      point_policy='follow_mouse',
                      renderers=[line_1])
    hover.formatters = {"@date": "datetime"}
    p.tools.append(hover)
    return p
예제 #8
0
def pointplot(p, source, data_cols, colormap, hovertool, xlabelname,
              x_axis_type, **kwargs):
    """Adds pointplot to figure p for each data_col."""

    N_cols = len(data_cols)

    # Define marker for pointplot:
    if "marker" in kwargs:
        markers = [kwargs["marker"]] * N_cols
        del kwargs["marker"]
    else:
        marker = [
            "circle",
            "square",
            "triangle",
            "asterisk",
            "circle_x",
            "square_x",
            "inverted_triangle",
            "x",
            "circle_cross",
            "square_cross",
            "diamond",
            "cross",
        ]
        markers = marker * int(N_cols / 20 + 1)
        markers = markers[:N_cols]

    # Add scatter/point glyphs to figure:
    for name, color, marker in zip(data_cols, colormap, markers):

        glyph = p.scatter(x="x",
                          y=str(name),
                          legend=" " + str(name),
                          source=source,
                          color=color,
                          marker=marker,
                          **kwargs)
        if hovertool:
            my_hover = HoverTool(mode="vline", renderers=[glyph])
            if x_axis_type == "datetime":
                my_hover.tooltips = [
                    (xlabelname, "@x{%F}"),
                    (str(name), "@{%s}" % str(name)),
                ]
                my_hover.formatters = {"x": "datetime"}
            else:
                my_hover.tooltips = [
                    (xlabelname, "@x"),
                    (str(name), "@{%s}" % str(name)),
                ]
            p.add_tools(my_hover)

    return p
예제 #9
0
def bar_line_plot(data, target_col, date_col, span=500):
    """
    Creates a plot with bars and a line. Bars represent daily values, line represents 7 day rolling mean
    Data - dataframe with datta to use in plotting
    target_columns - columns to include on the plot. Date is always included as x axis values. Columns supplied in format:
    (column name,name to display on hover tool)
    date_col - column with dates
    span - variable used to restrict size of the plot. Number of days to display
    """

    # calculating rolling mean
    data["rolling_mean"] = data[target_col[0]].rolling(7).mean()

    # clipping data to have length equal to span supplied
    data = data.iloc[-span:, :]

    # defining tooltips
    tooltips = [("Data", "@date{%F}"),
                ((target_col[1], f"@{target_col[0]}" + "{0,0}")),
                ("Średnia 7-dniowa", '@rolling_mean{0,0}')]
    source = ColumnDataSource(data=data)

    # creating figure, enabling sizing plots to fit containers on site
    p = figure(plot_width=900,
               plot_height=400,
               x_axis_type="datetime",
               sizing_mode="scale_both")
    # creatin bars and line plot
    bars = p.vbar(x="date",
                  top=target_col[0],
                  source=source,
                  color="#2422bb",
                  alpha=0.5,
                  width=timedelta(days=1),
                  legend_label=target_col[1])
    line = p.line(x="date",
                  y="rolling_mean",
                  source=source,
                  line_width=2,
                  color="black",
                  legend_label="Średnia 7-dniowa")
    # creating hoover tool
    hover = HoverTool(tooltips=tooltips,
                      mode='vline',
                      point_policy='follow_mouse',
                      renderers=[line])
    hover.formatters = {
        "@date": "datetime"
    }  # specyfying datetime formater for date field in hoover tool
    p.tools.append(hover)
    # returning plot
    p.legend.location = "top_left"
    return p
예제 #10
0
def dash_line_plot(data, target_col, date_col, span=500):
    """
    Creates a plot with two lines. One follows daily changes of the parameter, second one follows 7 day rolling mean.
    target_columns - columns to include on the plot. Date must be always included as x axis values. Supplied in format: (column name,name to display on hover tool)
    span - variable used to restrict size of the plot. Number of days to display
    """
    # calculating the rolling mean
    data["rolling_mean"] = data[target_col[0]].rolling(7).mean()
    # clipping data to match span lenght
    data = data.iloc[-span:, :]

    # defining tooltips for hover tool and data source for bokeh to use
    tooltips = [("Data", "@date{%F}"),
                ((target_col[1], f"@{target_col[0]}" + "{0.0}")),
                ("Średnia 7-dniowa", '@rolling_mean' + "{0.0}")]
    source = ColumnDataSource(data=data)

    # defining fgure, scaling enabled
    p = figure(plot_width=900,
               plot_height=400,
               x_axis_type="datetime",
               sizing_mode="scale_width")
    # defining lines to display - dash line represents daily values, normaln line - rolling mean
    line_dash = p.line(x="date",
                       y=target_col[0],
                       source=source,
                       color="grey",
                       line_width=1,
                       alpha=0.6,
                       legend_label=target_col[1])
    line = p.line(x="date",
                  y="rolling_mean",
                  source=source,
                  line_width=2,
                  color="#2422bb",
                  legend_label="Średnia 7-dniowa")
    # plot often used to display values around zero - plotting horizontal line at zero
    hline = Span(location=0,
                 dimension='width',
                 line_color='black',
                 line_width=1)
    p.renderers.extend([hline])
    # creating hover tool
    hover = HoverTool(tooltips=tooltips,
                      mode='vline',
                      point_policy='follow_mouse',
                      renderers=[line])
    hover.formatters = {"@date": "datetime"}
    p.tools.append(hover)
    p.legend.location = "top_left"
    return p
예제 #11
0
    def AddToolTip(self, plot, tooltips, formatters = None):
        # Create a hover tool
        hover_tool = HoverTool()

        # Set the tooltips
        hover_tool.tooltips = tooltips

        # Formatter for dates
        hover_tool.formatters = formatters

        # Add the tooltip
        plot.add_tools(hover_tool)

        return hover_tool
예제 #12
0
def lineplot(p, source, data_cols, colormap, hovertool, xlabelname,
             x_axis_type, plot_data_points, plot_data_points_size, **kwargs):
    """Adds lineplot to figure p for each data_col."""

    if "marker" in kwargs:
        marker = kwargs["marker"]
        del kwargs["marker"]
    else:
        marker = "circle"

    # Add line (and optional scatter glyphs) to figure:
    for name, color in zip(data_cols, colormap):
        glyph = p.line(x="x",
                       y=str(name),
                       legend=" " + str(name),
                       source=source,
                       color=color,
                       **kwargs)

        if plot_data_points:
            p.scatter(
                x="x",
                y=str(name),
                legend=" " + str(name),
                source=source,
                color=color,
                marker=marker,
                size=plot_data_points_size,
            )

        if hovertool:
            my_hover = HoverTool(mode="vline", renderers=[glyph])
            if x_axis_type == "datetime":
                my_hover.tooltips = [
                    (xlabelname, "@x{%F}"),
                    (str(name), "@{%s}" % str(name)),
                ]
                my_hover.formatters = {"x": "datetime"}
            else:
                my_hover.tooltips = [
                    (xlabelname, "@x"),
                    (str(name), "@{%s}" % str(name)),
                ]
            p.add_tools(my_hover)

    return p
예제 #13
0
    def plot_2(self):
        group = self.valore

        temp = self.data().groupby(group).sum()[[
            "NA_Sales", "EU_Sales", "JP_Sales", "Other_Sales"
        ]]
        temp = temp.div(temp.sum(axis=1), axis=0)
        temp = temp.reset_index()
        temp[group] = temp[group].astype("str")

        fruits = temp[group].tolist()
        years = ["NA_Sales", "EU_Sales", "JP_Sales", "Other_Sales"]

        p = figure(
            x_range=fruits,
            plot_height=350,
            title="Sales percentage for each area of the world grouped by " +
            str(group),
            toolbar_location=None,
            tools="")

        p.vbar_stack(years,
                     x=group,
                     width=0.9,
                     source=temp,
                     legend_label=years,
                     color=Category20[11][2:6])

        hover = HoverTool()
        hover.tooltips = [("Zone", "$name"), ("Value", "@$name")]
        hover.formatters = {'Value': 'printf'}
        p.add_tools(hover)

        p.y_range.start = 0
        p.x_range.range_padding = 0.1
        p.xgrid.grid_line_color = None
        p.axis.minor_tick_line_color = None
        p.outline_line_color = None
        p.legend.location = "top_left"
        p.legend.orientation = "vertical"
        p.add_layout(p.legend[0], 'right')

        if group == "Publisher":
            p.xaxis.major_label_orientation = 45
            p.xaxis.axis_label_text_font_size = "2pt"
        return pn.pane.Bokeh(p)
예제 #14
0
        def SelectCountry(attr, old, new):
            now_selected = list(set(new) - set(old))
            was_selected = list(set(old) - set(new))

            if now_selected:
                country = checkboxes.labels[now_selected[0]]

                if country_data.glyph_dict[country] == None:
                    country_df = country_data.GetDataFrame(country)

                    if tail == True:
                        country_df = country_data.GetTail(
                            country, x_data, y_data, tail_threshold)

                    country_cds = ColumnDataSource(country_df)
                    country_data.glyph_dict[country] = plot.line(
                        x=x_data,
                        y=y_data,
                        source=country_cds,
                        name=country,
                        line_color=country_data.colour_dict[country],
                        line_width=1)

                    for tool in plot.tools:
                        if type(tool).__name__ == 'HoverTool':
                            plot.tools.remove(tool)

                    # Create a hover tool
                    hover_tool = HoverTool()

                    # Set the tooltips
                    hover_tool.tooltips = tooltips

                    # Formatter for dates
                    hover_tool.formatters = formatters

                    # Add the tooltip
                    plot.add_tools(hover_tool)

                country_data.glyph_dict[country].visible = True

            elif was_selected:
                country = checkboxes.labels[was_selected[0]]
                country_data.glyph_dict[country].visible = False
예제 #15
0
def createHoverTool(simg, cols):
    """
    """
    # Make the hovertool only follow the patches (still a hack)
    htline = simg

    ht = HoverTool()
    ht.tooltips = [("Time", "@index{%F %T}")]
    for col in cols:
        fStr = "@%s{0.00}" % (col)
        ht.tooltips.append((col, fStr))

    ht.formatters = {'index': 'datetime'}
    ht.show_arrow = False
    ht.point_policy = 'follow_mouse'
    ht.line_policy = 'nearest'
    ht.renderers = [htline]

    return ht
예제 #16
0
def fill_dotplot(plot,
                 source,
                 data_field,
                 tooltips=None,
                 tooltips_formatters=None,
                 js_tap_callback=None,
                 server_tap_callback=None,
                 lines=False,
                 lower_bound=False):
    '''
    General function for filling dotplots.
    Here are the possible parameters :

    tooltips: Bokeh Tooltip object to use for the plot
    tooltips_formatters: Formatter for the tooltip
    js_tap_callback: CustomJS object for client side click callback
    server_tap_callback: Callback object for server side click callback
    lines: Specify if lines should be drawn to connect the dots
    lower_bound: Specify if a lower bound interval should be displayed
    '''

    # (Optional) Tooltip and tooltip formatters
    if tooltips is not None:
        hover = HoverTool(tooltips=tooltips, mode="vline", names=["circle"])

        if tooltips_formatters is not None:
            hover.formatters = tooltips_formatters

        plot.add_tools(hover)

    # (Optional) Add TapTool (for JS tap callback)
    if js_tap_callback is not None:
        tap = TapTool(callback=CustomJS(code=js_tap_callback))
        plot.add_tools(tap)

    # (Optional) Add segment to represent a lower bound
    if lower_bound:
        lower_segment = plot.segment(x0="%s_x" % data_field,
                                     y0=data_field,
                                     x1="%s_x" % data_field,
                                     y1="%s_lower_bound" % data_field,
                                     source=source,
                                     line_color="black")

    # Draw dots (actually Bokeh circles)
    circle = plot.circle(name="circle",
                         x="%s_x" % data_field,
                         y=data_field,
                         source=source,
                         size=12)

    # (Optional) Draw lines between dots
    if lines:
        line = plot.line(x="%s_x" % data_field, y=data_field, source=source)

    # (Optional) Add server tap callback
    if server_tap_callback is not None:
        circle.data_source.selected.on_change("indices", server_tap_callback)

    # Plot appearance
    plot.xgrid.grid_line_color = None
    plot.ygrid.grid_line_color = None

    plot.yaxis[0].formatter.power_limit_high = 0
    plot.yaxis[0].formatter.power_limit_low = 0
    plot.yaxis[0].formatter.precision = 3

    plot.xaxis[0].major_label_orientation = pi / 8
예제 #17
0
def plot_multiple_lines(df: pd.DataFrame, title: str, x_axis: str, y_axis: str, category_column: str,
                        x_axis_type: str = 'datetime', **kwargs):
    """
    Cretes plot with multiple lines
    :param df:
    :param title:
    :param x_axis:
    :param y_axis:
    :param category_column:
    :param x_axis_type:
    :param kwargs:
    :return:
    """

    """ prepare data """
    if (x_axis in df.index.names) | (y_axis in df.index.names):
        df.reset_index(inplace=True)

    df[category_column] = df[category_column].apply(str)
    df_pivoted = df.pivot(index=x_axis, columns=category_column, values=y_axis)

    """ Multiple line chart """
    custom_hover = HoverTool()
    p = figure(x_axis_type=x_axis_type, title=title, plot_width=kwargs.get('plot_width', 800),
               plot_height=kwargs.get('plot_height', 400), tools=[custom_hover, 'save'])

    legend_list = []

    source = ColumnDataSource(df_pivoted)

    colours = create_multi_colour_pallete()
    if len(colours) < len(df[category_column].unique()):
        raise IndexError("""There are more categorical ({} categories) columns than there are colours ({} colours). 
                                Reduce categories or add more colours.""".format(str(len(df[category_column].unique())),
                                                                                 str(len(colours))))

    for ind, category_line in enumerate(df_pivoted.columns):
        line_g = p.line(
            x_axis,
            category_line,
            line_width=kwargs.get('line_width', 1),
            color=colours[ind],
            line_alpha=kwargs.get('line_alpha', 0.9),
            source=source
        )
        legend_list.append(LegendItem(label=category_line, renderers=[line_g], index=ind))

    """ hover tooltips """
    x_axis_default_format = '{%F, %A}' if x_axis_type == 'datetime' else ''
    tooltips = [(x_axis, "@" + x_axis + kwargs.get('x_tooltip_format', x_axis_default_format))] + \
               [("{} of {} {}".format(y_axis, category_column, y),
                 "@" + y + kwargs.get('y_tooltip_format', '{0,0}')) for y in df_pivoted.columns]

    custom_hover.tooltips = get_custom_hover_tooltips(tooltips)
    custom_hover.formatters = {x_axis: x_axis_type}

    """ legend """
    legend = Legend(items=legend_list, location=kwargs.get('legend_location', (10, 10)))
    p.add_layout(legend, kwargs.get('legend_placement', 'right'))

    """ axis """
    p.xaxis.axis_label = kwargs.get('x_axis_label', x_axis)
    p.yaxis.axis_label = kwargs.get('y_axis_label', y_axis)
    p = format_axis(p, **kwargs)
    p = format_grid(p, **kwargs)
    return p
예제 #18
0
dell_2_time = pandas.to_datetime(dell_2_con, unit='s')

juniper = result[(result.DeviceName == 'juniper') & (result.TypeId == 1234)]
juniper_up = juniper["UpBytes"]
juniper_down = juniper["DownBytes"]
juniperconv = juniper["StatTime"]
juniper_time = pandas.to_datetime(juniperconv, unit='s')

p.multi_line(xs = [juniper_time, juniper_time], ys = [juniper_up, juniper_down] color=['red', 'blue'] line_width=1, legend='juniper')
p.multi_line(xs = [cisco_time, cisco_time], ys = [cisco_up, cisco_down], color=['#EE0091','#2828B0'], line_width=1, legend='cisco')
p.multi_line(xs = [hp_time, hp_time], ys = [hp_up, hp_down], color=['yellow','green'], line_width=1, legend='cisco')
p.multi_line(xs = [cisco_time, cisco_time], ys = [cisco_up, cisco_down], color=['pink','black'], line_width=1, legend='cisco')
p.multi_line(xs = [cisco_time, cisco_time], ys = [cisco_up, cisco_down], color=['#498ABF','#2F00E1'], line_width=1, legend='cisco')

hover = HoverTool(tooltips = [('Time', '@x{int}'),
                            ('Value', '@y{1.11} GB'),
                            ('Device', '@DeviceName')])

hover.formatters = {"Date": "datetime"}
p.legend.label_text_font = "times"
p.legend.label_text_font_style = "italic"

p.grid.grid_line_alpha=0.5
p.xaxis.major_tick_line_width = 3
p.xaxis.minor_tick_line_color = "navy"

p.add_tools(hover)

output_file("plotting.html", title="Device_Reports")
show(p)
예제 #19
0
def fill_boxplot(plot,
                 source,
                 prefix="",
                 tooltips=None,
                 tooltips_formatters=None,
                 js_tap_callback=None,
                 server_tap_callback=None):
    '''
    General function for filling boxplots.
    Here are the possible parameters :

    prefix: specify which prefix to use for the name of data fields
    tooltips: Bokeh Tooltip object to use for the plot
    tooltips_formatters: Formatter for the tooltip
    js_tap_callback: CustomJS object for client side click callback
    server_tap_callback: Callback object for server side click callback
    '''

    # (Optional) Tooltip and tooltip formatters
    if tooltips is not None:
        hover = HoverTool(tooltips=tooltips, mode="vline", names=["full_box"])

        if tooltips_formatters is not None:
            hover.formatters = tooltips_formatters

        plot.add_tools(hover)

    # (Optional) Add TapTool (for JS tap callback)
    if js_tap_callback is not None:
        tap = TapTool(callback=CustomJS(code=js_tap_callback))
        plot.add_tools(tap)

    # Draw boxes (the prefix argument modifies the fields of ColumnDataSource
    # that are used)

    if prefix != "":
        prefix = "%s_" % prefix

    # Stems
    top_stem = plot.segment(x0="%sx" % prefix,
                            y0="%smax" % prefix,
                            x1="%sx" % prefix,
                            y1="%squantile75" % prefix,
                            source=source,
                            line_color="black")
    bottom_stem = plot.segment(x0="%sx" % prefix,
                               y0="%smin" % prefix,
                               x1="%sx" % prefix,
                               y1="%squantile25" % prefix,
                               source=source,
                               line_color="black")

    # Boxes
    full_box = plot.vbar(name="full_box",
                         x="%sx" % prefix,
                         width=0.5,
                         top="%squantile75" % prefix,
                         bottom="%squantile25" % prefix,
                         source=source,
                         line_color="black")
    bottom_box = plot.vbar(x="%sx" % prefix,
                           width=0.5,
                           top="%squantile50" % prefix,
                           bottom="%squantile25" % prefix,
                           source=source,
                           line_color="black")

    # Mu dot
    mu_dot = plot.dot(x="%sx" % prefix,
                      y="%smu" % prefix,
                      size=30,
                      source=source,
                      color="black")

    # (Optional) Add server tap callback
    if server_tap_callback is not None:
        top_stem.data_source.selected.on_change("indices", server_tap_callback)
        bottom_stem.data_source.selected.on_change("indices",
                                                   server_tap_callback)

        full_box.data_source.selected.on_change("indices", server_tap_callback)
        bottom_box.data_source.selected.on_change("indices",
                                                  server_tap_callback)

        mu_dot.data_source.selected.on_change("indices", server_tap_callback)

    # Plot appearance
    plot.xgrid.grid_line_color = None
    plot.ygrid.grid_line_color = None

    plot.yaxis[0].formatter.power_limit_high = 0
    plot.yaxis[0].formatter.power_limit_low = 0
    plot.yaxis[0].formatter.precision = 3

    plot.xaxis[0].major_label_orientation = pi / 8
예제 #20
0
def scatterplot(p, x, y, category, category_values, colormap, hovertool,
                x_axis_type, xlabelname, ylabelname, **kwargs):
    """Adds a scatterplot to figure p for each data_col."""

    # Set standard size and linecolor of markers:
    if "size" not in kwargs:
        kwargs["size"] = 10
    if "line_color" not in kwargs:
        kwargs["line_color"] = "black"

    # Define source:
    source = ColumnDataSource({"x": x, "y": y})

    # Define Colormapper for categorical scatterplot:
    if not category is None:

        category = str(category)
        source.data[category] = category_values

        # Make numerical categorical scatterplot:
        if check_type(category_values) == "numeric":

            kwargs["legend"] = category + " "

            # Define colormapper for numerical scatterplot:
            if colormap == None:
                colormap = Inferno256
            elif isinstance(colormap, str):
                if colormap in all_palettes:
                    colormap = all_palettes[colormap]
                    max_key = max(colormap.keys())
                    colormap = colormap[max_key]
                else:
                    raise ValueError(
                        "Could not find <colormap> with name %s. The following predefined colormaps are supported (see also https://bokeh.pydata.org/en/latest/docs/reference/palettes.html ): %s"
                        % (colormap, list(all_palettes.keys())))
            elif isinstance(colormap, (list, tuple)):
                pass
            else:
                raise ValueError(
                    "<colormap> can onyl be None, a name of a colorpalette as string( see https://bokeh.pydata.org/en/latest/docs/reference/palettes.html ) or a list/tuple of colors."
                )

            colormapper = LinearColorMapper(palette=colormap)

            # Set fill-color to colormapper:
            kwargs["fill_color"] = {
                "field": category,
                "transform": colormapper
            }

            # Define Colorbar:
            colorbar_options = {
                "color_mapper": colormapper,
                "label_standoff": 0,
                "border_line_color": None,
                "location": (0, 0),
            }
            colorbar = ColorBar(**colorbar_options)
            p.add_layout(colorbar, "right")

            # Draw glyph:
            glyph = p.scatter(x="x", y="y", source=source, **kwargs)

            # Add Hovertool
            if hovertool:
                my_hover = HoverTool(renderers=[glyph])
                if x_axis_type == "datetime":
                    my_hover.tooltips = [(xlabelname, "@x{%F}"),
                                         (ylabelname, "@y")]
                    my_hover.formatters = {"x": "datetime"}
                else:
                    my_hover.tooltips = [(xlabelname, "@x"),
                                         (ylabelname, "@y")]
                my_hover.tooltips.append((str(category), "@{%s}" % category))
                p.add_tools(my_hover)

        # Make categorical scatterplot:
        elif check_type(category_values) == "object":

            # Define colormapper for categorical scatterplot:
            labels, categories = pd.factorize(category_values)
            colormap = get_colormap(colormap, len(categories))

            # Draw each category as separate glyph:
            x, y = source.data["x"], source.data["y"]
            for cat, color in zip(categories, colormap):
                x_cat = x[category_values == cat]
                y_cat = y[category_values == cat]
                cat_cat = category_values[category_values == cat]
                source = ColumnDataSource({
                    "x": x_cat,
                    "y": y_cat,
                    "category": cat_cat
                })

                # Draw glyph:
                glyph = p.scatter(x="x",
                                  y="y",
                                  legend=str(cat) + " ",
                                  source=source,
                                  color=color,
                                  **kwargs)

                # Add Hovertool
                if hovertool:
                    my_hover = HoverTool(renderers=[glyph])
                    if x_axis_type == "datetime":
                        my_hover.tooltips = [(xlabelname, "@x{%F}"),
                                             (ylabelname, "@y")]
                        my_hover.formatters = {"x": "datetime"}
                    else:
                        my_hover.tooltips = [(xlabelname, "@x"),
                                             (ylabelname, "@y")]
                    my_hover.tooltips.append((str(category), "@category"))
                    p.add_tools(my_hover)

            if len(categories) > 5:
                warnings.warn(
                    "There are more than 5 categories in the scatterplot. The legend might be crowded, to hide the axis you can pass 'legend=False' as an optional argument."
                )

        else:
            raise ValueError(
                "<category> is not supported with datetime objects. Consider casting the datetime objects to strings, which can be used as <category> values."
            )

    # Draw non categorical plot:
    else:
        # Draw glyph:
        glyph = p.scatter(x="x", y="y", source=source, **kwargs)

        # Add Hovertool:
        if hovertool:
            my_hover = HoverTool(renderers=[glyph])
            if x_axis_type == "datetime":
                my_hover.tooltips = [(xlabelname, "@x{%F}"),
                                     (ylabelname, "@y")]
                my_hover.formatters = {"x": "datetime"}
            else:
                my_hover.tooltips = [(xlabelname, "@x"), (ylabelname, "@y")]
            p.add_tools(my_hover)

    return p
예제 #21
0
def assembly_chart(df, complements):
    """function to assembly the chart"""
    print('starting the plot...')

    # specify the output file name
    output_file("movigrama_chart.html")
    # force to show only one plot when multiples executions of the code occur
    # otherwise the plots will append each time one new calling is done
    reset_output()

    # create ColumnDataSource objects directly from Pandas data frames
    source = ColumnDataSource(df)

    # use the column DT as index
    df.set_index('DT', inplace=True)

    ###########################################################################
    #
    #  Movigrama Plot
    #
    ###########################################################################

    # build figure of the plot
    p = figure(x_axis_type='datetime',
               x_axis_label='days of moviment',
               y_axis_label='unities movimented',
               plot_width=1230,
               plot_height=500,
               active_scroll='wheel_zoom')

    # TODO Specify X range (not all plots have 365 days of moviment)

    # build the Stock Level bar
    r1 = p.vbar(x='DT',
                bottom=0,
                top='STOCK',
                width=pd.Timedelta(days=1),
                fill_alpha=0.4,
                color='paleturquoise',
                source=source)

    # build the OUT bar
    p.vbar(x='DT',
           bottom=0,
           top='SOMA_SAI',
           width=pd.Timedelta(days=1),
           fill_alpha=0.8,
           color='crimson',
           source=source)

    # build the IN bar
    p.vbar(x='DT',
           bottom=0,
           top='SOMA_ENTRA',
           width=pd.Timedelta(days=1),
           fill_alpha=0.8,
           color='seagreen',
           source=source)

    # edit title
    # adds warehouse title
    p.add_layout(
        Title(text=complements['warehouse'],
              text_font='helvetica',
              text_font_size='10pt',
              text_color='orangered',
              text_alpha=0.5,
              align='center',
              text_font_style="italic"), 'above')
    # adds product title
    p.add_layout(
        Title(text=complements['product'],
              text_font='helvetica',
              text_font_size='10pt',
              text_color='orangered',
              text_alpha=0.5,
              align='center',
              text_font_style="italic"), 'above')
    # adds main title
    p.add_layout(
        Title(text='Movigrama Endicon',
              text_font='helvetica',
              text_font_size='16pt',
              text_color='orangered',
              text_alpha=0.9,
              align='center',
              text_font_style="bold"), 'above')

    # adds horizontal line
    hline = Span(location=0,
                 line_alpha=0.4,
                 dimension='width',
                 line_color='gray',
                 line_width=3)
    p.renderers.extend([hline])

    # adapt the range to the plot
    p.x_range.range_padding = 0.1
    p.y_range.range_padding = 0.1

    # format the plot's outline
    p.outline_line_width = 4
    p.outline_line_alpha = 0.1
    p.outline_line_color = 'orangered'

    # format major labels
    p.axis.major_label_text_color = 'gray'
    p.axis.major_label_text_font_style = 'bold'

    # format labels
    p.axis.axis_label_text_color = 'gray'
    p.axis.axis_label_text_font_style = 'bold'

    #    p.xgrid.grid_line_color = None  # disable vertical bars
    #    p.ygrid.grid_line_color = None  # disable horizontal bars

    # change placement of minor and major ticks in the plot
    p.axis.major_tick_out = 10
    p.axis.minor_tick_in = -3
    p.axis.minor_tick_out = 6
    p.axis.minor_tick_line_color = 'gray'

    # format properly the X datetime axis
    p.xaxis.formatter = DatetimeTickFormatter(days=['%d/%m'],
                                              months=['%m/%Y'],
                                              years=['%Y'])

    # iniciate hover object
    hover = HoverTool()
    hover.mode = "vline"  # activate hover by vertical line
    hover.tooltips = [("SUM-IN", "@SOMA_ENTRA"), ("SUM-OUT", "@SOMA_SAI"),
                      ("COUNT-IN", "@TRANSACT_ENTRA"),
                      ("COUNT-OUT", "@TRANSACT_SAI"), ("STOCK", "@STOCK"),
                      ("DT", "@DT{%d/%m/%Y}")]
    # use 'datetime' formatter for 'DT' field
    hover.formatters = {"DT": 'datetime'}
    hover.renderers = [r1]  # display tolltip only to one render
    p.add_tools(hover)

    ###########################################################################
    #
    #  Demand analysis
    #
    ###########################################################################

    # change to positive values
    df['out_invert'] = df['SOMA_SAI'] * -1
    # moving average with n=30 days
    df['MA30'] = df['out_invert'].rolling(30).mean().round(0)
    # moving standard deviation with n=30 days
    df['MA30_std'] = df['out_invert'].rolling(30).std().round(0)
    # lower control limit for 1 sigma deviation
    df['lcl_1sigma'] = (df['MA30'] - df['MA30_std'])
    # upper control limit for 1 sigma deviation
    df['ucl_1sigma'] = (df['MA30'] + df['MA30_std'])

    source = ColumnDataSource(df)

    p1 = figure(plot_width=1230,
                plot_height=500,
                x_range=p.x_range,
                x_axis_type="datetime",
                active_scroll='wheel_zoom')

    # build the Sum_out bar
    r1 = p1.vbar(x='DT',
                 top='out_invert',
                 width=pd.Timedelta(days=1),
                 color='darkred',
                 line_color='salmon',
                 fill_alpha=0.4,
                 source=source)

    # build the moving average line
    p1.line(x='DT', y='MA30', source=source)

    # build the confidence interval
    band = Band(base='DT',
                lower='lcl_1sigma',
                upper='ucl_1sigma',
                source=source,
                level='underlay',
                fill_alpha=1.0,
                line_width=1,
                line_color='black')
    p1.renderers.extend([band])

    # adds title
    p1.add_layout(
        Title(text='Demand Variability',
              text_font='helvetica',
              text_font_size='16pt',
              text_color='orangered',
              text_alpha=0.5,
              align='center',
              text_font_style="bold"), 'above')

    # adds horizontal line
    hline = Span(location=0,
                 line_alpha=0.4,
                 dimension='width',
                 line_color='gray',
                 line_width=3)
    p1.renderers.extend([hline])

    # format the plot's outline
    p1.outline_line_width = 4
    p1.outline_line_alpha = 0.1
    p1.outline_line_color = 'orangered'

    # format major labels
    p1.axis.major_label_text_color = 'gray'
    p1.axis.major_label_text_font_style = 'bold'

    # format labels
    p1.axis.axis_label_text_color = 'gray'
    p1.axis.axis_label_text_font_style = 'bold'

    # change placement of minor and major ticks in the plot
    p1.axis.major_tick_out = 10
    p1.axis.minor_tick_in = -3
    p1.axis.minor_tick_out = 6
    p1.axis.minor_tick_line_color = 'gray'

    # format properly the X datetime axis
    p1.xaxis.formatter = DatetimeTickFormatter(days=['%d/%m'],
                                               months=['%m/%Y'],
                                               years=['%Y'])

    # iniciate hover object
    hover = HoverTool()
    hover.mode = "vline"  # activate hover by vertical line
    hover.tooltips = [("DEMAND", '@out_invert'), ("UCL 1σ", "@ucl_1sigma"),
                      ("LCL 1σ", "@lcl_1sigma"), ("M AVG 30d", "@MA30"),
                      ("DT", "@DT{%d/%m/%Y}")]
    # use 'datetime' formatter for 'DT' field
    hover.formatters = {"DT": 'datetime'}
    hover.renderers = [r1]  # display tolltip only to one render
    p1.add_tools(hover)

    ###########################################################################
    #
    #  Demand groupped by month
    #
    ###########################################################################

    resample_M = df.iloc[:, 0:6].resample('M').sum()  # resample to month
    # create column date as string
    resample_M['date'] = resample_M.index.strftime('%b/%y').values
    # moving average with n=3 months
    resample_M['MA3'] = resample_M['out_invert'].rolling(3).mean()

    resample_M['MA3'] = np.ceil(resample_M.MA3)  # round up the column MA3
    # resample to month with mean
    resample_M['mean'] = np.ceil(resample_M['out_invert'].mean())
    # resample to month with standard deviation
    resample_M['std'] = np.ceil(resample_M['out_invert'].std())
    # moving standard deviation with n=30 days
    resample_M['MA3_std'] = np.ceil(resample_M['out_invert'].rolling(3).std())
    # lower control limit for 1 sigma deviation
    resample_M['lcl_1sigma'] = resample_M['MA3'] - resample_M['MA3_std']
    # upper control limit for 1 sigma deviation
    resample_M['ucl_1sigma'] = resample_M['MA3'] + resample_M['MA3_std']

    source = ColumnDataSource(resample_M)

    p2 = figure(plot_width=1230,
                plot_height=500,
                x_range=FactorRange(factors=list(resample_M.date)),
                title='demand groupped by month')

    colors = factor_cmap('date',
                         palette=Category20_20,
                         factors=list(resample_M.date))

    p2.vbar(x='date',
            top='out_invert',
            width=0.8,
            fill_color=colors,
            fill_alpha=0.8,
            source=source,
            legend=value('OUT'))

    p2.line(x='date',
            y='MA3',
            color='red',
            line_width=3,
            line_dash='dotted',
            source=source,
            legend=value('MA3'))

    p2.line(x='date',
            y='mean',
            color='blue',
            line_width=3,
            line_dash='dotted',
            source=source,
            legend=value('mean'))

    band = Band(base='date',
                lower='lcl_1sigma',
                upper='ucl_1sigma',
                source=source,
                level='underlay',
                fill_alpha=1.0,
                line_width=1,
                line_color='black')

    labels1 = LabelSet(x='date',
                       y='MA3',
                       text='MA3',
                       level='glyph',
                       y_offset=5,
                       source=source,
                       render_mode='canvas',
                       text_font_size="8pt",
                       text_color='darkred')

    labels2 = LabelSet(x='date',
                       y='out_invert',
                       text='out_invert',
                       level='glyph',
                       y_offset=5,
                       source=source,
                       render_mode='canvas',
                       text_font_size="8pt",
                       text_color='gray')

    low_box = BoxAnnotation(
        top=resample_M['mean'].iloc[0] -
        resample_M['std'].iloc[0],  # analysis:ignore
        fill_alpha=0.1,
        fill_color='red')
    mid_box = BoxAnnotation(
        bottom=resample_M['mean'].iloc[0] -
        resample_M['std'].iloc[0],  # analysis:ignore
        top=resample_M['mean'].iloc[0] +
        resample_M['std'].iloc[0],  # analysis:ignore
        fill_alpha=0.1,
        fill_color='green')
    high_box = BoxAnnotation(
        bottom=resample_M['mean'].iloc[0] +
        resample_M['std'].iloc[0],  # analysis:ignore
        fill_alpha=0.1,
        fill_color='red')

    p2.renderers.extend([band, labels1, labels2, low_box, mid_box, high_box])
    p2.legend.click_policy = "hide"
    p2.legend.background_fill_alpha = 0.4

    p2.add_layout(
        Title(text='Demand Grouped by Month',
              text_font='helvetica',
              text_font_size='16pt',
              text_color='orangered',
              text_alpha=0.5,
              align='center',
              text_font_style="bold"), 'above')

    # adds horizontal line
    hline = Span(location=0,
                 line_alpha=0.4,
                 dimension='width',
                 line_color='gray',
                 line_width=3)
    p2.renderers.extend([hline])

    # format the plot's outline
    p2.outline_line_width = 4
    p2.outline_line_alpha = 0.1
    p2.outline_line_color = 'orangered'

    # format major labels
    p2.axis.major_label_text_color = 'gray'
    p2.axis.major_label_text_font_style = 'bold'

    # format labels
    p2.axis.axis_label_text_color = 'gray'
    p2.axis.axis_label_text_font_style = 'bold'

    # change placement of minor and major ticks in the plot
    p2.axis.major_tick_out = 10
    p2.axis.minor_tick_in = -3
    p2.axis.minor_tick_out = 6
    p2.axis.minor_tick_line_color = 'gray'

    # iniciate hover object
    # TODO develop hoverTool
    #    hover = HoverTool()
    #    hover.mode = "vline"  # activate hover by vertical line
    #    hover.tooltips = [("SUM-IN", "@SOMA_ENTRA"),
    #                      ("SUM-OUT", "@SOMA_SAI"),
    #                      ("COUNT-IN", "@TRANSACT_ENTRA"),
    #                      ("COUNT-OUT", "@TRANSACT_SAI"),
    #                      ("STOCK", "@STOCK")]
    #    hover.renderers = [r1]  # display tolltip only to one render
    #    p2.add_tools(hover)

    ###########################################################################
    #
    #  Plot figures
    #
    ###########################################################################

    # put the results in a column and show
    show(column(p, p1, p2))

    # show(p)  # plot action

    print('plot finished')
예제 #22
0
def plot_single_line(df: pd.DataFrame, x_axis: str, y_axis: str, title: str, x_axis_type: str = 'datetime',
                     colour_name: str = 'blue', colour_code: str = '500', md_design_colour: bool = True,
                     show_legend: bool = False, **kwargs) -> figure:
    """
    Creates a single line Bokeh chart

    :param df: dataframe with the x and y values
    :param x_axis: column name in df used for the x axis
    :param y_axis: column name in df used for the y axis
    :param title: title for figure
    :param x_axis_type: if axis type is datetime or linear (default: datetime)
    :param colour_name: colour name used by material design
    :param colour_code: colour code used by material desgin
    :param md_design_colour: if we should use Material Design's colours, otherwise a hex code can be passed in line_colour
    :param show_legend: if legend should be shown
    :param kwargs: extra information that can be passed
    :return: Bokehfigure with line chart
    """
    """ prepare data """
    if (x_axis in df.index.names) | (y_axis in df.index.names):
        df.reset_index(inplace=True)

    if x_axis_type == 'datetime':
        df = df.sort_values(x_axis, ascending=True)

    source = ColumnDataSource(df)

    """ line plot """
    custom_hover = HoverTool()

    p = figure(x_axis_type=x_axis_type, title=title, plot_width=kwargs.get('plot_width', 700),
               plot_height=kwargs.get('plot_height', 350), tools=[custom_hover, 'save'])

    if md_design_colour:
        line_colour = get_colour_hex_code(
            colour_name,
            colour_code
        )
    else:
        line_colour = kwargs.get('line_colour', '#2196f3')

    line_chart = p.line(x_axis, y_axis, line_width=kwargs.get('line_width', 1), color=line_colour, source=source)

    """ hover tooltips """
    x_axis_default_format = "{%F, %A}" if x_axis_type == 'datetime' else ''
    tooltips = [(x_axis, "@" + x_axis + kwargs.get('x_tooltip_format', x_axis_default_format)),
                (y_axis, "@" + y_axis + kwargs.get('y_tooltip_format', '{0,0}'))]
    custom_hover.tooltips = get_custom_hover_tooltips(tooltips)
    custom_hover.formatters = {x_axis: x_axis_type}
    p.add_tools(custom_hover)

    """ legend """
    if show_legend:
        legend = Legend(
            items=[LegendItem(label=kwargs.get('y_axis_label', y_axis), renderers=[line_chart], index=0)],
            location=kwargs.get('legend_location', (10, 10))
        )

        p.add_layout(legend, kwargs.get('legend_placement', 'below'))

    """ axis """
    p.xaxis.axis_label = kwargs.get('x_axis_label', x_axis)
    p.yaxis.axis_label = kwargs.get('y_axis_label', y_axis)
    p = format_axis(p, **kwargs)
    p = format_grid(p, **kwargs)

    return p
예제 #23
0
def fill_dotplot(plot,
                 source,
                 data_field,
                 tooltips=None,
                 tooltips_formatters=None,
                 js_tap_callback=None,
                 server_tap_callback=None,
                 lines=False,
                 lower_bound=False,
                 second_series=None,
                 legend=None,
                 second_legend=None,
                 custom_colors="#1f77b4"):
    '''
    General function for filling dotplots.
    Here are the possible parameters :

    tooltips: Bokeh Tooltip object to use for the plot
    tooltips_formatters: Formatter for the tooltip
    js_tap_callback: CustomJS object for client side click callback
    server_tap_callback: Callback object for server side click callback
    lines: Specify if lines should be drawn to connect the dots
    lower_bound: Specify if a lower bound interval should be displayed
    second_series: Name of a second data series to plot on the same figure. It
    should also have its own x series with the "_x" prefix.
    legend: lengend for the first data series
    second_legend: same for the second optional data series
    custom_colors: Will plot additional glyphs with a custom color (to display
    check errors for instance). Should be the name of the series of colors.
    '''

    # (Optional) Tooltip and tooltip formatters
    if tooltips is not None:
        hover = HoverTool(tooltips=tooltips, mode="vline", names=["circle"])

        if tooltips_formatters is not None:
            hover.formatters = tooltips_formatters

        plot.add_tools(hover)

    # (Optional) Add TapTool (for JS tap callback)
    if js_tap_callback is not None:
        tap = TapTool(callback=CustomJS(code=js_tap_callback))
        plot.add_tools(tap)

    # (Optional) Add segment to represent a lower bound
    if lower_bound:
        lower_segment = plot.segment(x0="%s_x" % data_field,
                                     y0=data_field,
                                     x1="%s_x" % data_field,
                                     y1="%s_lower_bound" % data_field,
                                     source=source,
                                     line_color="black")

    # (Optional) Draw a second data series
    if second_series is not None:
        if second_legend is not None:
            second_circle = plot.circle(name="second_circle",
                                        x="%s_x" % data_field,
                                        y=second_series,
                                        source=source,
                                        size=12,
                                        fill_color="gray",
                                        line_color="gray",
                                        legend_label=second_legend)
        else:
            second_circle = plot.circle(
                name="second_circle",
                x="%s_x" % data_field,
                y=second_series,
                source=source,
                size=12,
                fill_color="gray",
                line_color="gray",
            )

        if lines:
            second_line = plot.line(x="%s_x" % data_field,
                                    y=second_series,
                                    source=source,
                                    color="gray",
                                    line_dash="dashed")

    # (Optional) Draw lines between dots
    if lines:
        line = plot.line(x="%s_x" % data_field, y=data_field, source=source)

    # Draw dots (actually Bokeh circles)
    if legend is not None:
        circle = plot.circle(name="circle",
                             x="%s_x" % data_field,
                             y=data_field,
                             source=source,
                             size=12,
                             fill_color=custom_colors,
                             line_color=custom_colors,
                             legend_label=legend)
    else:
        circle = plot.circle(name="circle",
                             x="%s_x" % data_field,
                             y=data_field,
                             source=source,
                             size=12,
                             fill_color=custom_colors,
                             line_color=custom_colors)

    # (Optional) Add server tap callback
    if server_tap_callback is not None:
        circle.data_source.selected.on_change("indices", server_tap_callback)

    # Plot appearance
    plot.xgrid.grid_line_color = None
    plot.ygrid.grid_line_color = None

    plot.yaxis[0].formatter.power_limit_high = 0
    plot.yaxis[0].formatter.power_limit_low = 0
    plot.yaxis[0].formatter.precision = 3

    plot.xaxis[0].major_label_orientation = pi / 8
예제 #24
0
from bokeh.models.widgets import Slider, RangeSlider, CheckboxGroup, Button, TextInput, Paragraph
from bokeh.models.widgets import Panel, Tabs
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn
import sys
import waveform

from participant import participant
from xlrd import open_workbook
import os
import glob

# Hover tool definitions
hover = HoverTool(tooltips=[('Time', '@index{%H:%M:%S:%3Nms}'),
                            ('index', '$index')],
                  mode='vline')
hover.formatters = {'index': 'datetime'}

vs_hover = HoverTool(tooltips=[('Time', '@DateTime{%Y-%m-%d-%H:%M}'),
                               ('index', '$index')],
                     mode='vline')
vs_hover.formatters = {'DateTime': 'datetime'}

dt_axis_format = ["%d-%m-%Y %H:%M"]
vs_x_axis = DatetimeTickFormatter(
    hours=dt_axis_format,
    days=dt_axis_format,
    months=dt_axis_format,
    years=dt_axis_format,
)

wf_classes = [
예제 #25
0
def plot(
        df_in,
        x=None,
        y=None,
        kind="line",
        figsize=None,
        use_index=True,
        title="",
        grid=None,  # TODO:
        legend="top_right",
        logx=False,
        logy=False,
        xlabel=None,
        ylabel=None,
        xticks=None,
        yticks=None,
        xlim=None,
        ylim=None,
        fontsize=None,  # TODO:
        color=None,
        colormap=None,
        category=None,
        histogram_type="topontop",
        stacked=False,
        weights=None,
        bins=None,
        normed=False,
        cumulative=False,
        show_average=False,
        plot_data_points=False,
        plot_data_points_size=5,
        show_figure=True,
        return_html=False,
        panning=True,
        zooming=True,
        toolbar_location="right",
        hovertool=True,
        vertical_xlabel=False,
        webgl=True,
        **kwargs):
    # TODO: Make docstring
    """Method for creating a interactive with 'Bokeh' as plotting backend. Available
    plot kinds are:

    * line
    * point
    * scatter
    * bar
    * histogram

    Examples
    --------
    >>> df.plot_bokeh.line()
    >>> df.plot_bokeh.scatter(x='x',y='y')
    
    These plotting methods can also be accessed by calling the accessor as a
    method with the ``kind`` argument:
    ``df.plot_bokeh(kind='line')`` is equivalent to ``df.plot_bokeh.line()``

    For more informations about the individual plot kind implementations, have a
    look at the underlying methods (like df.plot_bokeh.line) or visit
    https://github.com/PatrikHlobil/Pandas-Bokeh. 
    
    """

    # Make a local copy of the DataFrame:
    df = df_in.copy()
    if isinstance(df, pd.Series):
        df = pd.DataFrame(df)

    # Get and check options for base figure:
    figure_options = {
        "title": title,
        "toolbar_location": toolbar_location,
        "active_scroll": "wheel_zoom",
        "plot_width": 600,
        "plot_height": 400,
        "output_backend": "webgl",
    }
    if not figsize is None:
        width, height = figsize
        figure_options["plot_width"] = width
        figure_options["plot_height"] = height
    if logx:
        figure_options["x_axis_type"] = "log"
    if logy:
        figure_options["y_axis_type"] = "log"
    if not xlabel is None:
        figure_options["x_axis_label"] = xlabel
    if not ylabel is None:
        figure_options["y_axis_label"] = ylabel
    if not xlim is None:
        if not isinstance(xlim, (tuple, list)):
            raise ValueError(
                "<xlim> must be a list/tuple of form (x_min, x_max).")
        elif len(xlim) != 2:
            raise ValueError(
                "<xlim> must be a list/tuple of form (x_min, x_max).")
        else:
            figure_options["x_range"] = xlim
    if not ylim is None:
        if not isinstance(ylim, (tuple, list)):
            raise ValueError(
                "<ylim> must be a list/tuple of form (y_min, y_max).")
        elif len(ylim) != 2:
            raise ValueError(
                "<ylim> must be a list/tuple of form (y_min, y_max).")
        else:
            figure_options["y_range"] = ylim
    if webgl:
        figure_options["output_backend"] = "webgl"

    # Set standard linewidth:
    if "line_width" not in kwargs:
        kwargs["line_width"] = 2

    # Get x-axis Name and Values:
    delete_in_y = None
    if not x is None:
        if x in df.columns:
            delete_in_y = x
            name = str(x)
            x = df[x].values
        elif isinstance(x, (tuple, list, type(np.array))):
            if len(x) == len(df):
                x = x
                name = ""
            else:
                raise Exception(
                    "Length of provided <x> argument does not fit length of DataFrame or Series."
                )
        else:
            raise Exception(
                "Please provide for the <x> parameter either a column name of the DataFrame/Series or an array of the same length."
            )
    else:
        if use_index:
            x = df.index.values
            if not df.index.name is None:
                name = str(df.index.name)
            else:
                name = ""
        else:
            x = np.linspace(0, len(df) - 1, len(df))
            name = ""

    if "x_axis_label" not in figure_options and not name is None:
        figure_options["x_axis_label"] = name

    # Check type of x-axis:
    if check_type(x) == "datetime":
        figure_options["x_axis_type"] = "datetime"
        xaxis_type = "datetime"
        if not xlim is None:
            starttime, endtime = xlim
            try:
                starttime = pd.to_datetime(starttime)
            except:
                raise ValueError(
                    "Could not parse x_min input of <xlim> as datetime.")
            try:
                endtime = pd.to_datetime(endtime)
            except:
                raise ValueError(
                    "Could not parse x_max input of <xlim> as datetime.")
            figure_options["x_range"] = (starttime, endtime)

    elif check_type(x) == "numeric":
        xaxis_type = "numerical"
    else:
        xaxis_type = "categorical"

    if kind == "bar":
        xaxis_type = "categorical"

    if xaxis_type == "categorical":
        x = [str(el) for el in x]
        if kind != "hist":
            figure_options["x_range"] = x
        if "x_axis_type" in figure_options:
            del figure_options["x_axis_type"]

    # Determine data cols to plot (only plot numeric data):
    if y is None:
        cols = df.columns
    elif not isinstance(y, (list, tuple)):
        cols = [y]
    else:
        cols = y
    data_cols = []
    for i, col in enumerate(cols):
        if col not in df.columns:
            raise Exception(
                "Could not find '%s' in the columns of the provided DataFrame/Series. Please provide for the <y> parameter either a column name of the DataFrame/Series or an array of the same length."
                % col)
        if np.issubdtype(df[col].dtype, np.number):
            data_cols.append(col)
    N_cols = len(data_cols)
    if N_cols == 0:
        raise Exception("No numeric data columns found for plotting.")

    # Delete x column if it appears in y columns:
    if not delete_in_y is None:
        if delete_in_y in data_cols:
            data_cols.remove(delete_in_y)

    # Create Figure for plotting:
    p = figure(**figure_options)
    if "x_axis_type" not in figure_options:
        figure_options["x_axis_type"] = None

    # Define xlabel name as "x" if no label is provided by user or data:
    xlabelname = (figure_options["x_axis_label"]
                  if figure_options["x_axis_label"] != "" else "x")

    # Define ColumnDataSource for Plot if kind != "hist":
    if kind != "hist":
        source = {str(col): df[col].values for col in data_cols}
        source["x"] = x

    # Define colormap
    if kind != "scatter":
        colormap = get_colormap(colormap, N_cols)

    if not color is None:
        colormap = get_colormap([color], N_cols)

    # Add Glyphs to Plot:
    if kind == "line":
        p = lineplot(p, source, data_cols, colormap, hovertool, xlabelname,
                     figure_options["x_axis_type"], plot_data_points,
                     plot_data_points_size, **kwargs)

    if kind == "point":
        p = pointplot(p, source, data_cols, colormap, hovertool, xlabelname,
                      figure_options["x_axis_type"], **kwargs)

    if kind == "scatter":

        if N_cols > 2:
            raise Exception(
                "For scatterplots <x> and <y> values can only be a single column of the DataFrame, not a list of columns. Please specify both <x> and <y> columns for a scatterplot uniquely."
            )

        # Get and set y-labelname:
        y_column = data_cols[0]
        if "y_axis_label" not in figure_options:
            p.yaxis.axis_label = str(y_column)

        # Get values for y-axis:
        y = df[y_column].values

        # Get values for categorical colormap:
        category_values = None
        if category in df.columns:
            category_values = df[category].values
        elif not category is None:
            raise Exception(
                "<category> parameter has to be either None or the name of a single column of the DataFrame"
            )

        scatterplot(p,
                    x,
                    y,
                    category,
                    category_values,
                    colormap,
                    hovertool,
                    x_axis_type=figure_options["x_axis_type"],
                    xlabelname=xlabelname,
                    ylabelname=str(y_column),
                    **kwargs)

    if kind == "bar":

        # Define data source for barplot:
        data = {str(col): df[col].values for col in data_cols}
        data["x"] = x
        source = ColumnDataSource(data)

        # Create Figure (just for categorical barplots):
        figure_options["x_range"] = x
        del figure_options["x_axis_type"]
        p = figure(**figure_options)
        figure_options["x_axis_type"] = None

        if N_cols >= 3:
            base_width = 0.5
        else:
            base_width = 0.35
        width = base_width / (N_cols - 0.5)
        if N_cols == 1:
            shifts = [0]
        else:
            delta_shift = base_width / (N_cols - 1)
            shifts = [-base_width / 2 + i * delta_shift for i in range(N_cols)]

        for i, name, color, shift in zip(range(N_cols), data_cols, colormap,
                                         shifts):
            glyph = p.vbar(x=dodge("x", shift, range=p.x_range),
                           top=str(name),
                           width=width,
                           source=source,
                           color=color,
                           legend=" " + str(name),
                           **kwargs)

            if hovertool:
                my_hover = HoverTool(mode="vline", renderers=[glyph])
                if figure_options["x_axis_type"] == "datetime":
                    my_hover.tooltips = [
                        (xlabelname, "@x{%F}"),
                        (str(name), "@{%s}" % str(name)),
                    ]
                    my_hover.formatters = {"x": "datetime"}
                else:
                    my_hover.tooltips = [
                        (xlabelname, "@x"),
                        (str(name), "@{%s}" % str(name)),
                    ]
                p.add_tools(my_hover)

    if kind == "hist":

        # Check for stacked keyword:
        if stacked and histogram_type != "stacked":
            warnings.warn(
                "<histogram_type> was set to '%s', but was overriden by <stacked>=True parameter."
                % histogram_type)
            histogram_type = "stacked"

        # Set xlabel if only one y-column is given and user does not override this via
        # xlabel parameter:
        if len(data_cols) == 1 and xlabel is None:
            p.xaxis.axis_label = data_cols[0]

        # If Histogram should be plotted, calculate bins, aggregates and
        # averages:
        if bins is None:
            values = df[data_cols].values
            values = values[~np.isnan(values)]
            data, bins = np.histogram(values)

        if not weights is None:
            if weights not in df.columns:
                raise ValueError(
                    "Columns '%s' for <weights> is not in provided DataFrame.")
            else:
                weights = df[weights].values

        aggregates = []
        averages = []
        for col in data_cols:
            values = df[col].values
            if not weights is None:
                not_nan = ~(np.isnan(values) | np.isnan(weights))
                values_not_nan = values[not_nan]
                weights_not_nan = weights[not_nan]
                if sum(not_nan) < len(not_nan):
                    warnings.warn(
                        "There are NaN values in column '%s' or in the <weights> column. For the histogram, these rows have been neglected."
                        % col,
                        Warning,
                    )
            else:
                not_nan = ~np.isnan(values)
                values_not_nan = values[not_nan]
                weights_not_nan = None
                if sum(not_nan) < len(not_nan):
                    warnings.warn(
                        "There are NaN values in column '%s'. For the histogram, these rows have been neglected."
                        % col,
                        Warning,
                    )

            average = np.average(values_not_nan, weights=weights_not_nan)
            averages.append(average)

            data, bins = np.histogram(values_not_nan,
                                      bins=bins,
                                      weights=weights_not_nan)
            if normed:
                data = data / np.sum(data) * normed
            if cumulative:
                data = np.cumsum(data)
            aggregates.append(data)

        p = histogram(p, data_cols, colormap, aggregates, bins, averages,
                      hovertool, normed, cumulative, show_average,
                      histogram_type, **kwargs)

    if kind == "area":

        p = areaplot(p, source, data_cols, colormap, hovertool, xlabelname,
                     figure_options["x_axis_type"], stacked, **kwargs)

    # Set xticks:
    if not xticks is None:
        p.xaxis[0].ticker = list(xticks)
    elif xaxis_type == "numerical" and kind not in ["hist", "scatter"]:
        p.xaxis.ticker = x
    if not yticks is None:
        p.yaxis.ticker = yticks

    # Format datetime ticks correctly:
    if figure_options["x_axis_type"] == "datetime":
        p.xaxis.formatter = DatetimeTickFormatter(
            milliseconds=["%H:%M:%S.%f"],
            seconds=["%H:%M:%S"],
            minutes=["%H:%M:%S"],
            hours=["%H:%M:%S"],
            days=["%d %B %Y"],
            months=["%d %B %Y"],
            years=["%d %B %Y"],
        )

    # Rotate xlabel if wanted:
    if vertical_xlabel:
        p.xaxis.major_label_orientation = np.pi / 2

    # Set click policy for legend:
    if not (kind == "area" and stacked):
        p.legend.click_policy = "hide"

    # Hide legend if wanted:
    if not legend:
        p.legend.visible = False
    # Modify legend position:
    else:
        if legend is True:
            p.legend.location = "top_right"
        elif legend in [
                "top_left",
                "top_center",
                "top_right",
                "center_left",
                "center",
                "center_right",
                "bottom_left",
                "bottom_center",
                "bottom_right",
        ]:
            p.legend.location = legend
        else:
            raise ValueError(
                "Legend can only be True/False or one of 'top_left', 'top_center', 'top_right', 'center_left', 'center', 'center_right', 'bottom_left', 'bottom_center', 'bottom_right'"
            )

    # Display plot if wanted
    if show_figure:
        show(p)

    # Return as (embeddable) HTML if wanted:
    if return_html:
        return embedded_html(p)

    # Return plot:
    return p
예제 #26
0
def fill_barplot(
    plot,
    source,
    single_series=None,
    double_series=None,
    tooltips=None,
    tooltips_formatters=None,
    js_tap_callback=None,
    server_tap_callback=None,
):
    '''
    General function for filling barplots.
    Here are the possible parameters :

    single_series: Series that display one value at each x (string)
    double_series: Series that display two values at each x (list of strings, size 2)
    columns: Array of columns to display. Size should be coherent with "check_mode".
    legend: Array of texts to put in the legend. This should be specified when
    plotting more than one culum, and its size should be coherent with "check_mode".
    tooltips: Bokeh Tooltip object to use for the plot
    tooltips_formatters: Formatter for the tooltip
    js_tap_callback: CustomJS object for client side click callback
    server_tap_callback: Callback object for server side click callback
    '''

    vbars = []
    vbars_names = []

    # Draw "single" vbar
    if single_series is not None:
        vbar = plot.vbar(name="vbar",
                         x="x",
                         width=0.5,
                         top=single_series,
                         source=source)

        vbars.append(vbar)
        vbars_names.append("vbar")

    # Draw "double" vbars
    if double_series is not None:
        vbar1 = plot.vbar(name="vbar1",
                          x=dodge("x", -0.15, range=plot.x_range),
                          width=0.25,
                          top=double_series[0],
                          source=source)

        vbar2 = plot.vbar(name="vbar2",
                          x=dodge("x", 0.15, range=plot.x_range),
                          width=0.25,
                          top=double_series[1],
                          source=source,
                          line_color="gray",
                          fill_color="gray")

        vbars.append(vbar1)
        vbars.append(vbar2)
        vbars_names.append("vbar1")
        vbars_names.append("vbar2")

    # (Optional) Tooltip and tooltip formatters
    if tooltips is not None:
        hover = HoverTool(tooltips=tooltips, mode="vline", names=vbars_names)

        if tooltips_formatters is not None:
            hover.formatters = tooltips_formatters

        plot.add_tools(hover)

    # (Optional) Add server tap callback
    if server_tap_callback is not None:
        for vbar in vbars:
            vbar.data_source.selected.on_change("indices", server_tap_callback)

    # Plot appearance
    plot.xgrid.grid_line_color = None
    plot.ygrid.grid_line_color = None

    plot.yaxis[0].formatter.power_limit_high = 0
    plot.yaxis[0].formatter.power_limit_low = 0
    plot.yaxis[0].formatter.precision = 3

    plot.xaxis[0].major_label_orientation = pi / 8
예제 #27
0
def make_cluster_plot(plot_data, pod, recs):

    # get x, y coordinates for pod and recs
    main_pod = pod.merge(plot_data, on=["title", "itunes_id", "genre", "subgenre"])
    recs = recs.merge(plot_data, on=["title", "itunes_id", "genre", "subgenre"])

    genre_list = list(plot_data.groupby(by="genre").groups.keys())
    show_list = recs["genre"].unique()

    p = figure(tools="wheel_zoom,pan,box_zoom,reset,tap",\
        plot_width=700, plot_height=500,\
        toolbar_location="right")
    p.toolbar.active_drag = None # disabling pan helps with scrolling on smartphones

    # plot all data points and group them by genres for the legends
    group = dict()
    legend_items = []
    for i, g in enumerate(genre_list):
        source = ColumnDataSource(plot_data.loc[plot_data["genre"] == g])
        group[g] = p.circle(x='x', y='y', size = 10,\
            color = Category20[19][-(i+1)],\
            fill_alpha=0.5,\
            line_alpha=0, muted_color="lightgray",\
            source = source, muted_alpha = 0.05)
        legend_items.append((g,[group[g]]))
        if g not in show_list: # only show genres that are in the recommendations
            group[g].muted = True

    # plot the main podcast
    p.image_url(url="artwork_url", x="x", y="y", w=50, h = 50, \
        anchor="center", global_alpha = 0.8, \
        h_units = "screen", w_units = "screen",\
        source = ColumnDataSource(main_pod))
    p.rect(main_pod['x'], main_pod['y'], width = 52, height = 52, \
        line_width = 3, height_units="screen", width_units="screen", \
        fill_alpha = 0, line_color = "red")
    # plot the recommendations on the current page
    recs_source = ColumnDataSource(recs)
    rend_main = p.rect('x', 'y', width = 18, height = 18, \
        line_width = 2, height_units="screen", width_units="screen", \
        fill_alpha = 0, line_color = "royalblue", source = recs_source)
    p.image_url(url="artwork_url", x="x", y="y", w=16, h=16, \
        anchor="center", h_units="screen", w_units="screen",\
        source=recs_source)

    # plot the recommendations on the current page
    # rend_main = p.hex('x', 'y', fill_color = 'ivory', line_color = "royalblue", \
    #     line_width = 3, size = 15, \
    #     fill_alpha = 1, source = recs_source)
    # plot the main podcast
    # p.circle(main_pod['x'], main_pod['y'], color = "red", size = 5)
    # p.circle(main_pod['x'], main_pod['y'], fill_color = "red", \
    #     fill_alpha = 0.2, radius = 10, line_color = "red", \
    #     line_alpha = 0.2)

    custom_hover = HoverTool(mode="mouse", point_policy="snap_to_data", \
        muted_policy = "ignore", renderers = [rend_main])

    # limit the hover list to 5 items in case of overlapping glyphs
    custom_formatter = CustomJSHover(code="""
        special_vars.indices = special_vars.indices.slice(0,5)
        if (special_vars.indices.indexOf(special_vars.index) >= 0)
        {
            return " "
        }
        else
        {
            return " hidden "
        }""")
    custom_hover.tooltips = """
    <div @title{custom|safe}>
        <div>
        <img
            src="@artwork_url" alt="@artwork_url" width="42"
            style="margin: 5px 5px 5px 5px;"
            border="2"
        ></img>
        <span style="font-size: 15px; font-weight: bold;">@title</span>
        </div>
    </div>
    """
    custom_hover.formatters = {'@title':custom_formatter}

    p.add_tools(custom_hover)

    p.outline_line_width = 7
    p.outline_line_alpha = 0.2
    p.outline_line_color = "navy"
    p.toolbar.autohide = True
    p.grid.visible = False

    legends = []
    for i in range(0, len(legend_items), 4):
        legends.append(Legend(items=legend_items[i:i+4], margin=2))
    for legend in legends:
        p.add_layout(legend,'below')

    p.plot_height = (600 + ((len(legend_items)-1)//4)*40)

    p.legend.click_policy="mute"
    p.legend.location = "bottom_center"
    p.legend.orientation = "horizontal"

    # url for selected recommendation
    selection_url_code = """
    var ind = source.selected.indices
    if (ind.length==1) {
        var itunes_id = source.data['itunes_id'][ind]
    } else {
        var itunes_id = source.data['itunes_id'][ind[0]]
    }
    var url = "/itunes_id=".concat(itunes_id, "&offset=0")
    window.open(url, "_self")
    """
    taptool = p.select(type=TapTool)
    taptool.renderers = [rend_main]
    taptool.callback = CustomJS(args = dict(source = recs_source), \
        code = selection_url_code)

    # make the figure responsive
    clusters = column([p], sizing_mode = "stretch_width")

    return components(clusters)
예제 #28
0
    'ahr': rk_data['Average Heart Rate (bpm)'],
    'type': rk_data['Type'],
    'col': rk_data['color'],
}

hvr = HoverTool()
tooltip_main = [('Activity', '@type'), ('Date', '@x_ax{%a %b %d %Y}'),
                ('Distance', '@distance{0.00} km'),
                ('Duration', '@duration{%H:%M:%S}'),
                ('Average Pace', '@average_pace{%M:%S}')]
current_tooltip = [('Average Speed', '@average_speed{0.00} km/h')]
hvr.tooltips = tooltip_main + current_tooltip

hvr.formatters = {
    'x_ax': 'datetime',
    'duration': 'datetime',
    'average_pace': 'datetime',
}

toolbox = ['pan', 'box_zoom', 'reset', 'crosshair', hvr]

plot1 = figure(
    plot_width=700,
    x_axis_label='Date',
    x_axis_type='datetime',
    tools=toolbox,
    toolbar_location='above',
    background_fill_color='#bbbbbb',
    border_fill_color="whitesmoke",
)
예제 #29
0
def make_time_plot(place_1,
                   place_dict,
                   place_2=None,
                   window_len=11,
                   y_axis="log"):

    x_1 = np.array(list(place_dict[place_1].keys()))
    y_1 = np.array(list(place_dict[place_1].values()))

    # just to be sure, order the dates
    order = np.argsort(np.array(x_1), kind="stable")
    x_sorted = np.array(x_1)[order]
    y_sorted = np.array(y_1)[order]

    y_smooth = smooth(y_sorted, window_len=window_len)

    if place_2 is not None:
        x_2 = np.array(list(place_dict[place_2].keys()))
        y_2 = np.array(list(place_dict[place_2].values()))

        # just to be sure, order the dates
        order = np.argsort(np.array(x_2), kind="stable")
        x_2_sorted = np.array(x_2)[order]
        y_2_sorted = np.array(y_2)[order]
        y_2_smooth = smooth(y_2_sorted)

        len_diff = len(y_sorted) - len(y_2_sorted)
        if len_diff > 0:
            y_2_smooth = np.append(y_2_smooth, np.zeros(len_diff))

        m_hover = ColumnDataSource(
            dict({
                "date": x_sorted,
                "counts": y_sorted,
                "counts2": y_2_smooth
            }))
        m_title = "counts vs Date: " + args.type + " : " + place_1 + " overlaid with " + place_2  \
                  + " (black), shifted to " + place_1 + " first date"
    else:
        m_hover = ColumnDataSource(dict({
            "date": x_sorted,
            "counts": y_sorted
        }))
        m_title = "counts vs Date: " + args.type + " : " + place_1

    m = figure(tools=TOOLS,
               title=m_title,
               x_axis_type="datetime",
               x_axis_label='Date',
               y_axis_label='counts',
               width=750,
               y_axis_type=y_axis)

    m_hover_tool = HoverTool(tooltips=[("date",
                                        "@date{%F}"), ("counts", "@counts")])
    m_hover_tool.formatters = {"date": "datetime"}
    m.add_tools(m_hover_tool)
    m.line(x="date", y="counts", color="navy", source=m_hover)
    m.line(x=x_sorted, y=y_smooth, line_color="red")

    if place_2 is not None:
        m.line(x=x_2_sorted, y=y_2_smooth, line_color="black")

    return m
예제 #30
0
def run(stock):
    # Get stock
    quote = get(stock, "quote")
    stock_quote = {
        "companyName": quote['companyName'],
        "latestPrice": quote['latestPrice'],
        "symbol": quote['symbol'],
        "change": "{0:.2%}".format(quote['changePercent']),
        "volume": "{:,}".format(quote['latestVolume']),
        "logo": get(stock, 'logo')['url']
    }

    # Get stock related news
    news = get(stock, "news/last/5")
    stock_news = []
    for article in news:
        stock_news.append({
            "headline": article['headline'],
            "url": article['url']
        })

    # Get stock related company data
    company = get(stock, "company")
    company_data = {
        "website": company['website'],
        "CEO": company['CEO'],
        "description": company['description']
    }

    # Get stock key stats
    stats = get(stock, "stats")
    key_stats = {
        "latestEPS": stats['latestEPS'],
        "day5Change": "{0:.2%}".format(stats['day5ChangePercent']),
        "month3Change": "{0:.2%}".format(stats['month3ChangePercent']),
        "year1Change": "{0:.2%}".format(stats['year1ChangePercent']),
    }

    # Get chart stats and make bokeh
    chart = get(stock, "chart/5y")
    chart_cds_df = get(stock, 'chart/1m')
    chart = pd.DataFrame(chart)
    chart = chart.set_index(pd.to_datetime(chart.date))

    chart_cds = ColumnDataSource(chart)

    p = Figure(x_axis_label="Date",
               y_axis_label="Price",
               x_axis_type="datetime",
               title="{} - 5Y Graph".format(stock),
               sizing_mode='scale_width')
    # p.background_fill_color = '#8FBC8F'
    # p.background_fill_alpha = 0.2
    p.grid.grid_line_alpha = 0.3

    p.line(x='date',
           y='close',
           source=chart_cds,
           line_width=1,
           color='#F2583E')

    hover = HoverTool(mode='vline')
    hover.tooltips = [('Date', '@label'), ('Open', '$@open{%0.2f}'),
                      ('High', '$@high{%0.2f}'), ('Low', '$@low{%0.2f}'),
                      ('Close', '$@close{%0.2f}')]
    hover.formatters = {
        'open': 'printf',
        'high': 'printf',
        'low': 'printf',
        'close': 'printf'
    }
    p.add_tools(hover)

    cdl = Figure(x_axis_label="Date",
                 y_axis_label="Price",
                 x_axis_type="datetime",
                 title="{} - Candlestick".format(stock),
                 sizing_mode='scale_width')

    chart_cds_df = pd.DataFrame(chart_cds_df)
    chart_cds_df = chart_cds_df.set_index(pd.to_datetime(chart_cds_df.date))

    inc = chart_cds_df.close > chart_cds_df.open
    dec = chart_cds_df.open > chart_cds_df.close
    w = 12 * 60 * 60 * 1000

    cdl.segment(chart_cds_df.index,
                chart_cds_df.high,
                chart_cds_df.index,
                chart_cds_df.low,
                color='black')
    cdl.vbar(chart_cds_df.index[inc],
             w,
             chart_cds_df.open[inc],
             chart_cds_df.close[inc],
             fill_color='#D5E1DD',
             line_color='black')
    cdl.vbar(chart_cds_df.index[dec],
             w,
             chart_cds_df.open[dec],
             chart_cds_df.close[dec],
             fill_color='#F2583E',
             line_color='black')

    cdl.grid.grid_line_alpha = 0.3

    cdl_s, cdl_div = components(cdl)

    script, div = components(p)

    return {
        "stock_quote": stock_quote,
        "stock_news": stock_news,
        "company_data": company_data,
        "key_stats": key_stats,
        "chart_script": script,
        "chart_div": div,
        "s": cdl_s,
        "d": cdl_div
    }