Example #1
0
class BokehPlot(object):
    def __init__(self,
                 device,
                 points_list,
                 *,
                 title='My title',
                 show_notes=True,
                 update_data=True):
        self.device = device
        if len(points_list) < 3:
            raise ValueError("Provide at least 3 objects to the chart")
        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, infos=self.device.properties)
        #curdoc().add_root(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 = "pan,box_zoom,wheel_zoom,save,reset"
        self.p = Figure(x_axis_type="datetime",
                        x_axis_label="Time",
                        y_axis_label="Numeric Value",
                        title=self.title,
                        tools=TOOLS,
                        plot_width=700,
                        plot_height=600,
                        toolbar_location='above')

        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", axis_label="Binary"),
                          'left')
        self.p.add_layout(
            LinearAxis(y_range_name="enum", axis_label="Enumerated"), 'right')
        self.p.legend.location = "bottom_left"

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

        self.sources = {}
        if len(self.lst) <= 10:
            color_mapper = dict(zip(self.lst, d3['Category10'][len(self.lst)]))
        else:
            # This would be a very loaded trend...
            color_mapper = dict(zip(self.lst, Spectral6[:len(self.lst)]))

        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=color_mapper[each],
                    legend=("%s/%s (OFF-ON)" %
                            (each, self.device[each]['description'])),
                    y_range_name="bool",
                    size=10)
            elif each in self.multi_states:
                self.p.diamond(
                    'x',
                    'y',
                    source=self.sources[each],
                    name=each,
                    color=color_mapper[each],
                    legend=("%s/%s (%s)" %
                            (each, self.device[each]['description'],
                             self.device[each].properties.units_state)),
                    y_range_name="enum",
                    size=20)
            else:
                self.p.line(
                    'x',
                    'y',
                    source=self.sources[each],
                    name=each,
                    color=color_mapper[each],
                    legend=("%s/%s (%s)" %
                            (each, self.device[each]['description'],
                             self.device[each].properties.units_state)),
                    line_width=2)
        if self.show_notes:
            columns = [
                TableColumn(field="x",
                            title="Date",
                            formatter=DateFormatter(format='yy-mm-dd')),
                TableColumn(field="units", title="Notes"),
            ]
            data_table = DataTable(source=self.notes_source, columns=columns)
            return (self.p, data_table)
        else:
            return (self.p, None)

    def update_data(self):
        if self.device.properties.network._started:
            df = self.read_lst()
            for renderer in self.p.renderers:
                name = renderer.name
                glyph_renderer = renderer
                new_data = {}
                if name in self.points_list:
                    df['name'] = ('%s / %s' %
                                  (name, self.device[name]['description']))
                    new_data['x'] = df['index']
                    new_data['y'] = df[name]
                    new_data['desc'] = df['name']
                    new_data['time'] = df['time_s']
                    if name in self.multi_states:
                        new_data['units'] = [
                            self.multi_states[name][int(math.fabs(x - 1))]
                            for x in df[name]
                        ]
                    elif name in self.binary_states:
                        new_data['y'] = df[name]
                        new_data['units'] = [
                            self.binary_states[name][int(x / 1)]
                            for x in df[name]
                        ]
                    else:
                        df['units'] = self.analog_units[name]
                        new_data['units'] = df['units']
                    glyph_renderer.data_source.data = new_data
                elif name == 'Notes':
                    notes_df = self.read_notes()
                    new_data['x'] = notes_df['index']
                    new_data['y'] = notes_df['value']
                    new_data['desc'] = notes_df['desc']
                    new_data['units'] = notes_df[0]
                    new_data['time'] = notes_df['time_s']
                    glyph_renderer.data_source.data = new_data
def plot_waveform_bokeh(filename,waveform_list,metadata_list,station_lat_list,\
                       station_lon_list, event_lat, event_lon, boundary_data, style_parameter):
    xlabel_fontsize = style_parameter['xlabel_fontsize']
    #
    map_station_location_bokeh = ColumnDataSource(data=dict(map_lat_list=station_lat_list,\
                                                            map_lon_list=station_lon_list))
    dot_default_index = 0
    selected_dot_on_map_bokeh = ColumnDataSource(data=dict(lat=[station_lat_list[dot_default_index]],\
                                                           lon=[station_lon_list[dot_default_index]],\
                                                           index=[dot_default_index]))
    map_view = Figure(plot_width=style_parameter['map_view_plot_width'], \
                      plot_height=style_parameter['map_view_plot_height'], \
                      y_range=[style_parameter['map_view_lat_min'],\
                    style_parameter['map_view_lat_max']], x_range=[style_parameter['map_view_lon_min'],\
                    style_parameter['map_view_lon_max']], tools=style_parameter['map_view_tools'],\
                    title=style_parameter['map_view_title'])
    # ------------------------------
    # add boundaries to map view
    # country boundaries
    map_view.multi_line(boundary_data['country']['longitude'],\
                        boundary_data['country']['latitude'],color='gray',\
                        line_width=2, level='underlay', nonselection_line_alpha=1.0,\
                        nonselection_line_color='gray')
    # marine boundaries
    map_view.multi_line(boundary_data['marine']['longitude'],\
                        boundary_data['marine']['latitude'],color='gray',\
                        level='underlay', nonselection_line_alpha=1.0,\
                        nonselection_line_color='gray')
    # shoreline boundaries
    map_view.multi_line(boundary_data['shoreline']['longitude'],\
                        boundary_data['shoreline']['latitude'],color='gray',\
                        line_width=2, nonselection_line_alpha=1.0, level='underlay',
                        nonselection_line_color='gray')
    # state boundaries
    map_view.multi_line(boundary_data['state']['longitude'],\
                        boundary_data['state']['latitude'],color='gray',\
                        level='underlay', nonselection_line_alpha=1.0,\
                        nonselection_line_color='gray')
    #
    map_view.triangle('map_lon_list', 'map_lat_list', source=map_station_location_bokeh, \
                      line_color='gray', size=style_parameter['marker_size'], fill_color='black',\
                      selection_color='black', selection_line_color='gray',\
                      selection_fill_alpha=1.0,\
                      nonselection_fill_alpha=1.0, nonselection_fill_color='black',\
                      nonselection_line_color='gray', nonselection_line_alpha=1.0)
    map_view.triangle('lon','lat', source=selected_dot_on_map_bokeh,\
                      size=style_parameter['selected_marker_size'], line_color='black',fill_color='red')
    map_view.asterisk([event_lon], [event_lat], size=style_parameter['event_marker_size'], line_width=3, line_color='red', \
                      fill_color='red')
    # change style
    map_view.title.text_font_size = style_parameter['title_font_size']
    map_view.title.align = 'center'
    map_view.title.text_font_style = 'normal'
    map_view.xaxis.axis_label = style_parameter['map_view_xlabel']
    map_view.xaxis.axis_label_text_font_style = 'normal'
    map_view.xaxis.axis_label_text_font_size = xlabel_fontsize
    map_view.xaxis.major_label_text_font_size = xlabel_fontsize
    map_view.yaxis.axis_label = style_parameter['map_view_ylabel']
    map_view.yaxis.axis_label_text_font_style = 'normal'
    map_view.yaxis.axis_label_text_font_size = xlabel_fontsize
    map_view.yaxis.major_label_text_font_size = xlabel_fontsize
    map_view.xgrid.grid_line_color = None
    map_view.ygrid.grid_line_color = None
    map_view.toolbar.logo = None
    map_view.toolbar_location = 'above'
    map_view.toolbar_sticky = False
    # --------------------------------------------------------
    max_waveform_length = 0
    max_waveform_amp = 0
    ncurve = len(waveform_list)
    for a_sta in waveform_list:
        for a_trace in a_sta:
            if len(a_trace) > max_waveform_length:
                max_waveform_length = len(a_trace)
            if np.max(np.abs(a_trace)) > max_waveform_amp:
                max_waveform_amp = np.max(np.abs(a_trace))
    #
    plotting_list = []
    for a_sta in waveform_list:
        temp = []
        for a_trace in a_sta:
            if len(a_trace) < max_waveform_length:
                a_trace = np.append(a_trace,np.zeros([(max_waveform_length-len(a_trace)),1]))
            temp.append(list(a_trace))
        plotting_list.append(temp)
    #
    time_list = []
    for ista in range(len(plotting_list)):
        a_sta = plotting_list[ista]
        temp = []
        for itr in range(len(a_sta)):
            a_trace = a_sta[itr]
            delta = metadata_list[ista][itr]['delta']
            time = list(np.arange(len(a_trace))*delta)
            temp.append(time)
        #
        time_list.append(temp)
    #
    reftime_label_list = []
    channel_label_list = []
    for ista in range(len(metadata_list)):
        temp_ref = []
        temp_channel = []
        a_sta = metadata_list[ista]
        for a_trace in a_sta:
            temp_ref.append('Starting from '+a_trace['starttime'])
            temp_channel.append(a_trace['network']+'_'+a_trace['station']+'_'+a_trace['channel'])
        reftime_label_list.append(temp_ref)
        channel_label_list.append(temp_channel)
    # --------------------------------------------------------
    curve_fig01 = Figure(plot_width=style_parameter['curve_plot_width'], plot_height=style_parameter['curve_plot_height'], \
                       y_range=(-max_waveform_amp*1.05,max_waveform_amp*1.05), \
                       x_range=(0,max_waveform_length),\
                    tools=['save','box_zoom','ywheel_zoom','xwheel_zoom','reset','crosshair','pan']) 
    #
    curve_index = 0
    select_curve_data = plotting_list[dot_default_index][curve_index]
    select_curve_time = time_list[dot_default_index][curve_index]
    
    selected_curve_data_bokeh01 = ColumnDataSource(data=dict(time=select_curve_time,amp=select_curve_data))
    select_reftime_label = reftime_label_list[dot_default_index][curve_index]
    selected_reftime_label_bokeh01 = ColumnDataSource(data=dict(x=[style_parameter['curve_reftime_label_x']],\
                                                                y=[style_parameter['curve_reftime_label_y']],\
                                                                label=[select_reftime_label]))
    select_channel_label = channel_label_list[dot_default_index][curve_index]
    selected_channel_label_bokeh01 = ColumnDataSource(data=dict(x=[style_parameter['curve_channel_label_x']],\
                                                                y=[style_parameter['curve_channel_label_y']],\
                                                                label=[select_channel_label]))
    all_curve_data_bokeh = ColumnDataSource(data=dict(t=time_list, amp=plotting_list))
    all_reftime_label_bokeh = ColumnDataSource(data=dict(label=reftime_label_list))
    all_channel_label_bokeh = ColumnDataSource(data=dict(label=channel_label_list))
    # plot waveform
    curve_fig01.line('time','amp', source=selected_curve_data_bokeh01,\
                   line_color='black')
    # add refference time as a label
    curve_fig01.text('x', 'y', 'label', source=selected_reftime_label_bokeh01)
    # add channel label
    curve_fig01.text('x', 'y', 'label', source=selected_channel_label_bokeh01)
    # change style
    curve_fig01.title.text_font_size = style_parameter['title_font_size']
    curve_fig01.title.align = 'center'
    curve_fig01.title.text_font_style = 'normal'
    curve_fig01.xaxis.axis_label = style_parameter['curve_xlabel']
    curve_fig01.xaxis.axis_label_text_font_style = 'normal'
    curve_fig01.xaxis.axis_label_text_font_size = xlabel_fontsize
    curve_fig01.xaxis.major_label_text_font_size = xlabel_fontsize
    curve_fig01.yaxis.axis_label = style_parameter['curve_ylabel']
    curve_fig01.yaxis.axis_label_text_font_style = 'normal'
    curve_fig01.yaxis.axis_label_text_font_size = xlabel_fontsize
    curve_fig01.yaxis.major_label_text_font_size = xlabel_fontsize
    curve_fig01.toolbar.logo = None
    curve_fig01.toolbar_location = 'above'
    curve_fig01.toolbar_sticky = False
    # --------------------------------------------------------
    curve_fig02 = Figure(plot_width=style_parameter['curve_plot_width'], plot_height=style_parameter['curve_plot_height'], \
                       y_range=(-max_waveform_amp*1.05,max_waveform_amp*1.05), \
                       x_range=(0,max_waveform_length),\
                    tools=['save','box_zoom','ywheel_zoom','xwheel_zoom','reset','crosshair','pan']) 
    #
    curve_index = 1
    select_curve_data = plotting_list[dot_default_index][curve_index]
    select_curve_time = time_list[dot_default_index][curve_index]
    selected_curve_data_bokeh02 = ColumnDataSource(data=dict(time=select_curve_time,amp=select_curve_data))
    select_channel_label = channel_label_list[dot_default_index][curve_index]
    selected_channel_label_bokeh02 = ColumnDataSource(data=dict(x=[style_parameter['curve_channel_label_x']],\
                                                                y=[style_parameter['curve_channel_label_y']],\
                                                                label=[select_channel_label]))
    # plot waveform
    curve_fig02.line('time','amp', source=selected_curve_data_bokeh02,\
                   line_color='black')
    # add channel label
    curve_fig02.text('x', 'y', 'label', source=selected_channel_label_bokeh02)
    # change style
    curve_fig02.title.text_font_size = style_parameter['title_font_size']
    curve_fig02.title.align = 'center'
    curve_fig02.title.text_font_style = 'normal'
    curve_fig02.xaxis.axis_label = style_parameter['curve_xlabel']
    curve_fig02.xaxis.axis_label_text_font_style = 'normal'
    curve_fig02.xaxis.axis_label_text_font_size = xlabel_fontsize
    curve_fig02.xaxis.major_label_text_font_size = xlabel_fontsize
    curve_fig02.yaxis.axis_label = style_parameter['curve_ylabel']
    curve_fig02.yaxis.axis_label_text_font_style = 'normal'
    curve_fig02.yaxis.axis_label_text_font_size = xlabel_fontsize
    curve_fig02.yaxis.major_label_text_font_size = xlabel_fontsize
    curve_fig02.toolbar.logo = None
    curve_fig02.toolbar_location = 'above'
    curve_fig02.toolbar_sticky = False
    # --------------------------------------------------------
    curve_fig03 = Figure(plot_width=style_parameter['curve_plot_width'], plot_height=style_parameter['curve_plot_height'], \
                       y_range=(-max_waveform_amp*1.05,max_waveform_amp*1.05), \
                       x_range=(0,max_waveform_length),\
                    tools=['save','box_zoom','ywheel_zoom','xwheel_zoom','reset','crosshair','pan']) 
    #
    curve_index = 2
    select_curve_data = plotting_list[dot_default_index][curve_index]
    select_curve_time = time_list[dot_default_index][curve_index]
    selected_curve_data_bokeh03 = ColumnDataSource(data=dict(time=select_curve_time,amp=select_curve_data))
    select_channel_label = channel_label_list[dot_default_index][curve_index]
    selected_channel_label_bokeh03 = ColumnDataSource(data=dict(x=[style_parameter['curve_channel_label_x']],\
                                                                y=[style_parameter['curve_channel_label_y']],\
                                                                label=[select_channel_label]))
    # plot waveform
    curve_fig03.line('time','amp', source=selected_curve_data_bokeh03,\
                   line_color='black')
    # add channel label
    curve_fig03.text('x', 'y', 'label', source=selected_channel_label_bokeh03)
    # change style
    curve_fig03.title.text_font_size = style_parameter['title_font_size']
    curve_fig03.title.align = 'center'
    curve_fig03.title.text_font_style = 'normal'
    curve_fig03.xaxis.axis_label = style_parameter['curve_xlabel']
    curve_fig03.xaxis.axis_label_text_font_style = 'normal'
    curve_fig03.xaxis.axis_label_text_font_size = xlabel_fontsize
    curve_fig03.xaxis.major_label_text_font_size = xlabel_fontsize
    curve_fig03.yaxis.axis_label = style_parameter['curve_ylabel']
    curve_fig03.yaxis.axis_label_text_font_style = 'normal'
    curve_fig03.yaxis.axis_label_text_font_size = xlabel_fontsize
    curve_fig03.yaxis.major_label_text_font_size = xlabel_fontsize
    curve_fig03.toolbar.logo = None
    curve_fig03.toolbar_location = 'above'
    curve_fig03.toolbar_sticky = False
    # --------------------------------------------------------
    map_station_location_js = CustomJS(args=dict(selected_dot_on_map_bokeh=selected_dot_on_map_bokeh,\
                                                            map_station_location_bokeh=map_station_location_bokeh,\
                                                            selected_curve_data_bokeh01=selected_curve_data_bokeh01,\
                                                            selected_curve_data_bokeh02=selected_curve_data_bokeh02,\
                                                            selected_curve_data_bokeh03=selected_curve_data_bokeh03,\
                                                            selected_channel_label_bokeh01=selected_channel_label_bokeh01,\
                                                            selected_channel_label_bokeh02=selected_channel_label_bokeh02,\
                                                            selected_channel_label_bokeh03=selected_channel_label_bokeh03,\
                                                            selected_reftime_label_bokeh01=selected_reftime_label_bokeh01,\
                                                            all_reftime_label_bokeh=all_reftime_label_bokeh,\
                                                            all_channel_label_bokeh=all_channel_label_bokeh,\
                                                            all_curve_data_bokeh=all_curve_data_bokeh), code="""
    var inds = cb_obj.indices
    
    selected_dot_on_map_bokeh.data['index'] = [inds]
    var new_loc = map_station_location_bokeh.data
    
    selected_dot_on_map_bokeh.data['lat'] = [new_loc['map_lat_list'][inds]]
    selected_dot_on_map_bokeh.data['lon'] = [new_loc['map_lon_list'][inds]]
    
    selected_dot_on_map_bokeh.change.emit()
    
    selected_curve_data_bokeh01.data['t'] = all_curve_data_bokeh.data['t'][inds][0]
    selected_curve_data_bokeh01.data['amp'] = all_curve_data_bokeh.data['amp'][inds][0]

    selected_curve_data_bokeh01.change.emit()
    
    selected_curve_data_bokeh02.data['t'] = all_curve_data_bokeh.data['t'][inds][1]
    selected_curve_data_bokeh02.data['amp'] = all_curve_data_bokeh.data['amp'][inds][1]

    selected_curve_data_bokeh02.change.emit()
    
    selected_curve_data_bokeh03.data['t'] = all_curve_data_bokeh.data['t'][inds][2]
    selected_curve_data_bokeh03.data['amp'] = all_curve_data_bokeh.data['amp'][inds][2]

    selected_curve_data_bokeh03.change.emit()
    
    selected_reftime_label_bokeh01.data['label'] = [all_reftime_label_bokeh.data['label'][inds][0]]
    
    selected_reftime_label_bokeh01.change.emit()
    
    selected_channel_label_bokeh01.data['label'] = [all_channel_label_bokeh.data['label'][inds][0]]
    
    selected_channel_label_bokeh01.change.emit()
    
    selected_channel_label_bokeh02.data['label'] = [all_channel_label_bokeh.data['label'][inds][1]]
    
    selected_channel_label_bokeh02.change.emit()
    
    selected_channel_label_bokeh03.data['label'] = [all_channel_label_bokeh.data['label'][inds][2]]
    
    selected_channel_label_bokeh03.change.emit()
    """)
    #
    map_station_location_bokeh.selected.js_on_change('indices', map_station_location_js)
    #
    curve_slider_callback = CustomJS(args=dict(selected_dot_on_map_bokeh=selected_dot_on_map_bokeh,\
                                                map_station_location_bokeh=map_station_location_bokeh,\
                                                selected_curve_data_bokeh01=selected_curve_data_bokeh01,\
                                                selected_curve_data_bokeh02=selected_curve_data_bokeh02,\
                                                selected_curve_data_bokeh03=selected_curve_data_bokeh03,\
                                                selected_channel_label_bokeh01=selected_channel_label_bokeh01,\
                                                selected_channel_label_bokeh02=selected_channel_label_bokeh02,\
                                                selected_channel_label_bokeh03=selected_channel_label_bokeh03,\
                                                selected_reftime_label_bokeh01=selected_reftime_label_bokeh01,\
                                                all_reftime_label_bokeh=all_reftime_label_bokeh,\
                                                all_channel_label_bokeh=all_channel_label_bokeh,\
                                                all_curve_data_bokeh=all_curve_data_bokeh),code="""
    var inds = Math.round(cb_obj.value)
    
    selected_dot_on_map_bokeh.data['index'] = [inds]
    var new_loc = map_station_location_bokeh.data
    
    selected_dot_on_map_bokeh.data['lat'] = [new_loc['map_lat_list'][inds]]
    selected_dot_on_map_bokeh.data['lon'] = [new_loc['map_lon_list'][inds]]
    
    selected_dot_on_map_bokeh.change.emit()
    
    selected_curve_data_bokeh01.data['t'] = all_curve_data_bokeh.data['t'][inds][0]
    selected_curve_data_bokeh01.data['amp'] = all_curve_data_bokeh.data['amp'][inds][0]

    selected_curve_data_bokeh01.change.emit()
    
    selected_curve_data_bokeh02.data['t'] = all_curve_data_bokeh.data['t'][inds][1]
    selected_curve_data_bokeh02.data['amp'] = all_curve_data_bokeh.data['amp'][inds][1]

    selected_curve_data_bokeh02.change.emit()
    
    selected_curve_data_bokeh03.data['t'] = all_curve_data_bokeh.data['t'][inds][2]
    selected_curve_data_bokeh03.data['amp'] = all_curve_data_bokeh.data['amp'][inds][2]

    selected_curve_data_bokeh03.change.emit()
    
    selected_reftime_label_bokeh01.data['label'] = [all_reftime_label_bokeh.data['label'][inds][0]]
    
    selected_reftime_label_bokeh01.change.emit()
    
    selected_channel_label_bokeh01.data['label'] = [all_channel_label_bokeh.data['label'][inds][0]]
    
    selected_channel_label_bokeh01.change.emit()
    
    selected_channel_label_bokeh02.data['label'] = [all_channel_label_bokeh.data['label'][inds][1]]
    
    selected_channel_label_bokeh02.change.emit()
    
    selected_channel_label_bokeh03.data['label'] = [all_channel_label_bokeh.data['label'][inds][2]]
    
    selected_channel_label_bokeh03.change.emit()
    """)
    curve_slider = Slider(start=0, end=ncurve-1, value=style_parameter['curve_default_index'], \
                          step=1, title=style_parameter['curve_slider_title'], width=style_parameter['map_view_plot_width'],\
                          height=50, callback=curve_slider_callback)
    
    # ==============================
    # annotating text
    annotating_fig01 = Div(text=style_parameter['annotating_html01'], \
        width=style_parameter['annotation_plot_width'], height=style_parameter['annotation_plot_height'])
    annotating_fig02 = Div(text=style_parameter['annotating_html02'],\
        width=style_parameter['annotation_plot_width'], height=style_parameter['annotation_plot_height'])
    # ==============================
    output_file(filename,title=style_parameter['html_title'],mode=style_parameter['library_source'])
    #
    left_fig = Column(curve_slider, map_view, annotating_fig01, width=style_parameter['left_column_width'] )
    
    right_fig = Column(curve_fig01, curve_fig02, curve_fig03, annotating_fig02, width=style_parameter['right_column_width'])
    layout = Row(left_fig, right_fig)
    save(layout)
Example #3
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']
Example #4
0
a_rad = 2.7 * rv['mstar']
rv_syms = p1.circle(rv['semi'] / a_rad,
                    rv['msini'] * mjup,
                    color='red',
                    fill_alpha=0.4,
                    line_alpha=1.,
                    size=8)

# microlens
ulens = Table.read(
    '/Users/tumlinson/Dropbox/LUVOIR_STDT/luvoir_simtools/planetspace/ulens.dat',
    format='ascii',
    names=['name', 'msini', 'semi', 'mstar'])
a_rad = 2.7 * ulens['mstar']
ulens_syms = p1.asterisk(ulens['semi'] / a_rad,
                         ulens['msini'] * mjup,
                         color='green',
                         size=8)

# imaging
ulens = Table.read(
    '/Users/tumlinson/Dropbox/LUVOIR_STDT/luvoir_simtools/planetspace/imaging.dat',
    format='ascii',
    names=['name', 'msini', 'semi', 'mstar'])
a_rad = 2.7 * ulens['mstar']
ulens_syms = p1.square(ulens['semi'] / a_rad,
                       ulens['msini'] * mjup,
                       fill_alpha=0.4,
                       line_alpha=0.9,
                       color='purple',
                       size=8)
Example #5
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']