Esempio n. 1
0
def plot_bar_stack(
    p: Figure, source: ColumnDataSource, df: pd.DataFrame
) -> List[GlyphRenderer]:
    # Plot bar stack.
    measurements = list(df["Measurement"].unique())
    n_measurements = len(measurements)
    color = list((Category20_20 * 2)[:n_measurements])
    if "None" in measurements:
        color[measurements.index("None")] = "black"
    bar_stack = p.vbar_stack(
        **BAR_STACK_KWARGS, stackers=measurements, color=color, source=source,
    )
    stack_hover = HoverTool(
        renderers=bar_stack, tooltips=STACK_HOVER_TOOLTIPS,
    )
    p.add_tools(stack_hover)
    # Customize left y-axis range.
    p.y_range.start = 0
    max_count = bar_stack[0].data_source.data["total"].max() + 1
    p.y_range.end = max_count
    # Create a legend.
    kwargs = LEGEND_KWARGS.copy()
    if len(measurements) == 1:
        kwargs["location"] = (0, 250)
    legend = Legend(
        items=[
            (measurement, [bar_stack[i]])
            for i, measurement in enumerate(measurements)
        ],
        **kwargs,
    )
    p.add_layout(legend, "right")
    return bar_stack
Esempio n. 2
0
    def update_plot(event):
        N, G, T, V, I, Vm, Im, I_N, datapoints = get_inputs()
        print('#' * 30)
        print('Updating the plot')
        print('#' * 30)
        updated_data = iv.iv_data(N, G, T, V, I, Vm, Im, I_N, datapoints)
        source.data = updated_data[0]
        source_translated.data = updated_data[1]
        res_source.data = updated_data[2]
        global status_param
        status_param = updated_data[3]
        print(status_param)
        if (status_param.success == True):
            print('Inside success')
            cite = Label(text='Successful Parameter Extraction',
                         render_mode='css',
                         text_color='white',
                         border_line_color='green',
                         background_fill_color='green')
        else:
            print('Inside fail')
            cite = Label(text='Parameter extraction not converging',
                         render_mode='css',
                         text_color='white',
                         border_line_color='red',
                         background_fill_color='red')
        error_plt = Figure(
            plot_width=100,
            plot_height=50,
            toolbar_location=None,
        )

        error_plt.add_layout(cite)
        layout.children[2].children[1] = error_plt
Esempio n. 3
0
    def make_plot(src):
        # Blank plot with correct labels
        p = Figure(
            plot_width=1024,
            plot_height=768,
            x_axis_type="datetime",
            title="perfmon",
            output_backend="webgl",
        )
        cm = plt.get_cmap("gist_rainbow")

        numlines = len(perfmon.columns)
        mypal = [cm(1.0 * i / numlines) for i in range(numlines)]
        mypal = list(map(lambda x: colors.rgb2hex(x), mypal))
        col = 0
        legenditems = []
        for key in src.data.keys():
            if key == "datetime":
                continue
            l = key + " "
            col = col + 1
            cline = p.line(
                perfmon.index.values,
                perfmon[key],
                line_width=1,
                alpha=0.8,
                color=mypal[col],
            )
            legenditems += [(key, [cline])]
        p.legend.click_policy = "hide"
        legend = Legend(items=legenditems, location=(0, 0))
        p.add_layout(legend, "below")
        return p
Esempio n. 4
0
def gen_cmatrix_legend(p: Figure) -> Figure:
    legend = Legend(items=[tuple((n, [r])) for n, r in zip(dashboard_constants.CMATRIX_CLASS_NAMES, p.renderers)],
                    location="top_center", orientation="horizontal", click_policy='hide', border_line_alpha=0,
                    background_fill_alpha=0)
    legend.label_text_color = '#003566'
    p.add_layout(legend, 'above')
    return p
Esempio n. 5
0
def add_volume_bars(price: pd.DataFrame, p: Figure) -> Figure:
    # note that we set the y-range here to be 3 times the data range so that the volume bars appear in the bottom third
    p.extra_y_ranges = {"vol": Range1d(start=price.Volume.min(), end=price.Volume.max()*3)}
    # use bottom=price.Volume.min() to have bottom of bars clipped off.
    p.vbar(price.Date, w, top=price.Volume, y_range_name="vol")
    # https://bokeh.pydata.org/en/latest/docs/reference/models/formatters.html#bokeh.models.formatters.NumeralTickFormatter
    p.add_layout(LinearAxis(y_range_name="vol", formatter=NumeralTickFormatter(format='$0,0')), 'right')
    return p
Esempio n. 6
0
def add_cumulative_axis(p: Figure, source: ColumnDataSource):
    # Create right y-axis for cumulative line.
    cumulative_top = source.data["cumulative"].max() * 1.1
    p.extra_y_ranges = {
        "cumulative_y_range": Range1d(start=0, end=cumulative_top)
    }
    cumulative_axis = LinearAxis(**CUMULATIVE_AXIS_KWARGS)
    p.add_layout(cumulative_axis, "right")
Esempio n. 7
0
def render_scatter(
    itmdt: Intermediate, plot_width: int, plot_height: int, palette: Sequence[str]
) -> Figure:
    """
    Render scatter plot with a regression line and possible most influencial points
    """

    # pylint: disable=too-many-locals

    df = itmdt["data"]
    xcol, ycol, *maybe_label = df.columns

    tooltips = [(xcol, f"@{{{xcol}}}"), (ycol, f"@{{{ycol}}}")]

    fig = Figure(
        plot_width=plot_width,
        plot_height=plot_height,
        toolbar_location=None,
        title=Title(text="Scatter Plot & Regression Line", align="center"),
        tools=[],
        x_axis_label=xcol,
        y_axis_label=ycol,
    )

    # Scatter
    scatter = fig.scatter(x=df.columns[0], y=df.columns[1], source=df)
    if maybe_label:
        assert len(maybe_label) == 1
        mapper = CategoricalColorMapper(factors=["=", "+", "-"], palette=palette)
        scatter.glyph.fill_color = {"field": maybe_label[0], "transform": mapper}
        scatter.glyph.line_color = {"field": maybe_label[0], "transform": mapper}

    # Regression line
    coeff_a, coeff_b = itmdt["coeffs"]
    line_x = np.asarray([df.iloc[:, 0].min(), df.iloc[:, 0].max()])
    line_y = coeff_a * line_x + coeff_b
    fig.line(x=line_x, y=line_y, line_width=3)
    # Not adding the tooltips before because we only want to apply tooltip to the scatter
    hover = HoverTool(tooltips=tooltips, renderers=[scatter])
    fig.add_tools(hover)

    # Add legends
    if maybe_label:
        nidx = df.index[df[maybe_label[0]] == "-"][0]
        pidx = df.index[df[maybe_label[0]] == "+"][0]

        legend = Legend(
            items=[
                LegendItem(label="Most Influential (-)", renderers=[scatter], index=nidx),
                LegendItem(label="Most Influential (+)", renderers=[scatter], index=pidx),
            ],
            margin=0,
            padding=0,
        )

        fig.add_layout(legend, place="right")
    return fig
Esempio n. 8
0
    def create_fig(self, sources):
        """
        Implementation of :meth:`LivePlot.create_fig` to set up the bokeh figure
        """

        fig = Figure(background_fill_color= None,
                     toolbar_location = None,
                     x_range=[-100, 100], y_range=[-100, 100], tools="", **self._fig_args)



        # Remove existing axes and grid
        fig.xgrid.grid_line_color = None
        fig.ygrid.grid_line_color = None
        fig.axis.visible = False


        # Draw circular grid
        th = np.linspace(0, 360, 100)

        # Draw visibility field
        self.vis_horizon = 10
        #fig.patch(*pol2rect([90 - self.vis_horizon]*len(th), th), color='lightgray')
        fig.patch(*azel2rect(th, [self.vis_horizon]*len(th)), color='lightgray')


        for r in [0, 20, 40, 60, 80]:
            fig.line(*azel2rect(th, [r]*len(th)), line_dash='dashed')

        for th in np.arange(0,360,45):
            fig.line(*azel2rect([th,th], [0,90]), line_dash='dashed')

        # Add grid labels
        lx,ly = azel2rect([0, 90, 180, 270], [0]*4)
        lx[1] -= 30
        lx[2] -= 20
        ly[0] -= 10
        lx[0] -= 10
        src_labels = ColumnDataSource(dict(
            labels= ['N (0)', 'E (90)', 'S (180)', 'W (270)'],
            label_x= lx,
            label_y =ly))

        fig.add_layout(LabelSet(x='label_x', y='label_y', text='labels', source=src_labels))



        fig.line(source=sources['dpass'], x='x', y = 'y', line_width=2)
        fig.circle(source=sources['ant_cmd'], x='x', y='y', size=20, fill_color=None)
        fig.circle(source=sources['ant_cur'], x='x', y='y', size=10, color='green')
        fig.circle(source=sources['sat'], x= 'x', y ='y', size=10, color= 'yellow')

        return fig
Esempio n. 9
0
class ScatterDiagram(Component):
    def __init__(self, environment: Environment):
        super().__init__()
        self.environment = environment

        self.data_source = ColumnDataSource(
            data=dict(x_axis=[], y_axis=[], color=[]))
        self.diagram = Figure(plot_width=400, plot_height=400)

        self.x_axis_menu = Select(title="x axis",
                                  value="radius",
                                  options=list(BlobStatistics))
        self.y_axis_menu = Select(title="y axis",
                                  value="speed",
                                  options=list(BlobStatistics))
        self.color_menu = Select(title="colours",
                                 value="time of birth",
                                 options=list(BlobStatistics))

        self.color_mapper = LinearColorMapper(palette='Cividis11')
        self.color_bar = ColorBar(color_mapper=self.color_mapper,
                                  location=(0, 0))
        self.diagram.circle('x_axis',
                            'y_axis',
                            color={
                                'field': 'color',
                                'transform': self.color_mapper
                            },
                            source=self.data_source)
        self.diagram.add_layout(self.color_bar, 'right')

        self.component = column(
            self.diagram,
            row(self.x_axis_menu, self.y_axis_menu, self.color_menu))

    def refresh(self):
        self.data_source.data = {
            'x_axis': [
                BlobStatistics[self.x_axis_menu.value](organism,
                                                       self.environment)
                for organism in self.environment.organisms.organism_list
            ],
            'y_axis': [
                BlobStatistics[self.y_axis_menu.value](organism,
                                                       self.environment)
                for organism in self.environment.organisms.organism_list
            ],
            'color': [
                BlobStatistics[self.color_menu.value](organism,
                                                      self.environment)
                for organism in self.environment.organisms.organism_list
            ]
        }
Esempio n. 10
0
def render_heatmaps_tab(itmdt: Intermediate, plot_width: int, plot_height: int,
                        palette: Sequence[str]) -> Figure:
    """
    Render missing heatmaps in to tabs
    """
    tooltips = [("x", "@x"), ("y", "@y"),
                ("correlation", "@correlation{1.11}")]
    axis_range = itmdt["axis_range"]
    df = itmdt["data_heatmap"]
    df = df.where(
        np.triu(np.ones(df.shape)).astype(np.bool)  # pylint: disable=no-member
    ).T
    df = df.unstack().reset_index(name="correlation")
    df = df.rename(columns={"level_0": "x", "level_1": "y"})
    df = df[df["x"] != df["y"]]
    df = df.dropna()
    # in case of numerical column names
    df["x"] = df["x"].apply(str)
    df["y"] = df["y"].apply(str)
    mapper, color_bar = create_color_mapper_heatmap(palette)
    x_range = FactorRange(*axis_range)
    y_range = FactorRange(*reversed(axis_range))
    fig = Figure(
        x_range=x_range,
        y_range=y_range,
        plot_width=plot_width,
        plot_height=plot_height,
        x_axis_location="below",
        tools="hover",
        toolbar_location=None,
        tooltips=tooltips,
        background_fill_color="#fafafa",
    )

    tweak_figure(fig)
    fig.grid.grid_line_color = None
    fig.axis.axis_line_color = None
    fig.rect(
        x="x",
        y="y",
        width=1,
        height=1,
        source=df,
        fill_color={
            "field": "correlation",
            "transform": mapper
        },
        line_color=None,
    )

    fig.add_layout(color_bar, "right")

    return fig
Esempio n. 11
0
    def update_success():
        if (status_param.success==True):
            print ('Inside success')
            cite = Label(text='Success', render_mode='css', text_color='white', border_line_color='green', background_fill_color='green')
        else:
            print ('Inside fail')
            cite = Label(text='False', render_mode='css', text_color='white', border_line_color='red', background_fill_color='red')
        error_plt = Figure(plot_width=100, 
                        plot_height=50, 
                        toolbar_location = None,)

        error_plt.add_layout(cite)
        layout.children[2].children[1] = error_plt
Esempio n. 12
0
def highlight(
    fig: Figure,
    x_start: Any,
    x_end: Any,
    color: str = "#FF3936",
    redirect_to: str = None,
):
    """Add a box highlight to an area above the x axis.
    If a redirection URL is given, it can open the URL on double-click (this assumes datetimes are used on x axis!).
    It will pass the year, month, day, hour and minute as parameters to the URL."""
    ba = BoxAnnotation(
        left=x_start, right=x_end, fill_alpha=0.1, line_color=color, fill_color=color
    )
    fig.add_layout(ba)

    if redirect_to is not None:
        if isinstance(x_start, datetime):

            def open_order_book(
                o_url: str, box_start: datetime, box_end: datetime
            ) -> CustomJS:
                return CustomJS(
                    code="""
                    var boxStartDate = new Date("%s");
                    var boxEndDate = new Date("%s");
                    var clickedDate = new Date(cb_obj["x"]);
                    // This quick-fixes some localisation behaviour in bokeh JS (a bug?). Bring back to UTC.
                    clickedDate = new Date(clickedDate.getTime() + clickedDate.getTimezoneOffset() * 60000);
                    console.log("tapped!!");
                    if (boxStartDate <= clickedDate && clickedDate <= boxEndDate) {
                        // TODO: change this to a URL which fits the order book once we actually make it work
                        var urlPlusParams = "%s" + "?year=" + clickedDate.getUTCFullYear()
                                                 + "&month=" + (clickedDate.getUTCMonth()+1)
                                                 + "&day=" + clickedDate.getUTCDate()
                                                 + "&hour=" + clickedDate.getUTCHours()
                                                 + "&minute=" + clickedDate.getMinutes();
                        $(location).attr("href", urlPlusParams);
                    }
                """
                    % (
                        box_start.replace(tzinfo=None),
                        box_end.replace(tzinfo=None),
                        o_url,
                    )
                )

        else:
            raise NotImplementedError(
                "Highlighting only works for datetime ranges"
            )  # TODO: implement for other x-range types
        fig.js_on_event(events.DoubleTap, open_order_book(redirect_to, x_start, x_end))
Esempio n. 13
0
def main ():

    logger.debug('version %s starting' % VERSION)

    opt, args = getParms()

    # Find all the exons in all the transcripts for the gene, put them
    # in a list.

    tranList = list()                                      # list of Transcript objects
    exonList = list()                                      # list of Exon objects

    if opt.gtf is not None:
        getGeneFromAnnotation (opt, tranList, exonList)    # lists will be changed
    if opt.matches is not None:
        getGeneFromMatches (opt, tranList, exonList)       # lists will be changed
    if len(exonList) == 0:
        raise RuntimeError ('no exons found for gene %s in annotation or match files' % opt.gene)

    forwardStrand = '-' if opt.flip else '+'
    if exonList[0].strand == forwardStrand:
        exonList.sort(key=lambda x: x.start)               # sort the list by start position
        blocks = assignBlocks (opt, exonList)              # assign each exon to a block
    else:
        exonList.sort(key=lambda x: x.end, reverse=True)   # sort the list by decreasing end position
        blocks = assignBlocksReverse (opt, exonList)       # assign each exon to a block -- backwards

    findRegions (tranList)                       # determine regions occupied by each transcript

    tranNames = orderTranscripts (tranList)

    output_file("transcript.html")
    p = Figure(plot_width=1000, plot_height=750)
    df = groupTran(tranList, exonList, opt.group)
    length = len(tranNames)
    for myExon in exonList:
        exonSize = myExon.end - myExon.start + 1
        adjStart = myExon.adjStart
        for index, row in df.iterrows():
            name = row['name']
            groupColor = 'purple'
            if name in myExon.name:
                groupColor = row['color']
                break
        p.line([adjStart, adjStart+exonSize], [length-(myExon.tran.tranIx+1), length-(myExon.tran.tranIx+1)], line_width=20, line_color=groupColor)

    f_range = FactorRange(factors=tranNames[::-1])
    p.extra_y_ranges = {"Tran": f_range}
    new_axis = CategoricalAxis(y_range_name="Tran")
    p.add_layout(new_axis, 'left')
    show(p)
Esempio n. 14
0
def relocate_legend(fig: Figure, loc: str) -> Figure:
    """Relocate legend(s) from center to `loc`."""
    remains = []
    targets = []
    for layout in fig.center:
        if isinstance(layout, Legend):
            targets.append(layout)
        else:
            remains.append(layout)
    fig.center = remains
    for layout in targets:
        fig.add_layout(layout, loc)

    return fig
Esempio n. 15
0
def render_correlation_heatmaps(itmdt: Intermediate, plot_width: int, plot_height: int) -> Tabs:
    """
    Render correlation heatmaps in to tabs
    """
    tabs: List[Panel] = []
    tooltips = [("x", "@x"), ("y", "@y"), ("correlation", "@correlation{1.11}")]
    axis_range = itmdt["axis_range"]

    for method, df in itmdt["data"].items():
        # in case of numerical column names
        df = df.copy()
        df["x"] = df["x"].apply(str)
        df["y"] = df["y"].apply(str)

        mapper, color_bar = create_color_mapper(RDBU)
        x_range = FactorRange(*axis_range)
        y_range = FactorRange(*reversed(axis_range))
        fig = Figure(
            x_range=x_range,
            y_range=y_range,
            plot_width=plot_width,
            plot_height=plot_height,
            x_axis_location="below",
            tools="hover",
            toolbar_location=None,
            tooltips=tooltips,
            background_fill_color="#fafafa",
        )

        tweak_figure(fig)

        fig.rect(
            x="x",
            y="y",
            width=1,
            height=1,
            source=df,
            fill_color={"field": "correlation", "transform": mapper},
            line_color=None,
        )

        fig.add_layout(color_bar, "right")
        tab = Panel(child=fig, title=method)
        tabs.append(tab)

    tabs = Tabs(tabs=tabs)
    return tabs
Esempio n. 16
0
def multi_plot(figure_info, source):

    fig = Figure(plot_width=figure_info["plot_width"],
                 plot_height=figure_info["plot_height"],
                 title=figure_info["title"],
                 x_axis_type="datetime")

    fig.extra_y_ranges = {
        "foo": Range1d(start=0, end=figure_info["max_unemployment"])
    }
    fig.add_layout(LinearAxis(y_range_name="foo"), 'right')

    for idx in range(1, len(figure_info["names"])):
        legend_name = str(figure_info["legends"][idx - 1]) + " "

        if "Unem" not in figure_info["names"][idx]:

            fig.vbar(source=source,
                     x=figure_info["names"][0],
                     top=figure_info["names"][idx],
                     bottom=0,
                     width=1000000000,
                     color=figure_info["colors"][idx - 1],
                     fill_alpha=0.2,
                     line_alpha=0.1,
                     legend=legend_name)

        else:

            fig.line(source=source,
                     x=figure_info["names"][0],
                     y=figure_info["names"][idx],
                     line_width=figure_info["line_widths"][idx - 1],
                     alpha=figure_info["alphas"][idx - 1],
                     color=figure_info["colors"][idx - 1],
                     legend=legend_name,
                     y_range_name="foo")

    fig.legend.location = figure_info["legend_location"]
    fig.xaxis.axis_label = figure_info["xaxis_label"]
    fig.yaxis.axis_label = figure_info["yaxis_label"]
    fig.title.align = figure_info["title_align"]

    return fig
Esempio n. 17
0
    def _create_title_fig(self):
        fig = Figure(sizing_mode='scale_width',
                     x_range=[0, 1], y_range=[0, 1], plot_height=50, tools="")

        # Remove existing axes and grid
        fig.xgrid.grid_line_color = None
        fig.ygrid.grid_line_color = None
        fig.axis.visible = False
        fig.background_fill_color = None
        fig.toolbar_location = None

        text = Label(x=0.5, y=0.5,
                     text=self._title_text, render_mode='css',
                     background_fill_color='white', background_fill_alpha=1.0,
                     text_font_size='28pt', text_align='center', text_baseline='middle'
                     )

        fig.add_layout(text)

        return (fig)
Esempio n. 18
0
                x = spectrumwave[i],
                y = [y_offsets[i] + j for j in spectrumscaled[i]],
                src = [catalog[entry]['spectra'][i]['source']]*sl
            )
            if 'redshift' in catalog[entry]:
                data['xrest'] = [x/(1.0 + z) for x in spectrumwave[i]]
            if 'timeunit' in spectrum and 'time' in spectrum:
                data['epoch'] = [catalog[entry]['spectra'][i]['time'] for j in spectrumscaled[i]]
            sources.append(ColumnDataSource(data))
            p2.line('x', 'y', source=sources[i], color=mycolors[i % len(mycolors)], line_width=2)

        if 'redshift' in catalog[entry]:
            minredw = minsw/(1.0 + z)
            maxredw = maxsw/(1.0 + z)
            p2.extra_x_ranges = {"other wavelength": Range1d(start=minredw, end=maxredw)}
            p2.add_layout(LinearAxis(axis_label ="Restframe Wavelength (Å)", x_range_name="other wavelength"), 'above')

        sdicts = dict(zip(['s'+str(x) for x in range(len(sources))], sources))
        callback = CustomJS(args=sdicts, code="""
            var yoffs = [""" + ','.join([str(x) for x in y_offsets]) + """];
            for (s = 0; s < """ + str(len(sources)) + """; s++) {
                var data = eval('s'+s).get('data');
                var redshift = """ + str(z if 'redshift' in catalog[entry] else 0.) + """;
                if (!('binsize' in data)) {
                    data['binsize'] = 1.0
                }
                if (!('spacing' in data)) {
                    data['spacing'] = 1.0
                }
                if (cb_obj.get('title') == 'Spacing') {
                    data['spacing'] = cb_obj.get('value');
Esempio n. 19
0
def plot():

    # FIGURES AND X-AXIS
    fig1 = Figure(title = 'Dive Profile',  plot_width = WIDTH, plot_height = HEIGHT, tools = TOOLS)
    fig2 = Figure(title = 'Dive Controls', plot_width = WIDTH, plot_height = HEIGHT, tools = TOOLS, x_range=fig1.x_range)
    fig3 = Figure(title = 'Attitude',      plot_width = WIDTH, plot_height = HEIGHT, tools = TOOLS, x_range=fig1.x_range)
    figs = gridplot([[fig1],[fig2],[fig3]])

    # Formatting x-axis
    timeticks = DatetimeTickFormatter(formats=dict(seconds =["%b%d %H:%M:%S"],
                                                   minutes =["%b%d %H:%M"],
                                                   hourmin =["%b%d %H:%M"],
                                                   hours =["%b%d %H:%M"],
                                                   days  =["%b%d %H:%M"],
                                                   months=["%b%d %H:%M"],
                                                   years =["%b%d %H:%M %Y"]))
    fig1.xaxis.formatter = timeticks
    fig2.xaxis.formatter = timeticks
    fig3.xaxis.formatter = timeticks

    # removing gridlines
    fig1.xgrid.grid_line_color = None
    fig1.ygrid.grid_line_color = None
    fig2.xgrid.grid_line_color = None
    fig2.ygrid.grid_line_color = None
    fig3.xgrid.grid_line_color = None
    fig3.ygrid.grid_line_color = None

    # INPUT WIDGETS
    collection_list = CONN[DB].collection_names(include_system_collections=False)
    gliders = sorted([platformID for platformID in collection_list if len(platformID)>2])
    gliders = Select(title = 'PlatformID', value = gliders[0], options = gliders)
    prev_glider = Button(label = '<')
    next_glider = Button(label = '>')
    glider_controlbox = HBox(children = [gliders, prev_glider, next_glider], height=80)

    chunkations = Select(title = 'Chunkation', value = 'segment', options = ['segment', '24hr', '30days', '-ALL-'])
    chunk_indicator = TextInput(title = 'index', value = '0')
    prev_chunk = Button(label = '<')
    next_chunk = Button(label = '>')
    chunk_ID   = PreText(height=80)
    chunk_controlbox = HBox(chunkations,
                            HBox(chunk_indicator, width=25),
                            prev_chunk, next_chunk,
                            chunk_ID,
                            height = 80)

    control_box = HBox(glider_controlbox,
                        chunk_controlbox)

    # DATA VARS
    deadby_date = ''
    depth    = ColumnDataSource(dict(x=[],y=[]))
    vert_vel = ColumnDataSource(dict(x=[],y=[]))

    mbpump   = ColumnDataSource(dict(x=[],y=[]))
    battpos  = ColumnDataSource(dict(x=[],y=[]))
    pitch    = ColumnDataSource(dict(x=[],y=[]))

    mfin      = ColumnDataSource(dict(x=[],y=[]))
    cfin      = ColumnDataSource(dict(x=[],y=[]))
    mroll     = ColumnDataSource(dict(x=[],y=[]))
    mheading = ColumnDataSource(dict(x=[],y=[]))
    cheading = ColumnDataSource(dict(x=[],y=[]))

    # AXIS setup
    colors = COLORS[:]

    fig1.y_range.flipped = True
    fig1.yaxis.axis_label = 'm_depth (m)'
    fig1.extra_y_ranges = {'vert_vel': Range1d(start=-50, end=50),
                           'dummy':    Range1d(start=0, end=100)}
    fig1.add_layout(place = 'right',
                    obj = LinearAxis(y_range_name = 'vert_vel',
                                     axis_label   = 'vertical velocity (cm/s)'))
    fig1.add_layout(place = 'left',
                    obj = LinearAxis(y_range_name = 'dummy',
                                     axis_label   = ' '))
    fig1.yaxis[1].visible = False
    fig1.yaxis[1].axis_line_alpha = 0
    fig1.yaxis[1].major_label_text_alpha = 0
    fig1.yaxis[1].major_tick_line_alpha = 0
    fig1.yaxis[1].minor_tick_line_alpha = 0


    fig2.yaxis.axis_label = 'pitch (deg)'
    fig2.y_range.start, fig2.y_range.end = -40,40
    fig2.extra_y_ranges = {'battpos': Range1d(start=-1, end = 1),
                           'bpump':   Range1d(start=-275, end=275)}
    fig2.add_layout(place = 'right',
                    obj = LinearAxis(y_range_name = 'battpos',
                                     axis_label = 'battpos (in)'))
    fig2.add_layout(place = 'left',
                    obj = LinearAxis(y_range_name = 'bpump',
                                     axis_label   = 'bpump (cc)'))
    fig2.yaxis[1].visible = False # necessary for spacing. later gets set to true


    fig3.yaxis.axis_label = 'fin/roll (deg)'
    fig3.y_range.start, fig3.y_range.end = -30, 30
    fig3.extra_y_ranges = {'heading': Range1d(start=0, end=360), #TODO dynamic avg centering
                           'dummy':   Range1d(start=0, end=100)}
    fig3.add_layout(place = 'right',
                    obj = LinearAxis(y_range_name = 'heading',
                                     axis_label   = 'headings (deg)'))
    fig3.add_layout(place = 'left',
                    obj = LinearAxis(y_range_name = 'dummy',
                                     axis_label   = ' '))
    fig3.yaxis[1].visible = False
    fig3.yaxis[1].axis_line_alpha = 0
    fig3.yaxis[1].major_label_text_alpha = 0
    fig3.yaxis[1].major_tick_line_alpha = 0
    fig3.yaxis[1].minor_tick_line_alpha = 0

    # PLOT OBJECTS
    fig1.line(  'x', 'y', source = depth,    legend = 'm_depth',     color = 'red')
    fig1.circle('x', 'y', source = depth,    legend = 'm_depth',     color = 'red')
    fig1.line(  'x', 'y', source = vert_vel, legend = 'vert_vel',    color = 'green',     y_range_name = 'vert_vel')
    fig1.circle('x', 'y', source = vert_vel, legend = 'vert_vel',    color = 'green',     y_range_name = 'vert_vel')
    fig1.renderers.append(Span(location = 0, dimension = 'width',    y_range_name = 'vert_vel',
                               line_color= 'green', line_dash='dashed', line_width=1))

    fig2.line(  'x', 'y', source = pitch,   legend = "m_pitch",    color = 'indigo')
    fig2.circle('x', 'y', source = pitch,   legend = "m_pitch",    color = 'indigo')
    fig2.line(  'x', 'y', source = battpos, legend = 'm_battpos',  color = 'magenta',   y_range_name = 'battpos')
    fig2.circle('x', 'y', source = battpos, legend = 'm_battpos',  color = 'magenta',   y_range_name = 'battpos')
    fig2.line(  'x', 'y', source = mbpump,  legend = "m_'bpump'",  color = 'blue',      y_range_name = 'bpump')
    fig2.circle('x', 'y', source = mbpump,  legend = "m_'bpump'",  color = 'blue',      y_range_name = 'bpump')
    fig2.renderers.append(Span(location = 0, dimension = 'width',
                               line_color= 'black', line_dash='dashed', line_width=1))
    fig3.line(  'x', 'y', source = mfin,       legend = 'm_fin',     color = 'cyan')
    fig3.circle('x', 'y', source = mfin,       legend = 'm_fin',     color = 'cyan')
    fig3.line(  'x', 'y', source = cfin,       legend = 'c_fin',     color = 'orange')
    fig3.circle('x', 'y', source = cfin,       legend = 'c_fin',     color = 'orange')
    fig3.line(  'x', 'y', source = mroll,      legend = 'm_roll',    color = 'magenta')
    fig3.circle('x', 'y', source = mroll,      legend = 'm_roll',    color = 'magenta')
    fig3.line(  'x', 'y', source = mheading,   legend = 'm_heading', color = 'blue',    y_range_name = 'heading')
    fig3.circle('x', 'y', source = mheading,   legend = 'm_heading', color = 'blue',    y_range_name = 'heading')
    fig3.line(  'x', 'y', source = cheading,   legend = 'c_heading', color = 'indigo',  y_range_name = 'heading')
    fig3.circle('x', 'y', source = cheading,   legend = 'c_heading', color = 'indigo',  y_range_name = 'heading')
    fig3.renderers.append(Span(location = 0, dimension = 'width',    y_range_name = 'default',
                               line_color= 'black', line_dash='dashed', line_width=1))

    # CALLBACK FUNCS
    def update_data(attrib,old,new):
        g = gliders.value
        chnk = chunkations.value
        chindex = abs(int(chunk_indicator.value))

        depth.data    = dict(x=[],y=[])
        vert_vel.data = dict(x=[],y=[])
        mbpump.data   = dict(x=[],y=[])
        battpos.data  = dict(x=[],y=[])
        pitch.data    = dict(x=[],y=[])

        mfin.data     = dict(x=[],y=[])
        cfin.data     = dict(x=[],y=[])
        mroll.data    = dict(x=[],y=[])
        mheading.data = dict(x=[],y=[])
        cheading.data = dict(x=[],y=[])


        depth.data,startend   = load_sensor(g, 'm_depth', chnk, chindex)

        if chnk == 'segment':
            xbd = startend[2]
            chunk_ID.text = '{} {} \n{} ({}) \nSTART: {} \nEND:   {}'.format(g, xbd['mission'],
                                                                             xbd['onboard_filename'], xbd['the8x3_filename'],
                                                                             e2ts(xbd['start']), e2ts(xbd['end']))
            if len(set(depth.data['x']))<=1 and attrib == 'chunk':
                if old > new:
                    next_chunk.clicks += 1
                else:
                    prev_chunk.clicks += 1
                return
            elif len(set(depth.data['x']))<=1 and chunk_indicator.value == 0:
                chunk_indicator.value = 1

        elif chnk in ['24hr', '30days']:
            chunk_ID.text = '{} \nSTART: {} \nEND:   {}'.format(g, e2ts(startend[0]), e2ts(startend[1]))
        elif chnk == '-ALL-':
            chunk_ID.text = '{} \nSTART: {} \nEND:   {}'.format(g,e2ts(depth.data['x'][0] /1000),
                                                                  e2ts(depth.data['x'][-1]/1000))


        vert_vel.data  = calc_vert_vel(depth.data)

        mbpump.data,_     = load_sensor(g, 'm_de_oil_vol', chnk, chindex)
        if len(mbpump.data['x']) > 1:
            #for yax in fig2.select('mbpump'):
            #    yax.legend = 'm_de_oil_vol'
            pass
        else:
            mbpump.data,_     = load_sensor(g, 'm_ballast_pumped', chnk, chindex)
            #for yax in fig2.select('mbpump'):
            #    yax.legend = 'm_ballast_pumped'
        battpos.data,_ = load_sensor(g, 'm_battpos',    chnk, chindex)
        pitch.data,_   = load_sensor(g, 'm_pitch',      chnk, chindex)
        pitch.data['y'] = [math.degrees(y) for y in pitch.data['y']]

        mfin.data,_     = load_sensor(g, 'm_fin',     chnk, chindex)
        cfin.data,_     = load_sensor(g, 'c_fin',     chnk, chindex)
        mroll.data,_    = load_sensor(g, 'm_roll',    chnk, chindex)
        mheading.data,_ = load_sensor(g, 'm_heading', chnk, chindex)
        cheading.data,_ = load_sensor(g, 'c_heading', chnk, chindex)
        mfin.data['y']     = [math.degrees(y) for y in mfin.data['y']]
        cfin.data['y']     = [math.degrees(y) for y in cfin.data['y']]
        mheading.data['y'] = [math.degrees(y) for y in mheading.data['y']]
        cheading.data['y'] = [math.degrees(y) for y in cheading.data['y']]
        mroll.data['y']    = [math.degrees(y) for y in mroll.data['y']]

        fig1.yaxis[1].visible = True
        fig2.yaxis[1].visible = True
        fig3.yaxis[1].visible = True


    #GLIDER SELECTS
    def glider_buttons(increment):
        ops = gliders.options
        new_index = ops.index(gliders.value) + increment
        if new_index >= len(ops):
            new_index = 0
        elif new_index < 0:
            new_index = len(ops)-1
        gliders.value = ops[new_index]
        chunkation_update(None, None, None) #reset chunk indicator and clicks
    def next_glider_func():
        glider_buttons(1)
    def prev_glider_func():
        glider_buttons(-1)
    def update_glider(attrib,old,new):
        chunk_indicator.value = '0'
        #update_data(None,None,None)


    gliders.on_change('value', update_glider)
    next_glider.on_click(next_glider_func)
    prev_glider.on_click(prev_glider_func)


        #CHUNK SELECTS
    def chunkation_update(attrib,old,new):
        chunk_indicator.value = '0'
        prev_chunk.clicks = 0
        next_chunk.clicks = 0
        update_data(None,None,None)
        if new == '-ALL-':
            chunk_indicator.value = '-'

    def chunk_func():
        chunkdiff = prev_chunk.clicks - next_chunk.clicks
        if chunkdiff < 0:
            prev_chunk.clicks = 0
            next_chunk.clicks = 0
            chunkdiff = 0
        print (chunkdiff)
        chunk_indicator.value = str(chunkdiff)

    def chunk_indicator_update(attrib,old,new):
        try:
            if abs(int(old)-int(new))>1: #manual update, triggers new non-manual indicator update, ie else clause below
                prev_chunk.clicks = int(new)
                next_chunk.clicks = 0
            else:
                update_data('chunk',int(old),int(new))
            print("UPDATE", old, new)
        except Exception as e:
            print(type(e),e, old, new)

    chunkations.on_change('value', chunkation_update)
    chunk_indicator.on_change('value', chunk_indicator_update)
    next_chunk.on_click(chunk_func)
    prev_chunk.on_click(chunk_func)

    update_data(None,None,None)

    return vplot(control_box, figs)
Esempio n. 20
0
class DynamicPlotHandler(Handler):
    def __init__(self, network):
        self._network = weakref.ref(network)
        self.sources = {}
        self._last_time_list = None
        self._update_complete = False
        self._recurring_update = RecurringTask(self.plan_update_data, delay=5)
        self._pcb = None  # Periodic callback
        self._ntcb = None  # Next Tick callback
        super().__init__()

    @property
    def network(self):
        return self._network()

    def organize_data(self):

        self._log.debug("Organize Data")

        self.s = {}
        for point in self.network.trends:
            self.s[point.history.name] = (point.history, point.history.units)
        self.lst_of_trends = [his[0] for name, his in self.s.items()]

    def build_data_sources(self):
        sources = {}
        self.organize_data()
        for each in self.lst_of_trends:
            df = pd.DataFrame(each)
            df = df.reset_index()
            df["name"] = each.name
            df["units"] = str(each.units)
            df["time_s"] = df["index"].apply(str)
            df.states = each.states
            try:
                df = (
                    df.fillna(method="ffill")
                    .fillna(method="bfill")
                    .replace(["inactive", "active"], [0, 1])
                )
            except TypeError:
                df = df.fillna(method="ffill").fillna(method="bfill")

            sources[each.name] = ColumnDataSource(
                data=dict(
                    x=df["index"],
                    y=df[each.name],
                    time=df["time_s"],
                    name=df["name"],
                    units=df["units"],
                )
            )
        return sources

    def build_plot(self):
        self._log.debug("Build Plot")

        self.stop_update_data()
        self.sources = self.build_data_sources()

        TOOLS = "pan,box_zoom,wheel_zoom,save,reset"
        self.p = Figure(
            x_axis_type="datetime",
            x_axis_label="Time",
            y_axis_label="Numeric Value",
            title="BAC0 Trends",
            tools=TOOLS,
            plot_width=800,
            plot_height=600,
            toolbar_location="above",
        )

        self.p.background_fill_color = "#f4f3ef"
        self.p.border_fill_color = "#f4f3ef"
        self.p.extra_y_ranges = {
            "bool": Range1d(start=0, end=1.1),
            "enum": Range1d(start=0, end=10),
        }
        self.p.add_layout(LinearAxis(y_range_name="bool", axis_label="Binary"), "left")
        self.p.add_layout(
            LinearAxis(y_range_name="enum", axis_label="Enumerated"), "right"
        )

        hover = HoverTool(
            tooltips=[
                ("name", "@name"),
                ("value", "@y"),
                ("units", "@units"),
                ("time", "@time"),
            ]
        )
        self.p.add_tools(hover)

        length = len(self.s.keys())
        if length <= 10:
            if length < 3:
                length = 3
            color_mapper = dict(zip(self.s.keys(), d3["Category10"][length]))
        else:
            # This would be a very loaded trend...
            color_mapper = dict(zip(self.s.keys(), Spectral6[:length]))

        for each in self.lst_of_trends:
            if each.states == "binary":
                self.p.circle(
                    "x",
                    "y",
                    source=self.sources[each.name],
                    name=each.name,
                    color=color_mapper[each.name],
                    legend=("%s | %s (OFF-ON)" % (each.name, each.description)),
                    y_range_name="bool",
                    size=10,
                )
            elif each.states == "multistates":
                self.p.diamond(
                    "x",
                    "y",
                    source=self.sources[each.name],
                    name=each.name,
                    color=color_mapper[each.name],
                    legend=("%s | %s (%s)" % (each.name, each.description, each.units)),
                    y_range_name="enum",
                    size=20,
                )
            else:
                self.p.line(
                    "x",
                    "y",
                    source=self.sources[each.name],
                    name=each.name,
                    color=color_mapper[each.name],
                    legend=("%s | %s (%s)" % (each.name, each.description, each.units)),
                    line_width=2,
                )

            self.p.legend.location = "bottom_right"
            self.p.legend.click_policy = "hide"

            self.plots = [self.p]

    def update_data(self):
        self._log.debug("Update Data")
        doc = curdoc()
        # self.organize_data()
        if self._last_time_list:
            if self._last_time_list != self.s.keys():
                self._list_have_changed = True
                self.stop_update_data()
                # doc.add_next_tick_callback(self.modify_document)
                self.modify_document(doc)
            else:
                self._list_have_changed = False

        l = []
        for each in self.p.renderers:
            l.append(each.name)

            # for each in self.lst_of_trends:
            #    df = pd.DataFrame(each)
            #    df = df.reset_index()
            #    df['name'] = each.name
            #    df['units'] = str(each.units)
            #    df['time_s'] = df['index'].apply(str)

            #    try:
            #        df = df.fillna(method='ffill').fillna(
            #            method='bfill').replace(['inactive', 'active'], [0, 1])
            #    except TypeError:
            #        df = df.fillna(method='ffill').fillna(method='bfill')

            index = l.index(each.name)
        #    renderer = self.p.renderers[index]
        #    new_data = {}
        #    new_data['name'] = df['name']
        #    new_data['x'] = df['index']
        #    new_data['y'] = df[each.name]
        #    if each.states == 'binary':
        #        new_data['units'] = [each.units[int(x)] for x in df[each.name]]
        #    elif each.states == 'multistates':
        #        new_data['units'] = [
        #            each.units[int(math.fabs(x-1))] for x in df[each.name]]
        #    else:
        #        new_data['units'] = df['units']
        #    new_data['time'] = df['time_s']
        #    renderer.data_source.data = new_data
        try:
            new_data = self.build_data_sources()
            for each in self.lst_of_trends:
                self.sources[each.name].data = new_data[each.name].data

        except KeyError:
            self._log.warning(
                "Problem updating {} on chart, will try again next time.".format(
                    each.name
                )
            )

        else:
            self._last_time_list = self.s.keys()
            # self.start_update_data()
            self._update_complete = True

    def modify_document(self, doc):
        curdoc().clear()
        # doc = curdoc()
        try:
            curdoc().remove_periodic_callback(self._pcb)
        except:
            pass
        doc.clear()
        self.build_plot()
        layout = gridplot(self.plots, ncols=2)

        doc.add_root(layout)
        self._pcb = doc.add_periodic_callback(self.update_data, 10000)
        return doc

    def plan_update_data(self):
        doc = curdoc()
        if self._update_complete == True:
            self._update_complete = False
            self._ntcb = doc.add_next_tick_callback(self.update_data)

    def stop_update_data(self):
        doc = curdoc()
        if self._recurring_update.is_running:
            self._recurring_update.stop()
            while self._recurring_update.is_running:
                pass
            try:
                doc.remove_next_tick_callback(self._ntcb)
            except (ValueError, RuntimeError):
                pass  # Already gone

    def start_update_data(self):
        if not self._recurring_update.is_running:
            try:
                self._recurring_update.start()
                while not self._recurring_update.is_running:
                    pass
            except RuntimeError:
                pass
Esempio n. 21
0
# overlay volume level chart to salinity
tc = "MediumBlue"  # tide color
tide_range = Range1d(start=0, end=15)
tide_axis = LinearAxis(y_range_name="Z")
tide_axis.axis_label = "Tidal Height (m)"
tide_axis.axis_label_text_color = tc
tide_axis.axis_label_text_font_size = label_fontsize
tide_axis.major_tick_line_color = tc
tide_axis.major_label_text_color = tc
tide_axis.minor_tick_line_alpha = 0.

top.extra_y_ranges = {"Z": tide_range}
# top.line('day', 'Z', source=source,
         # line_color=tc, line_width=2, line_cap='round')
top.add_layout(tide_axis, "right")
top.line('day', 'Z', source=source,
         line_color=tc, line_width=2, line_cap='round',
         y_range_name="Z")

mid = Figure(title=None, x_range=top.x_range,
             toolbar_location=None, **figure_style_kws)
mid.line('day', 'N', source=source,
         line_color=colors[1], line_width=3, line_cap='round')
mid.y_range = Range1d(0., 200.)
mid.yaxis.axis_label = "Nitrate (µmol/L)"
mid.xaxis.axis_label_text_font_size = label_fontsize
mid.yaxis.axis_label_text_font_size = label_fontsize


bot = Figure(title=None, x_range=top.x_range,
# %%
# COLOR BAR

cb = bokeh.models.ColorBar(
    color_mapper=cm['transform'],
    width=30,
    location=(0, 0),
    #     title="DEN (N/km^2)",
    title="MAS-CC%",
    # margin=0,padding=0,
    title_standoff=10,
    # ticker=bokeh.models.LogTicker()
)

cart_fig.add_layout(cb, 'left')

# layout = row(column(slider, cart_f),map_f)
layout = bokeh.layouts.gridplot([[slider, None], [cart_fig, map_fig]],
                                merge_tools=False)
# layout = bokeh.layouts.column([slider, cart_fig])

cart_fig.x_range.start = -75
cart_fig.x_range.end = -50
cart_fig.y_range.start = -25
cart_fig.y_range.end = -5

_ll = ebu.lola_to_cart(lo=[-75, -50], la=[-25, -5])
map_fig.x_range.start = _ll[0][0]
map_fig.x_range.end = _ll[0][1]
map_fig.y_range.start = _ll[1][0]
Esempio n. 23
0
         hover_line_color='red')

taptool = p.select(type=TapTool)
taptool.callback = OpenURL(url=url)

## px.circle('x1','y1', source = source_comp, radius = 0.015,
##         fill_color = 'lightgray', line_color='black', line_width=0.3)

# bokeh.pydata.org/en/latest/docs/reference/models/annotations.html
xcolor_bar = ColorBar(color_mapper=mapper,
                      label_standoff=-13,
                      major_label_text_font_style="bold",
                      padding=26,
                      major_label_text_align='right',
                      major_label_text_font_size="10pt",
                      location=(0, 0))

p.add_layout(xcolor_bar, 'left')

#infos
info, nlines = write_info('skypeak', tests['skypeak'])
txt = PreText(text=info, height=nlines * 20, width=p.plot_width)
info_col = Div(text=write_description('skypeak'), width=p.plot_width)
p2txt = column(widgetbox(info_col), p)

layout = gridplot([[p2txt]])

# End of Bokeh Block
curdoc().add_root(layout)
curdoc().title = "SKYPEAK"
Esempio n. 24
0
    def plot_carto_single(self, data, frente, palette, path=FILE_OUT,
                          name_file="", low=0, high=100, show_plot=True):
        """

        :param data: df loaded by data_load
        :param frente: string, name of "partido" lowercase: diff, mas, cc, creemos, fpv, pan_bol
        :param palette: ej: P_GRAD_CC
        :param name_file: default:test
        :param low: cmap low limit: default: -80
        :param high: cmap high limit: defauilt: +80.
        :param path: file out
        :return: df
        """
        da_col = ['HAB','PAIS','MUN','REC','X','Y','LAT','LON','x','y',
                  'r','r2','GX','GY'
                  ]

        cart_init_val = self.CART_SLIDER_INIT  # add slider
        self.process_data(cart_init_val, data)


        if frente == "diff":
            low = self.C_BAR_LOW
            high = self.C_BAR_HIGH
            frente = "d_mas_cc"
            f1 = 'mas_o_cc'
            f2 = 'ad_mas_cc'
            _p = 'mas'
            _p1 = 'cc'
            da_col.append(frente)
            da_col.append(f1)
            da_col.append(f2)
            da_col.append(_p)
            da_col.append(_p1)
        if frente == "d_mas_creemos":
            low = self.C_BAR_LOW
            high = self.C_BAR_HIGH
            f1 = 'mas_o_creemos'
            f2 = 'ad_mas_creemos'
            da_col.append(frente)
            da_col.append(f1)
            da_col.append(f2)
            da_col.append('mas')
            da_col.append('creemos')

        da_col.append(frente)



        cm = linear_cmap(frente, palette=palette, low=low, high=high)



        data = data[da_col]
        source_master = ColumnDataSource(data)
        source_red_map = ColumnDataSource({'gx': [], 'gy': []})
        # la, lo = ebu.get_la_lo_bolivia()
        # source_bol = ColumnDataSource({'la': la, 'lo': lo})
        # source_red_car = ColumnDataSource({'lo': [], 'la': []})

        # JS CODE
        code_draw_red_map = """
        const data = {'gx': [], 'gy': []}
        const indices = cb_data.index.indices
        for (var i = 0; i < indices.length; i++ ) {
                data['gx'].push(source_master.data.GX[indices[i]])
                data['gy'].push(source_master.data.GY[indices[i]])
        }
        source_red_map.data = data
        """

        code_slider = """
            var data = source.data;
            var f = cb_obj.value
            var x = data['x']
            var y = data['y']
            var Y = data['Y']
            var X = data['X']
            var lat = data['LAT']
            var lon = data['LON']
            for (var i = 0; i < x.length; i++) {
                y[i] = (1-f)*lat[i] + f*Y[i]
                x[i] = (1-f)*lon[i] + f*X[i]
            }
            source.change.emit();
        """

        # FIGURES
        curr_time = ebu.get_bolivian_time(-3)

        pw = self.FIG_WIDTH

        callback_red_map = CustomJS(
            args={'source_master': source_master,
                  'source_red_map': source_red_map, },
            code=code_draw_red_map)

        hover_cart = bokeh.models.HoverTool(
            tooltips=self.TOOL_TIP_DIC[frente],
            callback=callback_red_map,
            # renderers = [red_scat_car]

        )

        cart_fig = Figure(plot_width=pw, plot_height=pw,
                          output_backend="webgl", )
        cart_fig.background_fill_color = "grey"
        cart_fig.background_fill_alpha = .5
        cart_fig.scatter('x', 'y', source=source_master, radius='r', color=cm)
        cart_fig.add_tools(hover_cart, )

        title = "Última actualización: " + curr_time["datetime_val"].strftime(
            "%Y-%m-%d %H:%M") + "BOT"


        map_fig = Figure(plot_width=pw, plot_height=pw,
                         x_axis_type='mercator',
                         y_axis_type='mercator',
                         output_backend="webgl",
                         title=title,
                         )

        # cb_fig = bokeh.plotting.Figure(plot_height=pw,plot_width=)
        # cb_fig.toolbar.logo = None
        # cb_fig.toolbar_location = None

        # SCATTER
        # noinspection PyUnresolvedReferences
        # add tiles
        tile_provider = bokeh.tile_providers.get_provider(
            bokeh.tile_providers.Vendors.CARTODBPOSITRON)
        map_fig.add_tile(tile_provider)

        # scatter in map
        map_fig.scatter(
            'GX', 'GY', source=source_master, size='r2',
            color=cm
        )

        # todo if we wont use map then we nee to delete the source
        # cart_fig.line('lo', 'la', source=source_bol, color='black')

        # noinspection PyUnusedLocal
        red_scat_map = map_fig.circle_cross('gx', 'gy',
                                            source=source_red_map,
                                            fill_color=None,
                                            size=20,
                                            line_color="white",
                                            line_width=4
                                            )

        # noinspection PyUnusedLocal
        red_scat_map = map_fig.circle_cross('gx', 'gy',
                                            source=source_red_map,
                                            fill_color=None,
                                            size=20,
                                            line_color="red",
                                            line_width=1
                                            )
        # red_scat_car = cart_fig.scatter('lo', 'la',
        # source=source_red_car, color='green')

        # add a hover tool that sets the link data for a hovered circle

        # callbacks

        # code = code_merged)

        # callback_red_car = CustomJS(
        # args={'source_master': source_master, 'source_red_car': source_red_car},
        # code=code_draw_red_car)

        # tools

        hover_map = bokeh.models.HoverTool(
            tooltips=self.TOOL_TIP_DIC[frente],
            # callback=callback_red_car,
            # renderers = [red_scat_map]
        )
        map_fig.add_tools(hover_map, )

        # slider
        callback_slider = CustomJS(args=dict(source=source_master),
                                   code=code_slider)

        slider = Slider(start=0, end=1, value=cart_init_val, step=.02,
                        title="carto")
        slider.js_on_change('value', callback_slider)

        # COLOR BAR
        ml = {int(i): str(np.abs(i)) for i in np.arange(-80, 81, 20)}
        cb = bokeh.models.ColorBar(
            color_mapper=cm['transform'],
            # width=int(.9 * 450),
            width='auto',
            location=(0, 0),
            #     title="DEN (N/km^2)",
            # title=(BAR_TITLE),
            # margin=0,padding=0,
            title_standoff=10,
            # ticker=bokeh.models.LogTicker(),
            orientation='horizontal',
            major_label_overrides=ml

        )

        cart_fig.add_layout(cb, 'above')
        # cb.title_text_align = 'left'
        cart_fig.title.text = self.BAR_TITLE_DIC[frente]
        cart_fig.title.align = 'center'

        # layout = row(column(slider, cart_f),map_f)
        layout = bokeh.layouts.gridplot(
            [[slider, None], [cart_fig, map_fig]], sizing_mode='scale_width',
            merge_tools=False)
        layout.max_width = 1400
        # layout = bokeh.layouts.column([slider, cart_fig])

        cart_fig.x_range.start = self.CXS
        cart_fig.x_range.end = self.CXE
        cart_fig.y_range.start = self.CYS
        cart_fig.y_range.end = self.CYE

        _ll = ebu.lola_to_cart(lo=[self.MXS, self.MXE], la=[self.MYS, self.MYE])
        map_fig.x_range.start = _ll[0][0]
        map_fig.x_range.end = _ll[0][1]
        map_fig.y_range.start = _ll[1][0]
        map_fig.y_range.end = _ll[1][1]

        cart_fig.xaxis.major_tick_line_color = None
        # turn off x-axis major ticks
        cart_fig.xaxis.minor_tick_line_color = None
        # turn off x-axis minor ticks
        cart_fig.yaxis.major_tick_line_color = None
        # turn off y-axis major ticks
        cart_fig.yaxis.minor_tick_line_color = None
        cart_fig.xaxis.major_label_text_font_size = '0pt'
        # turn off x-axis tick labels
        cart_fig.yaxis.major_label_text_font_size = '0pt'
        # turn off y-axis tick labels
        nam = 'z037_' + frente + '_' + name_file + '.html'
        nam_lat = 'z037_' + frente + '_' + 'latest' + '.html'
        nam1 = os.path.join(path, nam)

        nam2 = os.path.join(os.path.dirname(ebu.DIR), 'docs',
                            'graficas_htmls',
                            nam_lat)
        # bokeh.plotting.output_file(nam2)
        if show_plot:

            bokeh.plotting.show(layout)

        bokeh.plotting.save(layout, nam1)
        bokeh.plotting.save(layout, nam2)

        return data
Esempio n. 25
0
class BokehPlot(object):
    def __init__(self, device, points_list, *, title = 'My title', show_notes = True, update_data = True):
        self.device = device
        self.points_list = points_list
        self.title = title
        self.units = {}
        self.show_notes = show_notes

        self.lst = self.points_list

        self.multi_states = self.device.multi_states
        self.binary_states = self.device.binary_states
        self.analog_units = self.device.analog_units

        plot = self.build_plot()

        self.device.properties.network.bokeh_document.add_plot(plot)
        if update_data:
            self.device.properties.network.bokeh_document.add_periodic_callback(self.update_data, 100)   
        print('Chart created, please reload your web page to see changes')
        
     # Get data
    def read_lst(self):
        df = self.device[self.lst]
        try:
            df = df.fillna(method='ffill').fillna(method='bfill').replace(['inactive', 'active'], [0, 1])
        except TypeError:
            df = df.fillna(method='ffill').fillna(method='bfill')
                                      
        df = df.reset_index()
        df['name'] = 'nameToReplace'
        df['units'] = 'waiting for refresh'
        df['time_s'] = df['index'].apply(str)
        return df

    def read_notes(self):
        notes_df = self.device.notes.reset_index()
        notes_df['value'] = -5
        notes_df['desc'] = 'Notes'
        notes_df['time_s'] = notes_df['index'].apply(str)
        return notes_df

    def build_plot(self):        
        df = self.read_lst()
        notes_df = self.read_notes()

        TOOLS = "hover,resize,save,pan,box_zoom,wheel_zoom,reset"
        #plot_width=800, plot_height=600,
        self.p = Figure(x_axis_type="datetime", title = self.title, tools = TOOLS)

        if self.show_notes:
            self.notes_source = ColumnDataSource(
                    data=dict(
                        x = notes_df['index'],
                        y = notes_df['value'],
                        time = notes_df['time_s'],
                        desc = notes_df['desc'],
                        units = notes_df[0]
                    )
                )

            self.p.asterisk('x', 
                            'y',
                            source = self.notes_source,
                            name = 'Notes',
                            color = "#%06x" % random.randint(0x000000, 0x777777), 
                            legend='Notes',
                            size = 40) 

        self.p.legend.location = 'top_left'
        self.p.extra_y_ranges = {"bool": Range1d(start=0, end=1.1),
                                 "enum": Range1d(start=0, end=10)}
        self.p.add_layout(LinearAxis(y_range_name="bool"), 'left')
        self.p.add_layout(LinearAxis(y_range_name="enum"), 'right')
                            
        hover = self.p.select(dict(type=HoverTool))
        hover.tooltips = OrderedDict([
            ('name', '@desc'),
            ('value', '@y'),
            ('units', '@units'),
            ('time', '@time'),
        ])

        self.sources = {}               
        for each in self.lst:
            
            try:
                df['name'] = df['name'].replace('nameToReplace', ('%s / %s' % (each, self.device[each]['description'])))            
            except TypeError:
                continue
            self.sources[each] = ColumnDataSource(
                            data=dict(
                            x = df['index'],
                            y = df[each],
                            time = df['time_s'],
                            name = df['name'],
                            units = df['units']
                        )
                    )

            if each in self.binary_states:
                self.p.circle('x', 
                            'y',
                            source = self.sources[each],
                            name = each,
                            color = "#%06x" % random.randint(0x000000, 0x777777),
                            legend=each,
                            y_range_name="bool",
                            size = 10)
            elif each in self.multi_states:
                self.p.diamond('x', 
                            'y',
                            source = self.sources[each],
                            name = each,
                            color = "#%06x" % random.randint(0x000000, 0x777777), 
                            legend=each,
                            y_range_name="enum",
                            size = 20)            
            else:
                self.p.line('x',
                            'y',
                            source = self.sources[each],
                            name = each,
                            color = "#%06x" % random.randint(0x000000, 0x777777),
                            legend=each,
                            line_width = 2)
            
        return self.p
    
    def update_data(self):
        if self.device.properties.network._started:           
            df = self.read_lst()
            for renderer in self.p.renderers:
                name = renderer.name
                if name in self.points_list:
                    glyph_renderer = renderer
                    df['name'] = ('%s / %s' % (name, self.device[name]['description']))
                    glyph_renderer.data_source.data['x'] = df['index']
                    glyph_renderer.data_source.data['y'] = df[name]
                    glyph_renderer.data_source.data['desc'] = df['name']
                    glyph_renderer.data_source.data['time'] = df['time_s']
                    if name in self.multi_states:
                        glyph_renderer.data_source.data['units'] = [self.multi_states[name][int(math.fabs(x-1))] for x in df[name]]
                    elif name in self.binary_states:
                        glyph_renderer.data_source.data['y'] = df[name]
                        glyph_renderer.data_source.data['units'] = [self.binary_states[name][int(x/1)] for x in df[name]]
                    else:
                        df['units'] = self.analog_units[name]
                        glyph_renderer.data_source.data['units'] = df['units']
                elif name == 'Notes':
                    notes_df = self.read_notes()
                    glyph_renderer = renderer
                    glyph_renderer.data_source.data['x'] = notes_df['index']
                    glyph_renderer.data_source.data['y'] = notes_df['value']
                    glyph_renderer.data_source.data['desc'] = notes_df['desc']
                    glyph_renderer.data_source.data['units'] = notes_df[0]
                    glyph_renderer.data_source.data['time'] = notes_df['time_s']