def create_plot(title, xlabel, ylabel, source, lines, yformatter=None):
    fig = plotting.figure(
        plot_width=PLOT_WIDTH,
        plot_height=PLOT_HEIGHT,
        tools=TOOLS
    )
    fig.title.text = title
    fig.xaxis.axis_label = xlabel
    fig.yaxis.axis_label = ylabel

    fig.xaxis.formatter = models.NumeralTickFormatter(format='0,0')
    if yformatter is not None:
        fig.yaxis.formatter = yformatter

    is_legend = False
    for x in lines:
        if x.legend != '':
            is_legend = True
            fig.line(x='Time', y=x.col, color=x.color, legend_label=x.legend, source=source)
        else:
            fig.line(x='Time', y=x.col, color=x.color, source=source)

    if is_legend:
        fig.legend.click_policy="hide"

    return fig
def create_packets_plot(source, is_sender):
    side_name = 'Sender' if is_sender else 'Receiver'

    if is_sender:
        lines = [
            linedesc('pktSent', 'Sent', 'green'),
            linedesc('pktSndLoss', 'Lost', 'orange'),
            linedesc('pktRetrans', 'Retransmitted', 'blue'),
            linedesc('pktSndDrop', 'Dropped', 'red'),
            linedesc('pktFlightSize', 'On Flight', 'black'),
        ]
    else:
        lines = [
            linedesc('pktRecv', 'Received', 'green'),
            linedesc('pktRcvLoss', 'Lost', 'orange'),
            linedesc('pktRcvRetrans', 'Retransmitted', 'blue'),
            linedesc('pktRcvBelated', 'Belated', 'grey'),
            linedesc('pktRcvDrop', 'Dropped', 'red'),
        ]

    return create_plot(
        'Packets (' + side_name + ' Side)',
        'Time (ms)',
        'Number of Packets',
        source,
        lines,
        models.NumeralTickFormatter(format='0,0')
    )
예제 #3
0
def figure_histogram(hist, edges, title: str, normalized=False, x_range=(0, 5000)):
    """ Create and return `bokeh` histogram figure. """
    fig = plotting.figure(
        plot_height = 400,
        plot_width=800, 
        tools=TOOLS, 
        background_fill_color='#fafafa', 
        x_range=x_range
    )

    fig.quad(
        top=hist,
        bottom=0,
        left=edges[:-1],
        right=edges[1:],
        fill_color='navy',
        line_color='white',
        alpha=0.5
    )
    
    fig.title.text = title
    fig.xaxis.axis_label = 'x, us'
    fig.y_range.start = 0
    fig.grid.grid_line_color='white'

    if normalized:
        fig.yaxis.axis_label = 'f(x)'
    else:
        fig.yaxis.axis_label = 'f(x), packets'
        fig.yaxis.formatter = models.NumeralTickFormatter(format='0,0')

    return fig
예제 #4
0
    def _prepare_plot(self):
        mean = np.array(self.mean)
        deviation = np.array(self.deviation)

        self._figure = bp.figure(title=self._title, plot_width=1200, plot_height=600)
        self._figure.title.text_font_size = '20pt'

        self._figure.xaxis.axis_label = "Base length"
        self._figure.xaxis.axis_label_text_font_size = '16pt'
        self._figure.xaxis.major_label_text_font_size = '12pt'
        self._figure.yaxis[0].formatter = bm.NumeralTickFormatter(format="0.00%")
        self._figure.yaxis[0].major_label_text_font_size = '12pt'

        self._figure.line(self.scales, mean, legend="Error mean", line_color="red", line_width=2)
        self._figure.circle(self.scales, mean, legend="Error mean", line_color="red", fill_color="red")

        self._figure.square(self.scales, deviation, legend="Deviation", fill_color=None, line_color="green", line_width=2)
        self._figure.line(self.scales, deviation, legend="Deviation", line_color="green")

        self._figure.ygrid.minor_grid_line_color = '#e5e5e5'
        self._figure.ygrid.minor_grid_line_dash = [6, 4]
        self._figure.ygrid.minor_grid_line_alpha = 0.7

        self._figure.legend.location = "top_right"
        self._figure.legend.label_text_font_size = '16pt'
예제 #5
0
    def new_plot(self, title, units, *, line_width=None, precision=2):
        """
        Creates a blank line plot for with timestamps on the x-axis and
        a line for each data series on the y-axis.
        """

        plot = plotting.figure(title=title, tools=[])
        self.active_plot = plot
        self.plots.append(plot)
        self.colors = list(colors)
        self.units = units
        self.line_width = line_width or self.line_width

        plot.plot_width = self.width
        plot.plot_height = self.height
        plot.x_range = self.x_range

        datetime_tick_formats = {
            key: ["%a %b %d %H:%M:%S"]
            for key in ("seconds", "minsec", "minutes", "hourmin", "hours", "days")
        }
        plot.xaxis.formatter = models.DatetimeTickFormatter(**datetime_tick_formats)

        # https://bokeh.pydata.org/en/latest/docs/reference/models/formatters.html
        # plot.yaxis.formatter = models.NumeralTickFormatter(format="0a")
        plot.yaxis.formatter = models.NumeralTickFormatter(format="0,0.00 a")

        # With default precision level 2 (decimal places)
        # The units_formats = "@y{0,0.00}"
        # and the value would look like 1,234,567.89
        units_formats = f"@y{{0,0.{'0' * precision}}}"

        hover = models.HoverTool(
            # mode = vline would be nice to use,
            # but then separate hovers block each when lines are too close.
            # Would like a single hover box with time once, and a value per line
            # perhaps this will help acheive that:
            # https://stackoverflow.com/questions/29435200/bokeh-plotting-enable-tooltips-for-only-some-glyphs
            mode="mouse",  # other optins: vline
            line_policy="nearest",  # other optins: prev, next, nearest, interp, none
            tooltips=[
                ("Name", "$name"),
                ("Time", "@x{%a %m/%d %H:%M:%S}"),
                (self.units, units_formats),
            ],
            formatters={"x": "datetime", "Time": "datetime", "@x": "datetime"},
        )
        plot.add_tools(hover)

        plot.add_tools(models.BoxZoomTool())
        plot.add_tools(models.HelpTool())
        plot.add_tools(models.PanTool())
        plot.add_tools(models.WheelZoomTool(dimensions="width"))
        plot.toolbar.active_scroll = plot.select_one(models.WheelZoomTool)
        plot.add_tools(models.WheelZoomTool(dimensions="height"))
        plot.add_tools(models.UndoTool())
        plot.add_tools(models.RedoTool())
        plot.add_tools(models.ResetTool())
        plot.add_tools(models.SaveTool())
def plot_percents(data: list) -> plotting.Figure:
    """Return the bokeh of temperature data."""
    plot = make_timeseries_plot()
    plot.yaxis.formatter = models.NumeralTickFormatter(format="0%")
    plot.y_range = models.Range1d(0, 1)
    plot = make_fact_lines(plot, data)
    plot.legend.location = "top_left"  # because the legend requires glyphs
    return plot
def create_bandwidth_plot(source):
    lines = [linedesc('mbpsBandwidth', '', 'green')]

    return create_plot(
        'Bandwith',
        'Time (ms)',
        'Bandwith (Mbps)',
        source,
        lines,
        models.NumeralTickFormatter(format='0,0')
    )
def create_window_size_plot(source):
    lines = [
        linedesc('pktFlowWindow', 'Flow Window', 'green'),
        linedesc('pktCongestionWindow', 'Congestion Window', 'red'),
    ]

    return create_plot(
        'Window Size',
        'Time (ms)',
        'Number of Packets',
        source,
        lines,
        models.NumeralTickFormatter(format='0,0')
    )
def create_avail_buffer_plot(source, is_sender):
    side_name = 'Sending' if is_sender else 'Receiving'

    if is_sender:
        if not 'byteAvailSndBuf' in source.column_names:
            return None
        lines = [linedesc('MBAvailSndBuf', '', 'green')]
    else:
        if not 'byteAvailRcvBuf' in source.column_names:
            return None
        lines = [linedesc('MBAvailRcvBuf', '', 'green')]

    return create_plot(
        'Available ' + side_name + ' Buffer Size',
        'Time (ms)',
        'MB',
        source,
        lines,
        models.NumeralTickFormatter(format='0,0.00')
    )
def create_rate_plot(source, is_sender):
    side_name = 'Sending' if is_sender else 'Receiving'

    if is_sender:
        lines = [
            linedesc('mbpsSendRate', 'Sendrate', 'green'),
            # Please don't delete the following line.
            # It is used in some cases.
            #linedesc('mbpsMaxBW', 'Bandwidth Limit', 'black'),
        ]
    else:
        lines = [linedesc('mbpsRecvRate', '', 'green')]

    return create_plot(
        side_name + ' Rate',
        'Time (ms)',
        'Rate (Mbps)',
        source,
        lines,
        models.NumeralTickFormatter(format='0,0.00')
    )
def create_bytes_plot(source, is_sender):
    side_name = 'Sender' if is_sender else 'Receiver'

    if is_sender:
        lines = [
            linedesc('MBSent', 'Sent', 'green'),
            linedesc('MBSndDrop', 'Dropped', 'red')
        ]
    else:
        lines = [
            linedesc('MBRecv', 'Received', 'green'),
            linedesc('MBRcvDrop', 'Dropped', 'red'),
        ]

    return create_plot(
        'Megabytes (' + side_name + ' Side)',
        'Time (ms)',
        'MB',
        source,
        lines,
        models.NumeralTickFormatter(format='0,0.00')
    )
예제 #12
0
def make_color_bar(cmap, formatting):
    """ Generates color bar from make_color_mapper()

    :param (Bokeh object) cmap: colormapper from make_color_mapper()
    :param (dict) formatting: see DEFAULTFORMAT from params.py
    :return: None (adds to Bokeh object) """

    color_bar = models.ColorBar(color_mapper=cmap, label_standoff=10, location='bottom_right',
                                height=formatting['cbar_height'], background_fill_color=None,
                                major_label_text_font_size=formatting['cbar_fontsize'],
                                major_label_text_font=formatting['font'],
                                major_tick_line_color=formatting['cbar_tick_color'],
                                major_tick_line_alpha=formatting['cbar_tick_alpha'],
                                title=formatting['cbar_title'],
                                title_text_font_size=formatting['cbar_fontsize'],
                                title_text_font=formatting['font'],
                                title_text_align=formatting['cbar_title_align'],
                                title_text_font_style=formatting['cbar_style'],
                                title_standoff=int(formatting['width'] * \
                                                   formatting['cbar_title_standoff_ratio']))
    if formatting['cbar_textfmt']:
        color_bar.formatter = models.NumeralTickFormatter(
            format=formatting['cbar_textfmt'])
    return color_bar
예제 #13
0
 def __init__(self, readers, rule):
     super().__init__(readers, rule)
     self.figure.yaxis[0].formatter = bom.NumeralTickFormatter(format="0%")
예제 #14
0
def set_yaxis_cash(plot):
    plot.yaxis.axis_label = "Vuositulot"
    plot.yaxis[0].formatter = bm.NumeralTickFormatter(format="€0")
예제 #15
0
def panel_eda(data: pd.DataFrame):
    """
    The main panel with exploratory data analysis consisting of:
    - packet timestamp vs packet inter-arrival time plot,
    - basic statistics table,
    - bar chart and table with sliced into intervals packet inter-arrival times,
    - histograms regular and normalized, 100us bins,
    - histograms regular and normalized, 10us bins,
    - ECDF.

    Attributes:
        data:
            `pd.DataFrame` with packet inter-arrival times data preliminary
            cleaned up and consisting of the two columns `ws.time` and `ws.iat.us`,
            where `ws.time` is the packet timestamp in seconds and `ws.iat.us` is
            the corresponding inter-arrival time from the previous data packet
            in microseconds.

    Returns:
        `models.widgets.Panel` bokeh panel.
    """
    # Figure: Packet timestamp vs Inter-arrival packet time
    source_data = models.ColumnDataSource(data)

    fig_iat = plotting.figure(
        plot_height=400,
        plot_width=1000,
        x_range=(0, 10),
        tools=TOOLS
    )
    fig_iat.title.text = 'Inter-arrival packet time'
    fig_iat.xaxis.axis_label = 'Time, s'
    fig_iat.yaxis.axis_label = 'IAT, us'
    fig_iat.yaxis.formatter = models.NumeralTickFormatter(format='0,0')
    fig_iat.line(x='ws.time', y='ws.iat.us', source=source_data)

    # Table: Statistics
    stats = {}
    stats['stats'] = [
        '25th percentile (Q1), us',
        '50th percentile (Median, Q2), us',
        '75th percentile (Q3), us',
        '90th percentile, us',
        '95th percentile, us',
        '99th percentile, us',
        'Interquartile range (IQR, Q3 - Q1), us',
        'Mean, us',
        'Standard deviation, us',
        'Min, us',
        'Max, us',
        'Packets',
    ]
    stats['value'] = get_stats(data['ws.iat.us'])
    
    source_stats = models.ColumnDataSource(pd.DataFrame(stats))
    columns = [
        models.widgets.TableColumn(field='stats', title='Statistic'),
        models.widgets.TableColumn(field='value', title='Value'),
    ]
    table_stats = models.widgets.DataTable(columns=columns, source=source_stats)

    # Bar chart, table: Sliced into intervals inter-arrival packet times
    fig_slicing, table_slicing = perform_slicing(data['ws.iat.us'])

    # Histograms regular and normalized, 100us bins
    bins_100 = [n * 100 for n in range(0, 5001)]
    hist_100, edges_100 = np.histogram(data['ws.iat.us'], bins=bins_100)
    fig_hist_100 = figure_histogram(hist_100, edges_100, 'Histogram of inter-arrival packet time, 100us bins')
    hist_norm_100, edges_norm_100 = np.histogram(data['ws.iat.us'], bins=bins_100, density=True)
    fig_hist_norm_100 = figure_histogram(hist_norm_100, edges_norm_100, 'Normalized histogram of inter-arrival packet time, 100us bins', True)

    # Histograms regular and normalized, 100us bins
    bins_10 = [n * 10 for n in range(0, 50001)]
    hist_10, edges_10 = np.histogram(data['ws.iat.us'], bins=bins_10)
    fig_hist_10 = figure_histogram(hist_10, edges_10, 'Histogram of inter-arrival packet time, 10us bins')
    hist_norm_10, edges_norm_10 = np.histogram(data['ws.iat.us'], bins=bins_10, density=True)
    fig_hist_norm_10 = figure_histogram(hist_norm_10, edges_norm_10, 'Normalized histogram of inter-arrival packet time, 10us bins', True)

    # Synchronize x axeses of the histograms
    fig_hist_100.x_range = \
        fig_hist_norm_100.x_range = \
        fig_hist_10.x_range = \
        fig_hist_norm_10.x_range

    # ECDF
    x, y = ecdf(data['ws.iat.us'])
    fig_ecdf = figure_ecdf(x, y)

    # Create grid
    grid = layouts.gridplot(
        [
            [fig_iat, table_stats],
            [fig_slicing, table_slicing],
            [fig_hist_100, fig_hist_norm_100],
            [fig_hist_10, fig_hist_norm_10],
            [None, fig_ecdf],
        ]
    )

    # Create panel
    panel = models.widgets.Panel(child=grid, title='Exploratory Data Analysis')
    return panel
예제 #16
0
def perform_slicing(s: pd.Series):
    """
    Perform slicing of the packet IAT series `s` into following bins:
    '0 - 10',
    '10 - 100',
    '100 - 500',
    '500 - 1,000',
    '1,000 - 5,000',
    '5,000 - 10,000',
    '10,000 - 50,000',
    '50,000 - 100,000',
    '100,000 - 500,000',
    where each diapason is specified in microseconds (us).

    Attributes:
        s: `
            pd.Series` of packet inter-arrival time in microseconds (us).

    Returns:
        `bokeh` bar chart figure and table with data.
    """
    bins = [0, 10, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000]
    hist, edges = np.histogram(s, bins=bins)

    bins_str = [
        '0 - 10',
        '10 - 100',
        '100 - 500',
        '500 - 1,000',
        '1,000 - 5,000',
        '5,000 - 10,000',
        '10,000 - 50,000',
        '50,000 - 100,000',
        '100,000 - 500,000'
    ]

    d = {}
    d['edges.us'] = bins_str
    d['packets'] = hist

    df = pd.DataFrame(d)
    n = df['packets'].sum()
    df['packets_cumsum'] = df['packets'].cumsum()
    df['percentage'] = df['packets'] * 100 / n
    df['percentage_cumsum'] = round(df['percentage'].cumsum(), 4)
    df['percentage'] = round(df['percentage'], 4)

    # Figure
    fig = plotting.figure(
        plot_height=300,
        plot_width=1000,
        x_range=bins_str,
        tools=TOOLS
    )
    fig.title.text = 'Inter-arrival packet time diapason vs Packets'
    fig.xaxis.axis_label = 'IAT, us'
    fig.yaxis.axis_label = 'Packets'
    fig.yaxis.formatter = models.NumeralTickFormatter(format='0,0')
    # fig.xaxis.major_label_orientation = math.pi/4
    fig.vbar(x=bins_str, top=hist, width=0.9)

    # Table
    source = models.ColumnDataSource(df)
    columns = [
        models.widgets.TableColumn(field='edges.us', title='IAT, us'),
        models.widgets.TableColumn(field='packets', title='Packets', formatter=models.NumberFormatter(format='0,0')),
        models.widgets.TableColumn(field='packets_cumsum', title='Packets cumsum', formatter=models.NumberFormatter(format='0,0')),
        models.widgets.TableColumn(field='percentage', title='Packets, %'),
        models.widgets.TableColumn(field='percentage_cumsum', title='Packets cumsum, %'),
    ]
    table = models.widgets.DataTable(columns=columns, source=source)

    return fig, table