예제 #1
0
def stop_button_click():

    print("stop")
    Stream.twitterStream.disconnect()
    global straming
    straming = False
    rdf['flash'] = 0


# def update_count():
    # start_button_click


p.x_range.on_change('end', update_lod)
start_button = Button(label="Start", button_type="primary", width=80)
start_button.on_click(start_button_click)
stop_button = Button(label="Stop", button_type="danger", width=80)
stop_button.on_click(stop_button_click)
text_input = TextInput(placeholder="Enter query here", width=400)

spacer_row = Spacer(width=450)
spacer_pad_col = Spacer(height=20)
spacer_pad_row = Spacer(width=100)
spacer_col = Spacer(height=20)
layout = column(row(
    spacer_row, text_input, start_button, stop_button, spacer_row), spacer_col, p)

main_layout = row(spacer_pad_row, column(
    spacer_pad_col, layout, spacer_pad_col), spacer_pad_row)
예제 #2
0
def make_plot(doc,
              df,
              headers,
              id_def,
              id_att,
              slider_steps,
              x_range,
              y_range,
              image_url,
              sport='football',
              anim_speed=50,
              show_dist_speed=False):
    """
            Parameters
    ---------------------------
    :param doc: Plots the graph
    :param df: Gets the user defined dataframe
    :param headers: Give the headers to the dataframe - Headers should be ["x", "y", "team_id", "player_id","time"]

    {x, y - int/float - Player location coordinates x and y
    team_id - int/string - Team Id for both attacking and defending teams
    player_id - int/string - Player Id for both attacking and defending team. Id for ball is optional
    time - int/float - Game time in seconds or any units.}

    :param id_def: Provide id of defending team
    :param id_att: Provide id of attacking team
    :param x_range: Provide x range of the pitch coordinates
    :param y_range: Provide y range of the pitch coordinates
    :param image_url: Provide the location of the background image of the pitch
    :param slider_steps: Provide the slider steps
    :param sport: (football/basketball) - Provide the sport details to change slider function - Default is football(⚽️)
                    Football allows slider timer to move from low to max (0-90 minutes),
                    while sports that have decreasing timer (12 to 0 minutes) should use "basketball".
    :param anim_speed: Provide speed of animation - milliseconds
    :param show_dist_speed: Turn on/off plotting speed and distance. Default value is False.
                        Note- Turning on speed and distance plot could make animation rending slow.

    :return: Returns the animation plot

    """
    """
            Value Errors
    ---------------------------
        
    """
    if not isinstance(df, pd.DataFrame):
        raise ValueError(
            "The expected data type of input data is a dataframe but a {} was provided."
            .format(type(df)))

    accept_dtypes_id = [int, float, str, tuple]

    if type(id_def) not in accept_dtypes_id:
        raise ValueError(
            "The expected data type for defending team-id is either integer, float "
            "or a string but {} was provided.".format(type(id_def)))

    if type(id_att) not in accept_dtypes_id:
        raise ValueError(
            "The expected data type for defending team-id is either integer, float "
            "or a string but {} was provided.".format(type(id_att)))

    if not isinstance(x_range, (list, tuple)):
        raise ValueError(
            "The expected data type for x-range is a list but a {} was provided."
            .format(type(x_range)))

    if not isinstance(y_range, (list, tuple)):
        raise ValueError(
            "The expected data type for y-range is a list but a {} was provided."
            .format(type(y_range)))

    if len(x_range) != 2:
        raise ValueError(
            "Length of x range of coordinates is {} but expected length is 2.".
            format(len(x_range)))

    if len(y_range) != 2:
        raise ValueError(
            "Length of y range of coordinates is {} but expected length is 2.".
            format(len(x_range)))

    if sport not in ['football', 'basketball']:
        raise ValueError(
            "Only football/basketball in accepted as input for sport type, but {} was provided."
            .format(sport))

    if not isinstance(image_url, list):
        image_url = [image_url]

    all_team = pd.DataFrame(df, columns=headers)

    all_team['x'] = pd.to_numeric(all_team['x'])
    all_team['y'] = pd.to_numeric(all_team['y'])
    all_team['time'] = pd.to_numeric(all_team['time'])
    all_team['player_id'] = all_team['player_id'].apply(str)

    all_team['team_id'] = np.where(
        ((all_team['team_id'] != id_att) & (all_team['team_id'] != id_def)),
        -99, all_team['team_id'])
    all_team['player_id'] = np.where(
        ((all_team['team_id'] != id_att) & (all_team['team_id'] != id_def)),
        " ", all_team['player_id'])

    if sport == 'basketball':
        all_team['time'] = -all_team['time']
        all_team = all_team.sort_values(['time', 'team_id', 'player_id'],
                                        ascending=[False, False, True
                                                   ]).reset_index(drop=True)
    else:
        all_team['time'] = all_team['time']
        all_team = all_team.sort_values(['time', 'team_id', 'player_id'],
                                        ascending=[True, False, True
                                                   ]).reset_index(drop=True)

    team_def = all_team[all_team.team_id == id_def]
    team_att = all_team[all_team.team_id == id_att]

    if team_def.empty:
        raise ValueError(
            "Defending team ID is not valid. Please enter a valid team ID")

    elif team_att.empty:
        raise ValueError(
            "Attacking team ID is not valid. Please enter a valid team ID")

    current_time = all_team['time'].min()

    coord_x = all_team[all_team.time == current_time]['x']
    coord_y = all_team[all_team.time == current_time]['y']

    vor_points = list(zip(coord_x, coord_y))
    vor = Voronoi(vor_points)
    x_patch, y_patch, x_vor_ls, y_vor_ls = patches_from_voronoi(vor)
    """
       Create the convex hull for the coordinates

    """
    def get_convex_hull(team_def, team_att, current_time):

        team_att_t = np.vstack((team_att[team_att.time == current_time].x,
                                team_att[team_att.time == current_time].y)).T
        team_def_t = np.vstack((team_def[team_def.time == current_time].x,
                                team_def[team_def.time == current_time].y)).T

        hull = ConvexHull(team_att_t)
        hull2 = ConvexHull(team_def_t)

        team_att_ch_x = team_att_t[hull.vertices, 0]
        team_att_ch_y = team_att_t[hull.vertices, 1]

        team_def_ch_x = team_def_t[hull2.vertices, 0]
        team_def_ch_y = team_def_t[hull2.vertices, 1]

        return team_att_ch_x, team_att_ch_y, team_def_ch_x, team_def_ch_y

    source_vor = ColumnDataSource(dict(xs=x_patch, ys=y_patch))
    source_vor_ls = ColumnDataSource(dict(xs=x_vor_ls, ys=y_vor_ls))

    team_att_ch_x, team_att_ch_y, team_def_ch_x, team_def_ch_y = get_convex_hull(
        team_def, team_att, current_time)

    player_id = all_team[all_team['time'] == current_time]['player_id']

    c = (['dodgerblue'] * len(team_def['player_id'].unique()) +
         ['orangered'] * len(team_att['player_id'].unique()) + ['gold'])

    source_coord = ColumnDataSource(
        data=dict(x=coord_x, y=coord_y, player_id=player_id, color=c))
    source_ch_att = ColumnDataSource(
        data=dict(xc=team_att_ch_x, yc=team_att_ch_y))
    source_ch_def = ColumnDataSource(
        data=dict(ax=team_def_ch_x, ay=team_def_ch_y))
    """
    Below code for travel distance and speed taken from 
    http://savvastjortjoglou.com/nba-play-by-play-movements.html and modified accordingly
    
    """

    def travel_dist(player_locations):

        diff = np.diff(player_locations, axis=0)

        dist = np.sqrt((diff**2).sum(axis=1))

        return np.round(dist.sum())

    def get_distance(team_def, team_att, i):

        if sport == 'football':
            team_def_k = team_def[(team_def.time >= 0) & (team_def.time <= i)]
        elif sport == 'basketball':
            team_def_k = team_def[(team_def.time >= team_def.time.min())
                                  & (team_def.time <= i)]

        def_dist = team_def_k.groupby('player_id')[[
            'x', 'y'
        ]].apply(travel_dist).values
        avg_speed_def = np.abs(
            np.round((def_dist / (i - team_def.time.min())), 2))

        if sport == 'football':
            team_att_k = team_att[(team_att.time >= 0) & (team_att.time <= i)]
        elif sport == 'basketball':
            team_att_k = team_att[(team_att.time >= team_def.time.min())
                                  & (team_att.time <= i)]

        def_dist_att = team_att_k.groupby('player_id')[[
            'x', 'y'
        ]].apply(travel_dist).values
        avg_speed_att = np.abs(
            np.round((def_dist_att / (i - team_att.time.min())), 2))

        return def_dist, avg_speed_def, def_dist_att, avg_speed_att

    def_dist, avg_speed_def, def_dist_att, avg_speed_att = get_distance(
        team_def, team_att, current_time)

    source_def_params = ColumnDataSource(data=dict(
        x=team_def.player_id.unique(), y=def_dist, speed=avg_speed_def))
    source_att_params = ColumnDataSource(data=dict(
        x=team_att.player_id.unique(), y=def_dist_att, speed=avg_speed_att))
    """
    Remove plot background and alter other styles
    
    """

    def plot_clean(plot):

        plot.xgrid.grid_line_color = None
        plot.ygrid.grid_line_color = None
        plot.axis.major_label_text_font_size = "10pt"
        plot.axis.major_label_standoff = 0
        plot.border_fill_color = "white"
        plot.title.text_font = "times"
        plot.title.text_font_size = '10pt'
        plot.background_fill_color = "white"
        plot.title.align = 'center'
        return plot

    plot = figure(name='base',
                  plot_height=550,
                  plot_width=850,
                  title="Game Animation",
                  tools="reset,save",
                  x_range=x_range,
                  y_range=y_range,
                  toolbar_location="below")

    image_min_x, image_min_y, image_max_x, image_max_y = min(x_range), min(y_range), \
                                                         (abs(x_range[0]) + abs(x_range[1])), \
                                                         (abs(y_range[0]) + abs(y_range[1]))

    plot.image_url(url=image_url,
                   x=image_min_x,
                   y=image_min_y,
                   w=image_max_x,
                   h=image_max_y,
                   anchor="bottom_left")

    plot.scatter('x', 'y', source=source_coord, size=20, fill_color='color')

    labels = LabelSet(x='x',
                      y='y',
                      text='player_id',
                      source=source_coord,
                      y_offset=-30,
                      render_mode='canvas',
                      text_color='black',
                      text_font_size="9pt",
                      text_align='center')

    plot.add_layout(labels)
    plot.axis.visible = False
    plot = plot_clean(plot)
    """
    Plot the distance figure
    """
    plot_distance_def = figure(name='distance',
                               plot_height=250,
                               plot_width=250,
                               tools="reset,save",
                               x_axis_type='linear',
                               y_range=source_def_params.data['x'].astype(str),
                               toolbar_location="below")

    plot_distance_def.hbar(y='x',
                           right='y',
                           source=source_def_params,
                           left=0,
                           height=0.5,
                           color='dodgerblue')

    plot_distance_def.xaxis.visible = True
    plot_distance_def.yaxis.visible = True
    plot_distance_def.toolbar.logo = None
    plot_distance_def.toolbar_location = None
    plot_distance_def.add_layout(
        Title(text="Blue team", text_font_size="10pt", text_font='times'),
        'above')
    plot_distance_def.add_layout(
        Title(text="Total distance covered",
              text_font_size="10pt",
              text_font='times'), 'above')

    plot_distance_def = plot_clean(plot_distance_def)

    labels_dist_red = LabelSet(x='y',
                               y='x',
                               text='y',
                               level='glyph',
                               x_offset=-20,
                               y_offset=-9,
                               source=source_def_params,
                               render_mode='css',
                               text_color='white',
                               text_font_size="8pt",
                               text_font_style='bold')

    plot_distance_def.add_layout(labels_dist_red)

    avg_speed_def = figure(name='distance',
                           plot_height=250,
                           plot_width=250,
                           title="Avg Speed of Blue Team",
                           tools="reset,save",
                           y_range=source_def_params.data['x'].astype(str),
                           toolbar_location="below")

    avg_speed_def.hbar(y='x',
                       right='speed',
                       source=source_def_params,
                       height=0.5,
                       color='dodgerblue')

    avg_speed_def.xaxis.visible = True
    avg_speed_def.yaxis.visible = True
    avg_speed_def.toolbar.logo = None
    avg_speed_def.toolbar_location = None

    avg_speed_def = plot_clean(avg_speed_def)

    labels_speed_red = LabelSet(x='speed',
                                y='x',
                                text='speed',
                                level='glyph',
                                x_offset=-20,
                                y_offset=-9,
                                source=source_def_params,
                                render_mode='css',
                                text_color='white',
                                text_font_size="8pt",
                                text_font_style='bold')

    avg_speed_def.add_layout(labels_speed_red)
    """
       Plot the distance figure
    """
    plot_distance_att = figure(name='distance',
                               plot_height=250,
                               plot_width=250,
                               y_range=source_att_params.data['x'].astype(str),
                               toolbar_location="below")

    plot_distance_att.hbar(y='x',
                           right='y',
                           source=source_att_params,
                           height=0.5,
                           color='orangered')

    plot_distance_att.xaxis.visible = True
    plot_distance_att.yaxis.visible = True
    plot_distance_att.toolbar.logo = None
    plot_distance_att.toolbar_location = None
    plot_distance_att.add_layout(
        Title(text="Red Team", text_font_size="10pt", text_font='times'),
        'above')
    plot_distance_att.add_layout(
        Title(text="Total distance covered",
              text_font_size="10pt",
              text_font='times'), 'above')
    plot_distance_att = plot_clean(plot_distance_att)

    labels_dist_red_att = LabelSet(x='y',
                                   y='x',
                                   text='y',
                                   level='glyph',
                                   x_offset=-20,
                                   y_offset=-9,
                                   source=source_att_params,
                                   render_mode='css',
                                   text_color='white',
                                   text_font_size="8pt",
                                   text_font_style='bold')

    plot_distance_att.add_layout(labels_dist_red_att)

    avg_speed_att = figure(name='avg_speed',
                           plot_height=250,
                           plot_width=250,
                           title="Avg Speed of Red Team",
                           tools="reset,save",
                           y_range=source_att_params.data['x'].astype(str),
                           toolbar_location="below")

    avg_speed_att.hbar(y='x',
                       right='speed',
                       source=source_att_params,
                       height=0.5,
                       color='orangered')

    avg_speed_att.xaxis.visible = True
    avg_speed_att.yaxis.visible = True
    avg_speed_att.toolbar.logo = None
    avg_speed_att.toolbar_location = None
    avg_speed_att = plot_clean(avg_speed_att)

    labels_speed_red_att = LabelSet(x='speed',
                                    y='x',
                                    text='speed',
                                    level='glyph',
                                    x_offset=-20,
                                    y_offset=-9,
                                    source=source_att_params,
                                    render_mode='css',
                                    text_color='white',
                                    text_font_size="8pt",
                                    text_font_style='bold')

    avg_speed_att.add_layout(labels_speed_red_att)

    slider_start = all_team.time.unique().min()
    slider_end = all_team.time.unique().max()
    game_time = Slider(title="Game Time (seconds)",
                       value=slider_start,
                       start=slider_start,
                       end=slider_end,
                       step=slider_steps)
    """
       Update the figure every time slider is updated.
    """

    def update_data(attrname, old, new):

        slider_value = np.round(game_time.value, 2)

        coord_x = all_team[all_team.time == slider_value]['x']
        coord_y = all_team[all_team.time == slider_value]['y']

        vor_points = list(zip(coord_x, coord_y))
        vor = Voronoi(vor_points)
        x_patch, y_patch, x_vor_ls, y_vor_ls = patches_from_voronoi(vor)

        source_vor.data = dict(xs=x_patch, ys=y_patch)
        source_vor_ls.data = dict(xs=x_vor_ls, ys=y_vor_ls)

        team_att_ch_x, team_att_ch_y, team_def_ch_x, team_def_ch_y = get_convex_hull(
            team_def, team_att, slider_value)

        source_coord.data = dict(x=coord_x,
                                 y=coord_y,
                                 player_id=player_id,
                                 color=c)
        source_ch_att.data = dict(xc=team_att_ch_x, yc=team_att_ch_y)
        source_ch_def.data = dict(ax=team_def_ch_x, ay=team_def_ch_y)

        def_dist, avg_speed_def, def_dist_att, avg_speed_att = get_distance(
            team_def, team_att, slider_value)

        source_def_params.data = dict(x=team_def.player_id.unique(),
                                      y=def_dist,
                                      speed=avg_speed_def)
        source_att_params.data = dict(x=team_att.player_id.unique(),
                                      y=def_dist_att,
                                      speed=avg_speed_att)

    for w in [game_time]:
        w.on_change('value', update_data)
    """
       Animation
    """

    def animate_update():

        time = game_time.value + slider_steps
        if time > all_team.time.max():
            time = all_team.time.min()
        game_time.value = time

    callback_id = None

    def animate():
        global callback_id
        if button.label == '► Play':
            button.label = '❚❚ Pause'
            callback_id = curdoc().add_periodic_callback(
                animate_update, anim_speed)
        else:
            button.label = '► Play'
            curdoc().remove_periodic_callback(callback_id)

    button = Button(label='► Play', width=60)
    button.on_click(animate)
    """
       Plot the patches for voronoi and convex hull
    """
    team_att_patch = plot.patch('xc',
                                'yc',
                                source=source_ch_att,
                                alpha=0,
                                line_width=3,
                                fill_color='orangered')
    team_def_patch = plot.patch('ax',
                                'ay',
                                source=source_ch_def,
                                alpha=0,
                                line_width=3,
                                fill_color='dodgerblue')

    glyph_vor = plot.patches('xs',
                             'ys',
                             source=source_vor,
                             alpha=0,
                             line_width=1,
                             fill_color='dodgerblue',
                             line_color='black')
    glyph_ls = plot.multi_line('xs',
                               'ys',
                               source=source_vor_ls,
                               alpha=0,
                               line_width=1,
                               line_color='black')

    checkbox_def = CheckboxButtonGroup(labels=["Team Defend"], width=100)
    checkbox_att = CheckboxButtonGroup(labels=["Team Attack"], width=100)
    checkbox_vor = CheckboxButtonGroup(labels=["Voronoi"], width=100)

    checkbox_def.callback = CustomJS(args=dict(l0=team_def_patch,
                                               checkbox=checkbox_def),
                                     code="""
        l0.visible = 0 in checkbox.active;
        l0.glyph.fill_alpha = 0.3;
        """)

    checkbox_att.callback = CustomJS(args=dict(l0=team_att_patch,
                                               checkbox=checkbox_att),
                                     code="""
        l0.visible = 0 in checkbox.active;
        l0.glyph.fill_alpha = 0.3;
        """)

    checkbox_vor.callback = CustomJS(args=dict(l0=glyph_vor,
                                               l1=glyph_ls,
                                               checkbox=checkbox_vor),
                                     code="""
        l0.visible = 0 in checkbox.active;
        l0.glyph.fill_alpha = .1;
        l0.glyph.line_alpha = 1;
        l1.visible = 0 in checkbox.active;
        l1.glyph.fill_alpha = .1;
        l1.glyph.line_alpha = 1;
        """)

    text_p = Paragraph(text="""Select a team to visualize convex hull""",
                       width=250)

    inputs = widgetbox(
        row(column(game_time, button),
            row(column(text_p, row(checkbox_def, checkbox_att)),
                checkbox_vor)))
    """
       Plot the speed and distance if true
    """
    if not show_dist_speed:
        layout = column(row(column(plot, inputs)))
    else:
        layout = column(
            row(
                column(plot, inputs),
                row(column(plot_distance_def, avg_speed_def),
                    column(plot_distance_att, avg_speed_att))))

    doc.add_root(layout)
    doc.title = "Game Animation"

    return doc
예제 #3
0
L2 = lProvince
L3 = L1

y1=df1.iloc[iSelect,4:maxKolom]
y2=df2.iloc[iSelect,4:maxKolom]
y3=df3.iloc[iSelect,4:maxKolom]
x1=[x1 for x1 in range(0,len(y1))]
mydates=y2.index.values
nBaris=len(lCountry)-1
nKolom=len(x1)-1

#print(z1)
# ------------------------------------------------------------------------------
# A = Button + Radio Grup
# ------------------------------------------------------------------------------
mybtn11 = Button(label="Confirmed Case", name="11", height=70, width=150)
mybtn12 = Button(label="Country = 1", name="12", width=120)

def myhandler1a(attr,old,new):
  mybtn12.label = "Country = " + str(nSum[new])

mylabels=["1-99", "100-999", "1.000-9.999", " 10.000-99.999", "100.000-499.999", " > 500.000", "ALL"]
myradio_group = RadioGroup(labels=mylabels, active=5, width=150)
myradio_group.on_change('active', myhandler1a)

mybtn15 = Button(label="Confirmed = 1176", name="12", width=120)
mybtn16 = Button(label="Recovered = 166", name="12", width=120)
mybtn17 = Button(label="Death = 140", name="12", width=120)

# ------------------------------------------------------------------------------
# B = Peta + Data
예제 #4
0
df_historic = pd.DataFrame(columns=[
    'slot_1', 'slot_2', 'slot_3', 'slot_4', 'correct_elements',
    'correctly_positioned', 'try'
])

# Button to choose the color in first, second, third and fourth position
slot_1 = RadioGroup(labels=COLORS, active=None, name='Place 1')
slot_2 = RadioGroup(labels=COLORS, active=None, name='Place 2')
slot_3 = RadioGroup(labels=COLORS, active=None, name='Place 3')
slot_4 = RadioGroup(labels=COLORS, active=None, name='Place 4')

# List of slots
list_slots = [slot_1, slot_2, slot_3, slot_4]

# Check button to have feedback on current proposal
check = Button(label="Check", button_type="success")

# Restart button
restart = Button(label="Restart", button_type="success")

# Current iteration
current_try = 0


# Function triggered when the "check" button is clicked on
def check_button():
    '''
    This function collects the current proposition, then plots the feedback and the current proposition.
    '''
    global current_try, df_historic, true_combination, p, ds
예제 #5
0
from bokeh.plotting import show, output_file
from bokeh.layouts import column
from bokeh.models import CustomJS
from bokeh.models.widgets import Button
from fontawesome_icon import FontAwesomeIcon

btn = Button(icon=FontAwesomeIcon(icon_name="thumbs-o-up", size=2),
             label="It works!",
             callback=CustomJS(code="alert('It works!');"))
show(column(btn))
예제 #6
0
###-----------------------------------------------------------------------###
###----------------------GRAPHICAL USER INTERFACE-------------------------###
### This code defines the Bokeh controls that are used for the user       ###
### interface. All the defaults for the controls are above. This code     ###
### should not need to be modified. ("View" Part 2)                       ###
###-----------------------------------------------------------------------###
# Plot- Regression Data
plot_data = figure(plot_height=300,
                   plot_width=600,
                   title="Regression Data",
                   toolbar_location="above",
                   x_axis_label='X',
                   y_axis_label='Y',
                   tools="pan,save,box_zoom,wheel_zoom")
# Plot Control Buttons
plot_sim = Button(label="Simulate")
plot_clear = Button(label="Clear")
plot_ctls = column(plot_sim, plot_clear)
# Main Control Buttons
ctl_title = Div(text="<h3>Parameters</h3>")
ctl_nsamp = Slider(title="Number of Samples",
                   value=d_nsamp,
                   start=r_nsamp[0],
                   end=r_nsamp[1],
                   step=r_nsamp[2])
ctl_bias = Slider(title="Bias",
                  value=d_bias,
                  start=r_bias[0],
                  end=r_bias[1],
                  step=r_bias[2])
ctl_noise = Slider(title="Noise",
예제 #7
0
from bokeh.io import output_file, show
from bokeh.layouts import row, column, layout
from bokeh.plotting import figure, curdoc
from bokeh.layouts import widgetbox
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import Button, RadioButtonGroup, Select, Slider, TextInput
from bokeh.models.widgets import RadioGroup, CheckboxGroup, MultiSelect, Dropdown
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn, Panel, Tabs
from bokeh.models.widgets import Paragraph
from bokeh.events import ButtonClick
from datetime import date
from random import randint
import string

refresh = Button(label="Refresh")
btnGroupTitle = RadioButtonGroup(
    name='title',
    labels=["begins with...", "...contains...", "...ends with"],
    active=1)
btnGroupDept = RadioButtonGroup(
    name='dept',
    labels=["begins with...", "...contains...", "...ends with"],
    active=1)
paragraph = Paragraph(text="option")
optionGroup = RadioGroup(labels=["and", "or"],
                         active=0,
                         width=100,
                         inline=True)
btnGroupLetters = RadioButtonGroup(labels=list(string.ascii_uppercase),
                                   active=-1)
title_input = TextInput(value="", title="Title:", placeholder="contains....")
예제 #8
0
plot_wei_index.title.text_font = 'Microsoft Yahei'
plot_wei_index.vbar(x='date',
                    top='val',
                    bottom=0,
                    width=1,
                    source=source_wei_index)
# plot_wei_index.line('date', 'val', source=source_wei_index, line_width=3, legend=plot_wei_index.title.text)

plot_blank = figure(plot_height=200, plot_width=1200, tools=[])

update_all()
update_momentum_statistics()

asset_text_1 = TextInput(value="881001.WI", title=u"资产一", width=300)
asset_text_2 = TextInput(value="HSI.HI", title=u"资产二", width=300)
update_button = Button(label=u"计算相关性", width=300, button_type="success")
update_button.on_click(update_correlation)
asset_row = row(asset_text_1, asset_text_2, update_button)
department_industry_row = row(department_select, industry_select)
liquidity_row = row(liquidity_select, index_select)

inputs = widgetbox(time_text, time_end_text, asset_select)

curdoc().add_root(
    column(
        inputs,
        plot_momentum,
        plot_sharpe,
        plot_price,
        plot_mom,
        plot_vol,
예제 #9
0
    def __init__(self, sources, categories, dvhs, rad_bio, roi_viewer, time_series,
                 correlation, regression, mlc_analyzer, custom_title, data_tables):
        self.sources = sources
        self.selector_categories = categories.selector
        self.range_categories = categories.range
        self.correlation_variables = categories.correlation_variables
        self.dvhs = dvhs
        self.rad_bio = rad_bio
        self.roi_viewer = roi_viewer
        self.time_series = time_series
        self.correlation = correlation
        self.regression = regression
        self.mlc_analyzer = mlc_analyzer

        self.uids = {n: [] for n in GROUP_LABELS}
        self.allow_source_update = True
        self.current_dvh = []
        self.anon_id_map = []
        self.colors = itertools.cycle(palette)

        # !!!!!!!!!!!!!!!!!!!!!!!!!!!!
        # Selection Filter UI objects
        # !!!!!!!!!!!!!!!!!!!!!!!!!!!!
        category_options = list(self.selector_categories)
        category_options.sort()

        # Add Current row to source
        self.add_selector_row_button = Button(label="Add Selection Filter", button_type="primary", width=200)
        self.add_selector_row_button.on_click(self.add_selector_row)

        # Row
        self.selector_row = Select(value='1', options=['1'], width=50, title="Row")
        self.selector_row.on_change('value', self.selector_row_ticker)

        # Category 1
        self.select_category1 = Select(value="ROI Institutional Category", options=category_options, width=300,
                                       title="Category 1")
        self.select_category1.on_change('value', self.select_category1_ticker)

        # Category 2
        cat_2_sql_table = self.selector_categories[self.select_category1.value]['table']
        cat_2_var_name = self.selector_categories[self.select_category1.value]['var_name']
        self.category2_values = DVH_SQL().get_unique_values(cat_2_sql_table, cat_2_var_name)
        self.select_category2 = Select(value=self.category2_values[0], options=self.category2_values, width=300,
                                       title="Category 2")
        self.select_category2.on_change('value', self.select_category2_ticker)

        # Misc
        self.delete_selector_row_button = Button(label="Delete", button_type="warning", width=100)
        self.delete_selector_row_button.on_click(self.delete_selector_row)
        self.group_selector = CheckboxButtonGroup(labels=["Group 1", "Group 2"], active=[0], width=180)
        self.group_selector.on_change('active', self.ensure_selector_group_is_assigned)
        self.selector_not_operator_checkbox = CheckboxGroup(labels=['Not'], active=[])
        self.selector_not_operator_checkbox.on_change('active', self.selector_not_operator_ticker)

        # !!!!!!!!!!!!!!!!!!!!!!!!!!!!
        # Range Filter UI objects
        # !!!!!!!!!!!!!!!!!!!!!!!!!!!!
        category_options = list(self.range_categories)
        category_options.sort()

        # Add Current row to source
        self.add_range_row_button = Button(label="Add Range Filter", button_type="primary", width=200)
        self.add_range_row_button.on_click(self.add_range_row)

        # Row
        self.range_row = Select(value='', options=[''], width=50, title="Row")
        self.range_row.on_change('value', self.range_row_ticker)

        # Category
        self.select_category = Select(value=options.SELECT_CATEGORY_DEFAULT, options=category_options, width=240, title="Category")
        self.select_category.on_change('value', self.select_category_ticker)

        # Min and max
        self.text_min = TextInput(value='', title='Min: ', width=150)
        self.text_min.on_change('value', self.min_text_ticker)
        self.text_max = TextInput(value='', title='Max: ', width=150)
        self.text_max.on_change('value', self.max_text_ticker)

        # Misc
        self.delete_range_row_button = Button(label="Delete", button_type="warning", width=100)
        self.delete_range_row_button.on_click(self.delete_range_row)
        self.group_range = CheckboxButtonGroup(labels=["Group 1", "Group 2"], active=[0], width=180)
        self.group_range.on_change('active', self.ensure_range_group_is_assigned)
        self.range_not_operator_checkbox = CheckboxGroup(labels=['Not'], active=[])
        self.range_not_operator_checkbox.on_change('active', self.range_not_operator_ticker)

        self.query_button = Button(label="Query", button_type="success", width=100)
        self.query_button.on_click(self.update_data)

        # define Download button and call download.js on click
        menu = [("All Data", "all"), ("Lite", "lite"), ("Only DVHs", "dvhs"), ("Anonymized DVHs", "anon_dvhs")]
        self.download_dropdown = Dropdown(label="Download", button_type="default", menu=menu, width=100)
        self.download_dropdown.callback = CustomJS(args=dict(source=sources.dvhs,
                                                             source_rxs=sources.rxs,
                                                             source_plans=sources.plans,
                                                             source_beams=sources.beams),
                                                   code=open(join(dirname(dirname(__file__)), "download.js")).read())

        self.layout = column(Div(text="<b>DVH Analytics v%s</b>" % options.VERSION),
                             row(custom_title['1']['query'], Spacer(width=50), custom_title['2']['query'],
                                 Spacer(width=50), self.query_button, Spacer(width=50), self.download_dropdown),
                             Div(text="<b>Query by Categorical Data</b>", width=1000),
                             self.add_selector_row_button,
                             row(self.selector_row, Spacer(width=10), self.select_category1, self.select_category2,
                                 self.group_selector, self.delete_selector_row_button, Spacer(width=10),
                                 self.selector_not_operator_checkbox),
                             data_tables.selection_filter,
                             Div(text="<hr>", width=1050),
                             Div(text="<b>Query by Numerical Data</b>", width=1000),
                             self.add_range_row_button,
                             row(self.range_row, Spacer(width=10), self.select_category, self.text_min,
                                 Spacer(width=30),
                                 self.text_max, Spacer(width=30), self.group_range,
                                 self.delete_range_row_button, Spacer(width=10), self.range_not_operator_checkbox),
                             data_tables.range_filter)
예제 #10
0
    def __init__(self,
                 name="name",
                 properties=[],
                 properties_telemetry=[],
                 output_path=None):
        self.N = 10
        self.antialias = 10
        self.name = name
        self.output_path = output_path
        reset_output()
        self.event_stack = Queue()

        # open a session to keep our local document in sync with server
        # TODO pass session_id = name to give a name -> doen't work propelry
        # the zoom gets broken
        self.session = push_session(curdoc())

        # This is important! Save curdoc() to make sure all threads
        # see then same document.
        curdoc().title = name
        curdoc().session_id = name
        output_file(name + ".html")
        self.doc = curdoc()

        self.progress = LinkedPlot(mainPlot=self,
                                   names=properties,
                                   plot_width=window_width,
                                   plot_height=110)
        self.disp_text = """
                         Terminal:

                         """

        # need tabs? othewise scretch
        if 1:
            # tab1
            c = column([self.progress.widget])
            tab1 = Panel(child=c, title="Training progress")

            # tab2
            # button
            self.button = Button(label="Enable", button_type="success")
            self.button.on_click(self.button_click_handler)
            self.button_save = Button(label="Save", button_type="success")
            self.button_save.on_click(self.button_save_click_handler)
            # label
            self.pre = PreText(text=self.disp_text,
                               width=window_width,
                               height=300)
            tab2_c = column([self.pre])
            tab2 = Panel(child=tab2_c, title="Dash board")

            # tab4 testing linked plots
            self.telemetry = LinkedPlot(mainPlot=self,
                                        names=properties_telemetry,
                                        plot_width=window_width,
                                        plot_height=110,
                                        enabled=True)
            telemetry_tab = Panel(child=column(
                [row([self.button, self.button_save]), self.telemetry.widget]),
                                  title="Live Telemetry")

            tabs = [telemetry_tab, tab1, tab2]
            self.tabs = Tabs(tabs=tabs)
            self.layout = self.tabs
        else:
            c = column([i.plot for i in self.plots], sizing_mode='scale_width')
            self.layout = c

        self.step = 0
        thread = Thread(target=self.show)
        thread.start()
예제 #11
0
                         options=invest_type_selections)
invtype1_select.on_change('value', lambda attr, old, new: update_inputs())
invtype2_select = Select(value=bond_type_selections[0],
                         title=u'基金二级投资分类',
                         width=200,
                         options=bond_type_selections)
scale_select = Select(value=scale_selections[0],
                      title=u'基金资产净值',
                      width=200,
                      options=scale_selections)
time_select = Select(value=u'1年',
                     title=u'业绩时间窗口',
                     width=200,
                     options=time_selections)
time_select.on_change('value', lambda attr, old, new: update_data())
fund_button = Button(label=u"筛选基金", button_type="success", width=200)
fund_button.on_click(select_fund)
update_button = Button(label=u'更新数据', button_type='success', width=200)
update_button.on_click(update_new_data)
fund_text = TextInput(value='000088.OF', title=u'基金Wind代码', width=200)
fund_text.on_change('value', lambda attr, old, new: update_data())

columns = [
    TableColumn(field='sec_name', title=u'基金简称'),
    TableColumn(field='wind_code', title=u'万得代码'),
    TableColumn(field='fundmanager', title=u'基金经理'),
    TableColumn(field='netasset',
                title=u'基金资产净值',
                formatter=NumberFormatter(format='$0,0.00')),
    TableColumn(field='current return',
                title=u'当前业绩',
예제 #12
0
from sqlalchemy import create_engine
from bokeh.charts import Histogram,output_file,show
from bokeh.plotting import curdoc,figure
from bokeh.models.widgets import Button,Slider
from bokeh.layouts import column,row,widgetbox
import pandas as pd

engine = create_engine('mysql+mysqldb://root:root@localhost/squidlog')
db_conn = engine.connect()
sql = "select url,cur_file_sz from access_status where hit = 'TCP_HSD_HIT'"
df = pd.read_sql(sql,db_conn)

#slider
sliderL1 = Slider(start=0,end=10240,value=1024,step=1024,title="L1")
sliderL2 = Slider(start=10240,end=10*1024*1024,step=1024*1024,title="L2")
button_refresh = Button(label="Fresh")
widget_box = widgetbox(sliderL1,sliderL2,button_refresh)
#figure times 
b1 = int()
b2 = int()
b3 = int()
l1 = 1024
l2 = 5*1024*1024
p = figure(width=400,height=400)
pvbar=p.vbar (x=[1,2,3],width=0.5,bottom=0,top=[b1,b2,b3],color="firebrick")
p2 = figure(width=400)
pvbar2=p2.vbar(x=[1,2,3],width=0.5,bottom=0,top=[b1,b2,b3],color="firebrick")


def get_times():
    global b1,b2,b3
예제 #13
0
from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.models.widgets import TextInput, Button, Paragraph

# create some widgets
button = Button(label="Say HI")
input = TextInput(value="Bokeh")
output = Paragraph()


# add a callback to a widget
def update():
    output.text = "Hello, " + input.value


button.on_click(update)

# create a layout for everything
layout = column(button, input, output)

# add the layout to curdoc
curdoc().add_root(layout)
예제 #14
0
def update_owned_0(attrname, old, new):
    btc_owned_0.value = float(btc_f_owned_0.value) * total_btc

def set_default_settings():
    set_miner_settings(default_mining_power, default_discount, default_rate)

def set_miner_settings(alpha, gamma, x_rate):
    mining_power.value = alpha
    discount_rate.value = gamma
    exchange_rate.value = x_rate

for w in [mining_power, discount_rate, exchange_rate, btc_f_owned_0, btc_f_stolen]:
    w.on_change('value', update_default)

btc_f_stolen.on_change('value', update_stolen)
btc_stolen.on_change('value', update_f_stolen)

btc_f_owned_0.on_change('value', update_owned_0)
btc_owned_0.on_change('value', update_f_owned_0)

default_button = Button(label='Default Miner')
default_button.on_click(set_default_settings)

# Set up layouts and add to document
inputs = widgetbox(mining_power, discount_rate, btc_owned_0, btc_f_owned_0, btc_stolen, btc_f_stolen, exchange_rate)

curdoc().add_root(row(inputs, plot, width=doc_width))
curdoc().add_root(row(default_button, width=doc_width))
curdoc().title = "Sliders"
# example for coupled plots
#         layout = hv.Layout(largeData_line_plot(_pipe__TOF_single, title="TOF single shots - LIVE") + largeData_line_plot(_pipe__TOF_single, title="TOF single shots - LIVE 2", cmap=['red'])).cols(1)
## TOF
bokeh_live_tof =  largeData_line_plot(_pipe__TOF_single, title="TOF single shots - LIVE", width = 500, height=500) 
bokeh_buffer_tof_integral = smallData_line_plot(_pipe__TOF_integral, title="TOF trace full range integral (absolute)", xlim=(None,None), ylim=(0, None), width = 400, height = 250)
## pnCCD
bokeh_live_pnCCD =  pnCCDData_plot(_pipe__pnCCD_single, title="pnCCD single shots - LIVE", width = 500, height =500) 
bokeh_buffer_pnCCD_integral = smallData_line_plot(_pipe__pnCCD_integral, title="pnCCD single shots integral", xlim=(None,None), ylim=(0, None), width = 500, height = 250)
bokeh_hits_pnCCD_list = list()
for i in range(len(_pipe__pnCCD_hits_list)):
    bokeh_hits_pnCCD_list.append(pnCCDData_plot(_pipe__pnCCD_hits_list[i], title="pnCCD Most Recent Hits "+str(i), width=370, height=370))
## GMD
bokeh_buffer_gmd_history = smallData_line_plot(_pipe__GMD_history, title="pulseE last 1000 Trains", xlim=(None,None), ylim=(0, None), width = 400, height =250)

## SET UP Additional Widgets
bokeh_button_StartStop = Button(label = "Start / Stop", button_type="success")
bokeh_button_StartStop.on_click(start_stop_dataThread)
# SET UP BOKEH LAYOUT
#
bokeh_row_1 = row(bokeh_live_pnCCD,bokeh_live_tof,column(bokeh_buffer_tof_integral,bokeh_buffer_gmd_history),bokeh_buffer_pnCCD_integral)
bokeh_row_2 = row(bokeh_hits_pnCCD_list[0],bokeh_hits_pnCCD_list[1],bokeh_hits_pnCCD_list[2],bokeh_hits_pnCCD_list[3],bokeh_hits_pnCCD_list[4])
#bokeh_row_2 = row(bokeh_hits_pnCCD_list[0],bokeh_hits_pnCCD_list[1])

bokeh_row_interact  = bokeh_button_StartStop
bokeh_layout = column(bokeh_row_1,bokeh_row_2, bokeh_row_interact)
print("...4")
# add bokeh layout to current doc
doc.add_root(bokeh_layout)
print("...5")
# Start Thread for Handling of the Live Data Strem
thread = Thread(target=makeBigData)
예제 #16
0
    else:
        desc = "{} [{}]".format(v['label'], v['unit'])

    if 'default' not in v.keys():
        v['default'] = None

    if v['type'] == 'float':
        filters_dict[k] = get_slider(desc, v['range'], v['default'])
    elif v['type'] == 'list':
        if 'labels' not in v.keys():
            v['labels'] = None
        filters_dict[k] = get_select(desc, v['values'], v['default'],
                                     v['labels'])

# plot button, output, graph
btn_plot = Button(label='Plot', button_type='primary')
info_block = PreText(text='', width=500, height=100)
plot_info = PreText(text='', width=300, height=100)

load_preset(None, None, get_preset_label_from_url())

source = bmd.ColumnDataSource(data=data_empty)
hover = bmd.HoverTool(tooltips=[])
tap = bmd.TapTool()


def create_plot():
    """Creates scatter plot.

    Note: While it is usually enough to update the data source, redrawing the
    plot is needed for adsorbaphore_label coloring, when the colormap needs to change
예제 #17
0
def tab_classification():

    data_list = glob.glob('./np/Classification/*.npy')
    data_list = sorted(data_list)
    select_data = Select(title="Data:", value="", options=data_list)

    model_list = os.listdir('./model/Classification/')
    model_list = sorted(model_list)
    select_model = Select(title="Trained Model", value="", options=model_list)

    notifier = Paragraph(text=""" Notification """, width=200, height=100)

    def refresh_handler():
        data_list_new = glob.glob('./np/Classification/*.npy')
        data_list_new = sorted(data_list_new)
        select_data.options = data_list_new

        model_list_new = os.listdir('./model/Classification/')
        model_list_new = sorted(model_list_new)
        select_model.options = model_list_new

    button_refresh = Button(label="Refresh list")
    button_refresh.on_click(refresh_handler)

    button_test = Button(label="Test model")

    #select_result = MultiSelect(title="Key(result):")

    colors = PuBu[9][:-1]
    colors.reverse()

    src_roc = ColumnDataSource(
        data=dict(xs=[], ys=[], line_color=[], label=[]))
    auc_paragraph = Paragraph(text="AUC")

    table_source = ColumnDataSource(pd.DataFrame())
    table_columns = [TableColumn(field=col, title=col) for col in ['-']]

    table_confusion = DataTable(source=table_source,
                                columns=table_columns,
                                width=800,
                                height=200,
                                fit_columns=True,
                                name="Confusion matrix")

    def test_handler():
        tf.reset_default_graph()
        K.clear_session()

        DL = True

        print("Start test")
        tf.reset_default_graph()
        notifier.text = """ Start testing """

        if (select_data.value == ""):
            data = np.load(select_data.options[0])
        else:
            data = np.load(select_data.value)
        data = data.item()
        notifier.text = """ Import data """

        data_x = data.get('x')
        if (data_x.shape[-1] == 1 and not 'cnn' in select_model.value):
            data_x = np.squeeze(data_x, -1)
        data_y = data.get('y')

        print(data_x.shape)
        print(data_y.shape)
        print(data.get('key1'))

        if (select_model.value == ""):
            model_name = select_model.options[0]
        else:
            model_name = select_model.value
        model_save_dir = './model/Classification/' + model_name + '/'

        model_dl = glob.glob(model_save_dir + '*.h5')
        model_ml = glob.glob(model_save_dir + '*.sav')

        print(model_save_dir + model_name)

        if (len(model_dl) != 0 and len(model_ml) == 0):
            model = keras.models.load_model(model_save_dir + model_name +
                                            '.h5')
            DL = True

        elif (len(model_dl) == 0 and len(model_ml) != 0):
            model = pickle.load(
                open(model_save_dir + model_name + '.sav', 'rb'))

            data_x = data_x.reshape([data_x.shape[0], -1])
            data_y_ = np.copy(data_y)
            data_y = np.argmax(data_y, axis=-1).astype(float)

            print(data_x.shape)
            print(data_y.shape)
            DL = False

        notifier.text = """ Model restored """
        print("Model restored.")

        fpr = dict()
        tpr = dict()
        roc_auc = dict()

        label = data.get('labels')
        print(label)

        if (DL):
            p_class = model.predict_classes(data_x)
            prob_class = model.predict(data_x)
            K.clear_session()

            true_class = [np.where(r == 1)[0][0] for r in data_y]
            true_class = np.asarray(true_class)

            x, y, _ = roc_curve(data_y.ravel(), prob_class.ravel())
            x = list(x)
            y = list(y)

            for i in range(data_y.shape[-1]):
                fp_, tp_, _ = roc_curve(data_y[:, i], prob_class[:, i])
                fpr[i] = list(fp_)
                tpr[i] = list(tp_)
                roc_auc[i] = auc(fpr[i], tpr[i])

            f1 = f1_score(true_class, p_class, average='macro')

        else:
            p_class = model.predict(data_x)
            prob_class = model.predict_proba(data_x)

            true_class = data_y

            x, y, _ = roc_curve(data_y_.ravel(), prob_class.ravel())
            x = list(x)
            y = list(y)

            for i in range(data_y_.shape[-1]):
                fp_, tp_, _ = roc_curve(data_y_[:, i], prob_class[:, i])
                fpr[i] = list(fp_)
                tpr[i] = list(tp_)
                roc_auc[i] = auc(fpr[i], tpr[i])

            print(fpr[0])
            print(type(fpr[0]))

            f1 = f1_score(true_class, p_class, average='macro')

        print(p_class.shape)
        print("Prediction complete")
        print(true_class.shape)

        cm_count = confusion_matrix(true_class, p_class)
        cm_ratio = cm_count.astype('float') / cm_count.sum(axis=1)[:,
                                                                   np.newaxis]

        def operate_on_Narray(A, B, function):
            try:
                return [
                    operate_on_Narray(a, b, function) for a, b in zip(A, B)
                ]
            except TypeError as e:
                # Not iterable
                return function(A, B)

        df = pd.DataFrame(cm_ratio, columns=label, index=label)

        tp = []
        tp_ = []
        fp = []

        for row in range(df.shape[0]):
            tp.append(format(df.iloc[row][row], '.2f'))
            tp_.append(df.iloc[row][row])
            fp.append(format(1 - df.iloc[row][row], '.2f'))

        df = pd.DataFrame(operate_on_Narray(
            cm_ratio, cm_count,
            lambda a, b: format(a, '.2f') + "(" + str(b) + ")"),
                          columns=label,
                          index=label)

        df['True Positive'] = tp
        df['False Positive'] = fp

        df['Label'] = label
        cols = df.columns.tolist()
        cols = cols[-1:] + cols[:-1]
        df = df[cols]

        print(df)

        notifier.text = """ Calculation complete """

        table_confusion.columns = [
            TableColumn(field=col, title=col) for col in df.columns
        ]
        table_source.data = ColumnDataSource(df).data
        table_confusion.source = table_source

        # AOC Curve

        xs = []
        ys = []
        line_color = []
        labels = []

        xs.append(x)
        ys.append(y)
        line_color.append('blue')
        labels.append("Macro ROC Curve")
        color_list = ['yellow', 'green', 'red', 'cyan', 'black']

        for key in fpr.keys():
            xs.append(fpr.get(key))
            ys.append(tpr.get(key))
            line_color.append(color_list[key % len(color_list)])
            labels.append("ROC Curve of class " + str(label[key]))

        roc_auc = auc(x, y)
        src_roc.data = ColumnDataSource(
            data=dict(xs=xs, ys=ys, line_color=line_color, label=labels)).data

        auc_paragraph.text = "Area under the curve: %f" % roc_auc

        history.text = history.text + "\n\t" + model_name + "'s accuracy / F1 score: " + format(
            np.mean(np.asarray(tp_)), '.2f') + ' / ' + format(f1, '.2f')

    button_test.on_click(test_handler)

    figure_roc = figure(title="ROC Curve", width=800, height=400)
    figure_roc.multi_line('xs',
                          'ys',
                          line_color='line_color',
                          legend='label',
                          source=src_roc)
    history = PreText(text="", width=600, height=200)

    button_export = Button(label="Export result")

    def handler_export():
        df = table_source.data
        df = pd.DataFrame(df)

        print(df.columns)

        label_list = list(df['Label'])
        col_order = ['index', 'Label'
                     ] + label_list + ['True Positive', 'False Positive']
        df = df[col_order]

        # del df['index']

        df.to_csv('./Export/result.csv', index=False)

    button_export.on_click(handler_export)

    layout = Column(Row(button_refresh),
                    Row(select_data, select_model, button_test, notifier),
                    Row(table_confusion, history, button_export),
                    Row(Column(figure_roc, auc_paragraph)))

    tab = Panel(child=layout, title='Classification Test')

    return tab
예제 #18
0
def tab_create_db(csv):

    csv_original = csv

    col_list = list(csv_original.columns)

    param_key = MultiSelect(title="Separator(Maximum 2)", options=col_list)
    param_x = MultiSelect(title="Predictor", options=col_list)
    param_y = Select(title="Response", options=col_list)

    problem_type = RadioGroup(labels=["Classification", "Regression"],
                              active=0)

    notifier = Paragraph(text=""" DB """, width=200, height=100)

    def refresh_handler():
        col_list = list(csv_original.columns)

        param_key.options = col_list
        param_x.options = col_list
        param_y.options = col_list

    button_refresh = Button(label="Refresh column")
    button_refresh.on_click(refresh_handler)

    slider_window = Slider(start=1,
                           end=30,
                           value=15,
                           step=1,
                           title="Sliding window")
    slider_train_ratio = Slider(start=0,
                                end=100,
                                value=80,
                                step=1,
                                title="Train ratio")

    text_title = TextInput(value="", title="Title")

    button_create = Button(label="Create Numpy file")

    def create_handler():

        train_x = []
        train_y = []
        train_idx = []
        test_x = []
        test_y = []
        test_idx = []

        print(csv_original)

        if (problem_type.active == 1):
            notifier.text = """ Making DB - Regression """
        else:
            notifier.text = """ Making DB - Classification """

        if (len(param_key.value) == 0):

            slide = round(slider_window.value)

            xs = csv_original[param_x.value].values
            ys = csv_original[param_y.value].values

            train_ratio = round(slider_train_ratio.value)

            if (train_ratio != 0):

                train_x_set = xs[:xs.shape[0] * train_ratio / 100]
                train_y_set = ys[:ys.shape[0] * train_ratio / 100]

                for start, stop in zip(range(0, train_x_set.shape[0] - slide),
                                       range(slide, train_x_set.shape[0])):
                    train_x.append(train_x_set[start:start + slide])
                    train_y.append(train_y_set[start:start + slide][-1])
                    train_idx.append('0')

                train_x = np.asarray(train_x)
                train_x = np.swapaxes(train_x, 1, 2)
                train_x = np.expand_dims(train_x, -1)
                train_idx = np.asarray(train_idx)

            if (train_ratio != 100):

                test_x_set = xs[xs.shape[0] * train_ratio / 100:]
                test_y_set = ys[ys.shape[0] * train_ratio / 100:]

                for start, stop in zip(range(0, test_x_set.shape[0] - slide),
                                       range(slide, test_x_set.shape[0])):
                    test_x.append(test_x_set[start:start + slide])
                    test_y.append(test_y_set[start:start + slide][-1])
                    test_idx.append('1')

                test_x = np.asarray(test_x)
                test_x = np.swapaxes(test_x, 1, 2)
                test_x = np.expand_dims(test_x, -1)
                test_idx = np.asarray(test_idx)

            train_x = np.asarray(train_x)
            test_x = np.asarray(test_x)

            all_y = train_y + test_y

            data_train = {}
            data_test = {}

            if (problem_type.active == 1):
                train_y = np.asarray(train_y)
                train_y = np.expand_dims(train_y, -1)

                test_y = np.asarray(test_y)
                test_y = np.expand_dims(test_y, -1)

            elif (problem_type.active == 0):
                encoder = LabelEncoder()
                encoder.fit(all_y)
                encoded_y = encoder.transform(all_y)

                category_y = np_utils.to_categorical(encoded_y)

                labels = []
                for y in all_y:
                    if (y not in labels):
                        labels.append(y)

                data_train['labels'] = np.asarray(labels)
                data_test['labels'] = np.asarray(labels)

                train_y = category_y[:train_x.shape[0]]
                test_y = category_y[train_x.shape[0]:]

            data_train['x'] = train_x
            data_train['y'] = train_y
            data_train['key1'] = train_idx
            data_train['slideing_window'] = slider_window.value

            data_test['x'] = test_x
            data_test['y'] = test_y
            data_test['key1'] = test_idx
            data_test['slideing_window'] = slider_window.value

            if (problem_type.active == 1):
                print("Regression")
                target_dir = 'Regression/'
            elif (problem_type.active == 0):
                print("Classification")
                target_dir = 'Classification/'

            time_window = '[' + str(round(slider_window.value)) + ']'

            if (train_ratio != 0):
                np.save(
                    "./np/" + target_dir + time_window + text_title.value +
                    "_train.npy", data_train)
            if (train_ratio != 100):
                np.save(
                    "./np/" + target_dir + time_window + text_title.value +
                    "_test.npy", data_test)

        elif (len(param_key.value) == 1):

            key1_list = list(csv_original[param_key.value[0]].unique())

            train_ratio = round(slider_train_ratio.value)
            if (train_ratio == 0):
                train_key = []
                test_key = key1_list[int(len(key1_list) * train_ratio / 100):]
            elif (train_ratio == 100):
                train_key = key1_list[:int(len(key1_list) * train_ratio / 100)]
                test_key = []
            else:
                train_key = key1_list[:int(len(key1_list) * train_ratio / 100)]
                test_key = key1_list[int(len(key1_list) * train_ratio / 100):]

            for key in train_key:

                num_elements = csv_original[csv_original[param_key.value[0]] ==
                                            key].shape[0]
                slide = round(slider_window.value)

                if (num_elements < slide):
                    continue

                xs = csv_original[csv_original[param_key.value[0]] == key][
                    param_x.value].values
                ys = csv_original[csv_original[param_key.value[0]] == key][
                    param_y.value].values

                for start, stop in zip(range(0, num_elements - slide),
                                       range(slide, num_elements)):
                    train_x.append(xs[start:start + slide])
                    train_y.append(ys[start:start + slide][-1])
                    train_idx.append(key)

            for key in test_key:
                num_elements = csv_original[csv_original[param_key.value[0]] ==
                                            key].shape[0]
                slide = round(slider_window.value)

                if (num_elements < slide):
                    continue

                xs = csv_original[csv_original[param_key.value[0]] == key][
                    param_x.value].values
                ys = csv_original[csv_original[param_key.value[0]] == key][
                    param_y.value].values

                for start, stop in zip(range(0, num_elements - slide),
                                       range(slide, num_elements)):
                    test_x.append(xs[start:start + slide])
                    test_y.append(ys[start:start + slide][-1])
                    test_idx.append(key)

            all_y = train_y + test_y

            train_x = np.asarray(train_x)
            if (train_ratio != 0):
                train_x = np.swapaxes(train_x, 1, 2)
                train_x = np.expand_dims(train_x, -1)
            train_idx = np.asarray(train_idx)

            test_x = np.asarray(test_x)
            if (train_ratio != 100):
                test_x = np.swapaxes(test_x, 1, 2)
                test_x = np.expand_dims(test_x, -1)
            test_idx = np.asarray(test_idx)

            data_train = {}
            data_test = {}

            if (problem_type.active == 1):
                train_y = np.asarray(train_y)
                train_y = np.expand_dims(train_y, -1)

                test_y = np.asarray(test_y)
                test_y = np.expand_dims(test_y, -1)

            elif (problem_type.active == 0):
                encoder = LabelEncoder()
                encoder.fit(all_y)
                encoded_y = encoder.transform(all_y)

                category_y = np_utils.to_categorical(encoded_y)

                labels = []
                for y in all_y:
                    if (y not in labels):
                        labels.append(y)

                data_train['labels'] = np.asarray(labels)
                data_test['labels'] = np.asarray(labels)

                train_y = category_y[:train_x.shape[0]]
                test_y = category_y[train_x.shape[0]:]

            data_train['x'] = train_x
            data_train['y'] = train_y
            data_train['key1'] = train_idx
            data_train['slideing_window'] = slider_window.value

            data_test['x'] = test_x
            data_test['y'] = test_y
            data_test['key1'] = test_idx
            data_test['slideing_window'] = slider_window.value

            print(train_x.shape)
            print(train_y.shape)
            print(test_x.shape)
            print(test_y.shape)

            if (problem_type.active == 1):
                print("Regression")
                target_dir = 'Regression/'
            elif (problem_type.active == 0):
                print("Classification")
                target_dir = 'Classification/'

            print(train_x.shape)

            time_window = '[' + str(round(slider_window.value)) + ']'

            if (train_ratio == 0):
                np.save(
                    "./np/" + target_dir + time_window + text_title.value +
                    "_test.npy", data_test)
            elif (train_ratio == 100):
                np.save(
                    "./np/" + target_dir + time_window + text_title.value +
                    "_train.npy", data_train)
            else:
                np.save(
                    "./np/" + target_dir + time_window + text_title.value +
                    "_train.npy", data_train)
                np.save(
                    "./np/" + target_dir + time_window + text_title.value +
                    "_test.npy", data_test)

        elif (len(param_key.value) == 2):
            keys_list = csv_original[param_key.value].drop_duplicates()

            train_ratio = round(slider_train_ratio.value)
            if (train_ratio == 0):
                train_key = []
                test_key = keys_list.iloc[
                    int(len(keys_list) * slider_train_ratio.value / 100):]
            elif (train_ratio == 100):
                train_key = keys_list.iloc[:int(
                    len(keys_list) * slider_train_ratio.value / 100)]
                test_key = []
            else:
                train_key = keys_list.iloc[:int(
                    len(keys_list) * slider_train_ratio.value / 100)]
                test_key = keys_list.iloc[
                    int(len(keys_list) * slider_train_ratio.value / 100):]

            if (train_ratio != 0):
                for index, row in train_key.iterrows():

                    key1 = row[param_key.value[0]]
                    key2 = row[param_key.value[1]]

                    cond1 = csv_original[param_key.value[0]] == key1
                    cond2 = csv_original[param_key.value[0]] == key2

                    csv_target = csv_original[cond1 & cond2]

                    num_elements = csv_target.shape[0]
                    if (num_elements < slider_window.value):
                        continue

                    xs = csv_target[param_x.value].values
                    ys = csv_target[param_y.value].values

                    for start, stop in zip(
                            range(0, num_elements - slider_window.value),
                            range(slider_window.value, num_elements)):
                        train_x.append(xs[start:start + slider_window.value])
                        train_y.append(ys[start:start +
                                          slider_window.value][-1])
                        train_idx.append(str(key1) + "_" + str(key2))

            if (train_ratio != 100):
                for index, row in test_key.iterrows():

                    key1 = row[param_key.value[0]]
                    key2 = row[param_key.value[1]]

                    cond1 = csv_original[param_key.value[0]] == key1
                    cond2 = csv_original[param_key.value[1]] == key2

                    csv_target = csv_original[cond1 & cond2]

                    num_elements = csv_target.shape[0]
                    if (num_elements < slider_window.value):
                        continue

                    xs = csv_target[param_x.value].values
                    ys = csv_target[param_y.value].values

                    for start, stop in zip(
                            range(0, num_elements - slider_window.value),
                            range(slider_window.value, num_elements)):
                        test_x.append(xs[start:start + slider_window.value])
                        test_y.append(ys[start:start +
                                         slider_window.value][-1])
                        test_idx.append(str(key1) + "_" + str(key2))

            all_y = train_y + test_y

            train_x = np.asarray(train_x)
            if (train_ratio != 0):
                train_x = np.swapaxes(train_x, 1, 2)
                train_x = np.expand_dims(train_x, -1)
            train_idx = np.asarray(train_idx)

            test_x = np.asarray(test_x)
            if (train_ratio != 100):
                test_x = np.swapaxes(test_x, 1, 2)
                test_x = np.expand_dims(test_x, -1)
            test_idx = np.asarray(test_idx)

            data_train = {}
            data_test = {}

            if (problem_type.active == 1):
                train_y = np.asarray(train_y)
                train_y = np.expand_dims(train_y, -1)

                test_y = np.asarray(test_y)
                test_y = np.expand_dims(test_y, -1)

            elif (problem_type.active == 0):
                encoder = LabelEncoder()
                encoder.fit(all_y)
                encoded_y = encoder.transform(all_y)

                category_y = np_utils.to_categorical(encoded_y)

                labels = []
                for y in all_y:
                    if (y not in labels):
                        labels.append(y)

                data_train['labels'] = np.asarray(labels)
                data_test['labels'] = np.asarray(labels)

                train_y = category_y[:train_x.shape[0]]
                test_y = category_y[train_x.shape[0]:]

            data_train['x'] = train_x
            data_train['y'] = train_y
            data_train['key1'] = train_idx
            data_train['slideing_window'] = slider_window.value

            data_test['x'] = test_x
            data_test['y'] = test_y
            data_test['key1'] = test_idx
            data_test['slideing_window'] = slider_window.value

            print(train_x.shape)
            print(train_y.shape)
            print(test_x.shape)
            print(test_y.shape)

            if (problem_type.active == 1):
                print("Regression")
                target_dir = 'Regression/'
            elif (problem_type.active == 0):
                print("Classification")
                target_dir = 'Classification/'

            print(train_x.shape)

            time_window = '[' + str(round(slider_window.value)) + ']'

            if (train_ratio == 0):
                np.save(
                    "./np/" + target_dir + time_window + text_title.value +
                    "_test.npy", data_test)
            elif (train_ratio == 100):
                np.save(
                    "./np/" + target_dir + time_window + text_title.value +
                    "_train.npy", data_train)
            else:
                np.save(
                    "./np/" + target_dir + time_window + text_title.value +
                    "_train.npy", data_train)
                np.save(
                    "./np/" + target_dir + time_window + text_title.value +
                    "_test.npy", data_test)

        notifier.text = """ DB creation complete """

    button_create.on_click(create_handler)

    layout = Column(Row(param_key, param_x, param_y, notifier),
                    Row(problem_type),
                    Row(slider_window, slider_train_ratio, text_title),
                    Row(button_refresh, button_create))

    tab = Panel(child=layout, title='Create DB')

    return tab
예제 #19
0
def generate_plots(ulog, px4_ulog, db_data, vehicle_data, link_to_3d_page):
    """ create a list of bokeh plots (and widgets) to show """

    plots = []
    data = ulog.data_list

    # COMPATIBILITY support for old logs
    if any(elem.name == 'vehicle_air_data'
           or elem.name == 'vehicle_magnetometer' for elem in data):
        baro_alt_meter_topic = 'vehicle_air_data'
        magnetometer_ga_topic = 'vehicle_magnetometer'
    else:  # old
        baro_alt_meter_topic = 'sensor_combined'
        magnetometer_ga_topic = 'sensor_combined'
    for topic in data:
        if topic.name == 'system_power':
            # COMPATIBILITY: rename fields to new format
            if 'voltage5V_v' in topic.data:  # old (prior to PX4/Firmware:213aa93)
                topic.data['voltage5v_v'] = topic.data.pop('voltage5V_v')
            if 'voltage3V3_v' in topic.data:  # old (prior to PX4/Firmware:213aa93)
                topic.data['voltage3v3_v'] = topic.data.pop('voltage3V3_v')

    # initialize flight mode changes
    flight_mode_changes = get_flight_mode_changes(ulog)

    # VTOL state changes
    vtol_states = None
    try:
        cur_dataset = ulog.get_dataset('vehicle_status')
        if np.amax(cur_dataset.data['is_vtol']) == 1:
            vtol_states = cur_dataset.list_value_changes('in_transition_mode')
            # find mode after transitions (states: 1=transition, 2=FW, 3=MC)
            for i in range(len(vtol_states)):
                if vtol_states[i][1] == 0:
                    t = vtol_states[i][0]
                    idx = np.argmax(cur_dataset.data['timestamp'] >= t) + 1
                    vtol_states[i] = (t, 2 +
                                      cur_dataset.data['is_rotary_wing'][idx])
            vtol_states.append((ulog.last_timestamp, -1))
    except (KeyError, IndexError) as error:
        vtol_states = None

    # Heading
    curdoc().template_variables['title_html'] = get_heading_html(
        ulog, px4_ulog, db_data, link_to_3d_page)

    # info text on top (logging duration, max speed, ...)
    curdoc().template_variables['info_table_html'] = \
        get_info_table_html(ulog, px4_ulog, db_data, vehicle_data, vtol_states)

    curdoc().template_variables['error_labels_html'] = get_error_labels_html()

    hardfault_html = get_hardfault_html(ulog)
    if hardfault_html is not None:
        curdoc().template_variables['hardfault_html'] = hardfault_html

# FIXME: for now, we use Google maps directly without bokeh, because it's not working reliably
# GPS map
#    gps_plots = []
#    gps_titles = []
#    plot = plot_map(ulog, plot_config, map_type='google', api_key =
#            get_google_maps_api_key(), setpoints=False)
#    if plot is not None:
#        gps_plots.append(plot)
#        gps_titles.append('GPS Map: Satellite')
#
#    plot = plot_map(ulog, plot_config, map_type='plain', setpoints=True)
#    if plot is not None:
#        gps_plots.append(plot)
#        gps_titles.append('GPS Map: Plain')
#
#    data_plot = DataPlot2D(data, plot_config, 'vehicle_local_position',
#        x_axis_label = '[m]', y_axis_label='[m]', plot_height='large')
#    data_plot.add_graph('y', 'x', colors2[0], 'Estimated')
#    data_plot.change_dataset('vehicle_local_position_setpoint')
#    data_plot.add_graph('y', 'x', colors2[1], 'Setpoint')
#    if data_plot.finalize() is not None:
#        gps_plots.append(data_plot.bokeh_plot)
#        gps_titles.append('Local Position')
#
#    if len(gps_plots) >= 2:
#        tabs = []
#        for i in range(len(gps_plots)):
#            tabs.append(Panel(child=gps_plots[i], title=gps_titles[i]))
#        gps_plot_height=plot_config['plot_height']['large'] + 30
#        plots.append(Tabs(tabs=tabs, width=plot_width, height=gps_plot_height))
#    elif len(gps_plots) == 1:
#        plots.extend(gps_plots)

    if is_running_locally():
        # show the google maps plot via Bokeh, since the one in the html
        # template does not work locally (we disable it further down)
        map_plot = plot_map(ulog,
                            plot_config,
                            map_type='google',
                            api_key=get_google_maps_api_key(),
                            setpoints=False)
        if map_plot is not None:
            plots.append(map_plot)

    # Position plot
    data_plot = DataPlot2D(data,
                           plot_config,
                           'vehicle_local_position',
                           x_axis_label='[m]',
                           y_axis_label='[m]',
                           plot_height='large')
    data_plot.add_graph('y',
                        'x',
                        colors2[0],
                        'Estimated',
                        check_if_all_zero=True)
    if not data_plot.had_error:  # vehicle_local_position is required
        data_plot.change_dataset('vehicle_local_position_setpoint')
        data_plot.add_graph('y', 'x', colors2[1], 'Setpoint')
        # groundtruth (SITL only)
        data_plot.change_dataset('vehicle_groundtruth')
        data_plot.add_graph('y', 'x', color_gray, 'Groundtruth')
        # GPS + position setpoints
        plot_map(ulog,
                 plot_config,
                 map_type='plain',
                 setpoints=True,
                 bokeh_plot=data_plot.bokeh_plot)
        if data_plot.finalize() is not None:
            plots.append(data_plot.bokeh_plot)
            if not is_running_locally(
            ):  # do not enable Google Map if running locally
                curdoc().template_variables['has_position_data'] = True

    # initialize parameter changes
    changed_params = None
    if not 'replay' in ulog.msg_info_dict:  # replay can have many param changes
        if len(ulog.changed_parameters) > 0:
            changed_params = ulog.changed_parameters
            plots.append(None)  # save space for the param change button

    ### Add all data plots ###

    x_range_offset = (ulog.last_timestamp - ulog.start_timestamp) * 0.05
    x_range = Range1d(ulog.start_timestamp - x_range_offset,
                      ulog.last_timestamp + x_range_offset)

    # Altitude estimate
    data_plot = DataPlot(data,
                         plot_config,
                         'vehicle_gps_position',
                         y_axis_label='[m]',
                         title='Altitude Estimate',
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph([lambda data: ('alt', data['alt'] * 0.001)],
                        colors8[0:1], ['GPS Altitude'])
    data_plot.change_dataset(baro_alt_meter_topic)
    data_plot.add_graph(['baro_alt_meter'], colors8[1:2],
                        ['Barometer Altitude'])
    data_plot.change_dataset('vehicle_global_position')
    data_plot.add_graph(['alt'], colors8[2:3], ['Fused Altitude Estimation'])
    data_plot.change_dataset('position_setpoint_triplet')
    data_plot.add_circle(['current.alt'],
                         [plot_config['mission_setpoint_color']],
                         ['Altitude Setpoint'])
    data_plot.change_dataset('actuator_controls_0')
    data_plot.add_graph([lambda data: ('thrust', data['control[3]'] * 100)],
                        colors8[6:7], ['Thrust [0, 100]'])
    plot_flight_modes_background(data_plot, flight_mode_changes, vtol_states)

    if data_plot.finalize() is not None: plots.append(data_plot)

    # Roll/Pitch/Yaw angle & angular rate
    for axis in ['roll', 'pitch', 'yaw']:

        # angle
        axis_name = axis.capitalize()
        data_plot = DataPlot(data,
                             plot_config,
                             'vehicle_attitude',
                             y_axis_label='[deg]',
                             title=axis_name + ' Angle',
                             plot_height='small',
                             changed_params=changed_params,
                             x_range=x_range)
        data_plot.add_graph([lambda data: (axis, np.rad2deg(data[axis]))],
                            colors2[0:1], [axis_name + ' Estimated'],
                            mark_nan=True)
        data_plot.change_dataset('vehicle_attitude_setpoint')
        data_plot.add_graph(
            [lambda data: (axis + '_d', np.rad2deg(data[axis + '_d']))],
            colors2[1:2], [axis_name + ' Setpoint'],
            mark_nan=True,
            use_step_lines=True)
        data_plot.change_dataset('vehicle_groundtruth')
        data_plot.add_graph([lambda data: (axis, np.rad2deg(data[axis]))],
                            [color_gray], [axis_name + ' Groundtruth'])
        plot_flight_modes_background(data_plot, flight_mode_changes,
                                     vtol_states)

        if data_plot.finalize() is not None: plots.append(data_plot)

        # rate
        data_plot = DataPlot(data,
                             plot_config,
                             'vehicle_attitude',
                             y_axis_label='[deg/s]',
                             title=axis_name + ' Angular Rate',
                             plot_height='small',
                             changed_params=changed_params,
                             x_range=x_range)
        data_plot.add_graph(
            [lambda data: (axis + 'speed', np.rad2deg(data[axis + 'speed']))],
            colors3[0:1], [axis_name + ' Rate Estimated'],
            mark_nan=True)
        data_plot.change_dataset('vehicle_rates_setpoint')
        data_plot.add_graph([lambda data: (axis, np.rad2deg(data[axis]))],
                            colors3[1:2], [axis_name + ' Rate Setpoint'],
                            mark_nan=True,
                            use_step_lines=True)
        axis_letter = axis[0].upper()
        rate_int_limit = '(*100)'
        # this param is MC/VTOL only (it will not exist on FW)
        rate_int_limit_param = 'MC_' + axis_letter + 'R_INT_LIM'
        if rate_int_limit_param in ulog.initial_parameters:
            rate_int_limit = '[-{0:.0f}, {0:.0f}]'.format(
                ulog.initial_parameters[rate_int_limit_param] * 100)
        data_plot.change_dataset('rate_ctrl_status')
        data_plot.add_graph(
            [lambda data: (axis, data[axis + 'speed_integ'] * 100)],
            colors3[2:3], [axis_name + ' Rate Integral ' + rate_int_limit])
        data_plot.change_dataset('vehicle_groundtruth')
        data_plot.add_graph(
            [lambda data: (axis + 'speed', np.rad2deg(data[axis + 'speed']))],
            [color_gray], [axis_name + ' Rate Groundtruth'])
        plot_flight_modes_background(data_plot, flight_mode_changes,
                                     vtol_states)

        if data_plot.finalize() is not None: plots.append(data_plot)

    # Local position
    for axis in ['x', 'y', 'z']:
        data_plot = DataPlot(data,
                             plot_config,
                             'vehicle_local_position',
                             y_axis_label='[m]',
                             title='Local Position ' + axis.upper(),
                             plot_height='small',
                             changed_params=changed_params,
                             x_range=x_range)
        data_plot.add_graph([axis],
                            colors2[0:1], [axis.upper() + ' Estimated'],
                            mark_nan=True)
        data_plot.change_dataset('vehicle_local_position_setpoint')
        data_plot.add_graph([axis],
                            colors2[1:2], [axis.upper() + ' Setpoint'],
                            mark_nan=True,
                            use_step_lines=True)
        plot_flight_modes_background(data_plot, flight_mode_changes,
                                     vtol_states)

        if data_plot.finalize() is not None: plots.append(data_plot)

    # Velocity
    data_plot = DataPlot(data,
                         plot_config,
                         'vehicle_local_position',
                         y_axis_label='[m/s]',
                         title='Velocity',
                         plot_height='small',
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph(['vx', 'vy', 'vz'], colors8[0:3], ['X', 'Y', 'Z'])
    data_plot.change_dataset('vehicle_local_position_setpoint')
    data_plot.add_graph(['vx', 'vy', 'vz'],
                        [colors8[5], colors8[4], colors8[6]],
                        ['X Setpoint', 'Y Setpoint', 'Z Setpoint'],
                        use_step_lines=True)
    plot_flight_modes_background(data_plot, flight_mode_changes, vtol_states)

    if data_plot.finalize() is not None: plots.append(data_plot)

    # Visual Odometry (only if topic found)
    if any(elem.name == 'vehicle_visual_odometry' for elem in data):
        # Vision position
        data_plot = DataPlot(data,
                             plot_config,
                             'vehicle_visual_odometry',
                             y_axis_label='[m]',
                             title='Visual Odometry Position',
                             plot_height='small',
                             changed_params=changed_params,
                             x_range=x_range)
        data_plot.add_graph(['x', 'y', 'z'],
                            colors3, ['X', 'Y', 'Z'],
                            mark_nan=True)
        plot_flight_modes_background(data_plot, flight_mode_changes,
                                     vtol_states)

        data_plot.change_dataset('vehicle_groundtruth')
        data_plot.add_graph(
            ['x', 'y', 'z'], colors8[2:5],
            ['Groundtruth X', 'Groundtruth Y', 'Groundtruth Z'])

        if data_plot.finalize() is not None: plots.append(data_plot)

        # Vision velocity
        data_plot = DataPlot(data,
                             plot_config,
                             'vehicle_visual_odometry',
                             y_axis_label='[m]',
                             title='Visual Odometry Velocity',
                             plot_height='small',
                             changed_params=changed_params,
                             x_range=x_range)
        data_plot.add_graph(['vx', 'vy', 'vz'],
                            colors3, ['X', 'Y', 'Z'],
                            mark_nan=True)
        plot_flight_modes_background(data_plot, flight_mode_changes,
                                     vtol_states)

        data_plot.change_dataset('vehicle_groundtruth')
        data_plot.add_graph(
            ['vx', 'vy', 'vz'], colors8[2:5],
            ['Groundtruth VX', 'Groundtruth VY', 'Groundtruth VZ'])
        if data_plot.finalize() is not None: plots.append(data_plot)

        # Vision attitude
        data_plot = DataPlot(data,
                             plot_config,
                             'vehicle_visual_odometry',
                             y_axis_label='[deg]',
                             title='Visual Odometry Attitude',
                             plot_height='small',
                             changed_params=changed_params,
                             x_range=x_range)
        data_plot.add_graph([
            lambda data: ('roll', np.rad2deg(data['roll'])), lambda data:
            ('pitch', np.rad2deg(data['pitch'])), lambda data:
            ('yaw', np.rad2deg(data['yaw']))
        ],
                            colors3, ['Roll', 'Pitch', 'Yaw'],
                            mark_nan=True)
        plot_flight_modes_background(data_plot, flight_mode_changes,
                                     vtol_states)

        data_plot.change_dataset('vehicle_groundtruth')
        data_plot.add_graph(
            [
                lambda data: ('roll', np.rad2deg(data['roll'])), lambda data:
                ('pitch', np.rad2deg(data['pitch'])), lambda data:
                ('yaw', np.rad2deg(data['yaw']))
            ], colors8[2:5],
            ['Roll Groundtruth', 'Pitch Groundtruth', 'Yaw Groundtruth'])

        # Vision attitude rate
        data_plot = DataPlot(data,
                             plot_config,
                             'vehicle_visual_odometry',
                             y_axis_label='[deg]',
                             title='Visual Odometry Attitude Rate',
                             plot_height='small',
                             changed_params=changed_params,
                             x_range=x_range)
        data_plot.add_graph([
            lambda data:
            ('rollspeed', np.rad2deg(data['rollspeed'])), lambda data:
            ('pitchspeed', np.rad2deg(data['pitchspeed'])), lambda data:
            ('yawspeed', np.rad2deg(data['yawspeed']))
        ],
                            colors3, ['Roll Rate', 'Pitch Rate', 'Yaw Rate'],
                            mark_nan=True)
        plot_flight_modes_background(data_plot, flight_mode_changes,
                                     vtol_states)

        data_plot.change_dataset('vehicle_groundtruth')
        data_plot.add_graph([
            lambda data:
            ('rollspeed', np.rad2deg(data['rollspeed'])), lambda data:
            ('pitchspeed', np.rad2deg(data['pitchspeed'])), lambda data:
            ('yawspeed', np.rad2deg(data['yawspeed']))
        ], colors8[2:5], [
            'Roll Rate Groundtruth', 'Pitch Rate Groundtruth',
            'Yaw Rate Groundtruth'
        ])

        if data_plot.finalize() is not None: plots.append(data_plot)

    # Airspeed vs Ground speed: but only if there's valid airspeed data
    try:
        cur_dataset = ulog.get_dataset('airspeed')
        if np.amax(cur_dataset.data['indicated_airspeed_m_s']) > 0.1:
            data_plot = DataPlot(data,
                                 plot_config,
                                 'vehicle_global_position',
                                 y_axis_label='[m/s]',
                                 title='Airspeed',
                                 plot_height='small',
                                 changed_params=changed_params,
                                 x_range=x_range)
            data_plot.add_graph([
                lambda data: ('groundspeed_estimated',
                              np.sqrt(data['vel_n']**2 + data['vel_e']**2))
            ], colors3[2:3], ['Ground Speed Estimated'])
            data_plot.change_dataset('airspeed')
            data_plot.add_graph(['indicated_airspeed_m_s'], colors2[0:1],
                                ['Airspeed Indicated'])

            plot_flight_modes_background(data_plot, flight_mode_changes,
                                         vtol_states)

            if data_plot.finalize() is not None: plots.append(data_plot)
    except (KeyError, IndexError) as error:
        pass

    # manual control inputs
    # prefer the manual_control_setpoint topic. Old logs do not contain it
    if any(elem.name == 'manual_control_setpoint' for elem in data):
        data_plot = DataPlot(data,
                             plot_config,
                             'manual_control_setpoint',
                             title='Manual Control Inputs (Radio or Joystick)',
                             plot_height='small',
                             y_range=Range1d(-1.1, 1.1),
                             changed_params=changed_params,
                             x_range=x_range)
        data_plot.add_graph([
            'y', 'x', 'r', 'z', lambda data:
            ('mode_slot', data['mode_slot'] / 6), 'aux1', 'aux2', lambda data:
            ('kill_switch', data['kill_switch'] == 1)
        ], colors8, [
            'Y / Roll', 'X / Pitch', 'Yaw', 'Throttle [0, 1]', 'Flight Mode',
            'Aux1', 'Aux2', 'Kill Switch'
        ])
        # TODO: add RTL switch and others? Look at params which functions are mapped?
        plot_flight_modes_background(data_plot, flight_mode_changes,
                                     vtol_states)

        if data_plot.finalize() is not None: plots.append(data_plot)

    else:  # it's an old log (COMPATIBILITY)
        data_plot = DataPlot(data,
                             plot_config,
                             'rc_channels',
                             title='Raw Radio Control Inputs',
                             plot_height='small',
                             y_range=Range1d(-1.1, 1.1),
                             changed_params=changed_params,
                             x_range=x_range)
        num_rc_channels = 8
        if data_plot.dataset:
            max_channels = np.amax(data_plot.dataset.data['channel_count'])
            if max_channels < num_rc_channels: num_rc_channels = max_channels
        legends = []
        for i in range(num_rc_channels):
            channel_names = px4_ulog.get_configured_rc_input_names(i)
            if channel_names is None:
                legends.append('Channel ' + str(i))
            else:
                legends.append('Channel ' + str(i) + ' (' +
                               ', '.join(channel_names) + ')')
        data_plot.add_graph(
            ['channels[' + str(i) + ']' for i in range(num_rc_channels)],
            colors8[0:num_rc_channels],
            legends,
            mark_nan=True)
        plot_flight_modes_background(data_plot, flight_mode_changes,
                                     vtol_states)

        if data_plot.finalize() is not None: plots.append(data_plot)

    # actuator controls 0
    data_plot = DataPlot(data,
                         plot_config,
                         'actuator_controls_0',
                         y_start=0,
                         title='Actuator Controls 0',
                         plot_height='small',
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph(
        ['control[0]', 'control[1]', 'control[2]', 'control[3]'],
        colors8[0:4], ['Roll', 'Pitch', 'Yaw', 'Thrust'],
        mark_nan=True)
    plot_flight_modes_background(data_plot, flight_mode_changes, vtol_states)
    if data_plot.finalize() is not None: plots.append(data_plot)

    # actuator controls (Main) FFT (for filter & output noise analysis)
    data_plot = DataPlotFFT(data,
                            plot_config,
                            'actuator_controls_0',
                            title='Actuator Controls FFT')
    data_plot.add_graph(['control[0]', 'control[1]', 'control[2]'], colors3,
                        ['Roll', 'Pitch', 'Yaw'])
    if not data_plot.had_error:
        if 'MC_DTERM_CUTOFF' in ulog.initial_parameters:
            data_plot.mark_frequency(
                ulog.initial_parameters['MC_DTERM_CUTOFF'], 'MC_DTERM_CUTOFF')
        if 'IMU_GYRO_CUTOFF' in ulog.initial_parameters:
            data_plot.mark_frequency(
                ulog.initial_parameters['IMU_GYRO_CUTOFF'], 'IMU_GYRO_CUTOFF',
                20)

    if data_plot.finalize() is not None: plots.append(data_plot)

    # actuator controls 1
    # (only present on VTOL, Fixed-wing config)
    data_plot = DataPlot(data,
                         plot_config,
                         'actuator_controls_1',
                         y_start=0,
                         title='Actuator Controls 1 (VTOL in Fixed-Wing mode)',
                         plot_height='small',
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph(
        ['control[0]', 'control[1]', 'control[2]', 'control[3]'],
        colors8[0:4], ['Roll', 'Pitch', 'Yaw', 'Thrust'],
        mark_nan=True)
    plot_flight_modes_background(data_plot, flight_mode_changes, vtol_states)
    if data_plot.finalize() is not None: plots.append(data_plot)

    # actuator outputs 0: Main
    data_plot = DataPlot(data,
                         plot_config,
                         'actuator_outputs',
                         y_start=0,
                         title='Actuator Outputs (Main)',
                         plot_height='small',
                         changed_params=changed_params,
                         x_range=x_range)
    num_actuator_outputs = 8
    if data_plot.dataset:
        max_outputs = np.amax(data_plot.dataset.data['noutputs'])
        if max_outputs < num_actuator_outputs:
            num_actuator_outputs = max_outputs
    data_plot.add_graph(
        ['output[' + str(i) + ']' for i in range(num_actuator_outputs)],
        colors8[0:num_actuator_outputs],
        ['Output ' + str(i) for i in range(num_actuator_outputs)],
        mark_nan=True)
    plot_flight_modes_background(data_plot, flight_mode_changes, vtol_states)

    if data_plot.finalize() is not None: plots.append(data_plot)

    # actuator outputs 1: AUX
    data_plot = DataPlot(data,
                         plot_config,
                         'actuator_outputs',
                         y_start=0,
                         title='Actuator Outputs (AUX)',
                         plot_height='small',
                         changed_params=changed_params,
                         topic_instance=1,
                         x_range=x_range)
    num_actuator_outputs = 8
    # only plot if at least one of the outputs is not constant
    all_constant = True
    if data_plot.dataset:
        max_outputs = np.amax(data_plot.dataset.data['noutputs'])
        if max_outputs < num_actuator_outputs:
            num_actuator_outputs = max_outputs

        for i in range(num_actuator_outputs):
            output_data = data_plot.dataset.data['output[' + str(i) + ']']
            if not np.all(output_data == output_data[0]):
                all_constant = False
    if not all_constant:
        data_plot.add_graph(
            ['output[' + str(i) + ']' for i in range(num_actuator_outputs)],
            colors8[0:num_actuator_outputs],
            ['Output ' + str(i) for i in range(num_actuator_outputs)],
            mark_nan=True)
        plot_flight_modes_background(data_plot, flight_mode_changes,
                                     vtol_states)

        if data_plot.finalize() is not None: plots.append(data_plot)

    # raw acceleration
    data_plot = DataPlot(data,
                         plot_config,
                         'sensor_combined',
                         y_axis_label='[m/s^2]',
                         title='Raw Acceleration',
                         plot_height='small',
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph([
        'accelerometer_m_s2[0]', 'accelerometer_m_s2[1]',
        'accelerometer_m_s2[2]'
    ], colors3, ['X', 'Y', 'Z'])
    if data_plot.finalize() is not None: plots.append(data_plot)

    # raw angular speed
    data_plot = DataPlot(data,
                         plot_config,
                         'sensor_combined',
                         y_axis_label='[deg/s]',
                         title='Raw Angular Speed (Gyroscope)',
                         plot_height='small',
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph([
        lambda data:
        ('gyro_rad[0]', np.rad2deg(data['gyro_rad[0]'])), lambda data:
        ('gyro_rad[1]', np.rad2deg(data['gyro_rad[1]'])), lambda data:
        ('gyro_rad[2]', np.rad2deg(data['gyro_rad[2]']))
    ], colors3, ['X', 'Y', 'Z'])
    if data_plot.finalize() is not None: plots.append(data_plot)

    # magnetic field strength
    data_plot = DataPlot(data,
                         plot_config,
                         magnetometer_ga_topic,
                         y_axis_label='[gauss]',
                         title='Raw Magnetic Field Strength',
                         plot_height='small',
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph(
        ['magnetometer_ga[0]', 'magnetometer_ga[1]', 'magnetometer_ga[2]'],
        colors3, ['X', 'Y', 'Z'])
    if data_plot.finalize() is not None: plots.append(data_plot)

    # distance sensor
    data_plot = DataPlot(data,
                         plot_config,
                         'distance_sensor',
                         y_start=0,
                         y_axis_label='[m]',
                         title='Distance Sensor',
                         plot_height='small',
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph(['current_distance', 'covariance'], colors3[0:2],
                        ['Distance', 'Covariance'])
    if data_plot.finalize() is not None: plots.append(data_plot)

    # gps uncertainty
    # the accuracy values can be really large if there is no fix, so we limit the
    # y axis range to some sane values
    data_plot = DataPlot(data,
                         plot_config,
                         'vehicle_gps_position',
                         title='GPS Uncertainty',
                         y_range=Range1d(0, 40),
                         plot_height='small',
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph(
        ['eph', 'epv', 'satellites_used', 'fix_type'], colors8[::2], [
            'Horizontal position accuracy [m]',
            'Vertical position accuracy [m]', 'Num Satellites used', 'GPS Fix'
        ])
    if data_plot.finalize() is not None: plots.append(data_plot)

    # gps noise & jamming
    data_plot = DataPlot(data,
                         plot_config,
                         'vehicle_gps_position',
                         y_start=0,
                         title='GPS Noise & Jamming',
                         plot_height='small',
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph(['noise_per_ms', 'jamming_indicator'], colors3[0:2],
                        ['Noise per ms', 'Jamming Indicator'])
    if data_plot.finalize() is not None: plots.append(data_plot)

    # thrust and magnetic field
    data_plot = DataPlot(data,
                         plot_config,
                         magnetometer_ga_topic,
                         y_start=0,
                         title='Thrust and Magnetic Field',
                         plot_height='small',
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph([
        lambda data:
        ('len_mag',
         np.sqrt(data['magnetometer_ga[0]']**2 + data['magnetometer_ga[1]']**2
                 + data['magnetometer_ga[2]']**2))
    ], colors2[0:1], ['Norm of Magnetic Field'])
    data_plot.change_dataset('actuator_controls_0')
    data_plot.add_graph([lambda data: ('thrust', data['control[3]'])],
                        colors2[1:2], ['Thrust'])
    if data_plot.finalize() is not None: plots.append(data_plot)

    # Acceleration Spectrogram
    data_plot = DataPlotSpec(data,
                             plot_config,
                             'sensor_combined',
                             y_axis_label='[Hz]',
                             title='Acceleration Power Spectral Density',
                             plot_height='small',
                             x_range=x_range)
    data_plot.add_graph([
        'accelerometer_m_s2[0]', 'accelerometer_m_s2[1]',
        'accelerometer_m_s2[2]'
    ], ['X', 'Y', 'Z'])
    if data_plot.finalize() is not None: plots.append(data_plot)

    # power
    data_plot = DataPlot(data,
                         plot_config,
                         'battery_status',
                         y_start=0,
                         title='Power',
                         plot_height='small',
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph([
        'voltage_v', 'voltage_filtered_v', 'current_a', lambda data:
        ('discharged_mah', data['discharged_mah'] / 100), lambda data:
        ('remaining', data['remaining'] * 10)
    ], colors8[::2] + colors8[1:2], [
        'Battery Voltage [V]', 'Battery Voltage filtered [V]',
        'Battery Current [A]', 'Discharged Amount [mAh / 100]',
        'Battery remaining [0=empty, 10=full]'
    ])
    data_plot.change_dataset('system_power')
    if data_plot.dataset:
        if 'voltage5v_v' in data_plot.dataset.data and \
                        np.amax(data_plot.dataset.data['voltage5v_v']) > 0.0001:
            data_plot.add_graph(['voltage5v_v'], colors8[7:8], ['5 V'])
        if 'voltage3v3_v' in data_plot.dataset.data and \
                        np.amax(data_plot.dataset.data['voltage3v3_v']) > 0.0001:
            data_plot.add_graph(['voltage3v3_v'], colors8[5:6], ['3.3 V'])
    if data_plot.finalize() is not None: plots.append(data_plot)

    # estimator watchdog
    try:
        data_plot = DataPlot(data,
                             plot_config,
                             'estimator_status',
                             y_start=0,
                             title='Estimator Watchdog',
                             plot_height='small',
                             changed_params=changed_params,
                             x_range=x_range)
        estimator_status = ulog.get_dataset('estimator_status').data
        plot_data = []
        plot_labels = []
        input_data = [
            ('Health Flags (vel, pos, hgt)', estimator_status['health_flags']),
            ('Timeout Flags (vel, pos, hgt)',
             estimator_status['timeout_flags']),
            ('Velocity Check Bit',
             (estimator_status['innovation_check_flags']) & 0x1),
            ('Horizontal Position Check Bit',
             (estimator_status['innovation_check_flags'] >> 1) & 1),
            ('Vertical Position Check Bit',
             (estimator_status['innovation_check_flags'] >> 2) & 1),
            ('Mag X, Y, Z Check Bits',
             (estimator_status['innovation_check_flags'] >> 3) & 0x7),
            ('Yaw Check Bit',
             (estimator_status['innovation_check_flags'] >> 6) & 1),
            ('Airspeed Check Bit',
             (estimator_status['innovation_check_flags'] >> 7) & 1),
            ('Synthetic Sideslip Check Bit',
             (estimator_status['innovation_check_flags'] >> 8) & 1),
            ('Height to Ground Check Bit',
             (estimator_status['innovation_check_flags'] >> 9) & 1),
            ('Optical Flow X, Y Check Bits',
             (estimator_status['innovation_check_flags'] >> 10) & 0x3),
        ]
        # filter: show only the flags that have non-zero samples
        for cur_label, cur_data in input_data:
            if np.amax(cur_data) > 0.1:
                data_label = 'flags_' + str(
                    len(plot_data))  # just some unique string
                plot_data.append(lambda d, data=cur_data, label=data_label:
                                 (label, data))
                plot_labels.append(cur_label)
                if len(plot_data) >= 8:  # cannot add more than that
                    break

        if len(plot_data) == 0:
            # add the plot even in the absence of any problem, so that the user
            # can validate that (otherwise it's ambiguous: it could be that the
            # estimator_status topic is not logged)
            plot_data = [lambda d: ('flags', input_data[0][1])]
            plot_labels = [input_data[0][0]]
        data_plot.add_graph(plot_data, colors8[0:len(plot_data)], plot_labels)
        if data_plot.finalize() is not None: plots.append(data_plot)
    except (KeyError, IndexError) as error:
        print('Error in estimator plot: ' + str(error))

    # RC Quality
    data_plot = DataPlot(data,
                         plot_config,
                         'input_rc',
                         title='RC Quality',
                         plot_height='small',
                         y_range=Range1d(0, 1),
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph([lambda data: ('rssi', data['rssi'] / 100), 'rc_lost'],
                        colors3[0:2], ['RSSI [0, 1]', 'RC Lost (Indicator)'])
    data_plot.change_dataset('vehicle_status')
    data_plot.add_graph(['rc_signal_lost'], colors3[2:3],
                        ['RC Lost (Detected)'])
    if data_plot.finalize() is not None: plots.append(data_plot)

    # cpu load
    data_plot = DataPlot(data,
                         plot_config,
                         'cpuload',
                         title='CPU & RAM',
                         plot_height='small',
                         y_range=Range1d(0, 1),
                         changed_params=changed_params,
                         x_range=x_range)
    data_plot.add_graph(['ram_usage', 'load'], [colors3[1], colors3[2]],
                        ['RAM Usage', 'CPU Load'])
    data_plot.add_span('load', line_color=colors3[2])
    data_plot.add_span('ram_usage', line_color=colors3[1])
    plot_flight_modes_background(data_plot, flight_mode_changes, vtol_states)
    if data_plot.finalize() is not None: plots.append(data_plot)

    # sampling: time difference
    try:
        data_plot = DataPlot(data,
                             plot_config,
                             'sensor_combined',
                             y_range=Range1d(0, 25e3),
                             y_axis_label='[us]',
                             title='Sampling Regularity of Sensor Data',
                             plot_height='small',
                             changed_params=changed_params,
                             x_range=x_range)
        sensor_combined = ulog.get_dataset('sensor_combined').data
        sampling_diff = np.diff(sensor_combined['timestamp'])
        min_sampling_diff = np.amin(sampling_diff)

        plot_dropouts(data_plot.bokeh_plot, ulog.dropouts, min_sampling_diff)

        data_plot.add_graph(
            [lambda data: ('timediff', np.append(sampling_diff, 0))],
            [colors3[2]], ['delta t (between 2 logged samples)'])
        data_plot.change_dataset('estimator_status')
        data_plot.add_graph(
            [lambda data: ('time_slip', data['time_slip'] * 1e6)],
            [colors3[1]], ['Estimator time slip (cumulative)'])
        if data_plot.finalize() is not None: plots.append(data_plot)
    except:
        pass

    # exchange all DataPlot's with the bokeh_plot and handle parameter changes

    param_changes_button = Button(label="Hide Parameter Changes", width=170)
    param_change_labels = []

    # FIXME: this should be a CustomJS callback, not on the server. However this
    # did not work for me.
    def param_changes_button_clicked():
        """ callback to show/hide parameter changes """
        for label in param_change_labels:
            if label.visible:
                param_changes_button.label = 'Show Parameter Changes'
                label.visible = False
                label.text_alpha = 0  # label.visible does not work, so we use this instead
            else:
                param_changes_button.label = 'Hide Parameter Changes'
                label.visible = True
                label.text_alpha = 1

    param_changes_button.on_click(param_changes_button_clicked)

    jinja_plot_data = []
    for i in range(len(plots)):
        if plots[i] is None:
            plots[i] = widgetbox(param_changes_button,
                                 width=int(plot_width * 0.99))
        if isinstance(plots[i], DataPlot):
            if plots[i].param_change_label is not None:
                param_change_labels.append(plots[i].param_change_label)

            plot_title = plots[i].title
            plots[i] = plots[i].bokeh_plot

            fragment = 'Nav-'+plot_title.replace(' ', '-') \
                .replace('&', '_').replace('(', '').replace(')', '')
            jinja_plot_data.append({
                'model_id': plots[i].ref['id'],
                'fragment': fragment,
                'title': plot_title
            })

    # changed parameters
    plots.append(get_changed_parameters(ulog.initial_parameters, plot_width))

    # information about which messages are contained in the log
    # TODO: need to load all topics for this (-> log loading will take longer)
    #       but if we load all topics and the log contains some (external) topics
    #       with buggy timestamps, it will affect the plotting.
    #    data_list_sorted = sorted(ulog.data_list, key=lambda d: d.name + str(d.multi_id))
    #    table_text = []
    #    for d in data_list_sorted:
    #        message_size = sum([ULog.get_field_size(f.type_str) for f in d.field_data])
    #        num_data_points = len(d.data['timestamp'])
    #        table_text.append((d.name, str(d.multi_id), str(message_size), str(num_data_points),
    #           str(message_size * num_data_points)))
    #    topics_info = '<table><tr><th>Name</th><th>Topic instance</th><th>Message Size</th>' \
    #            '<th>Number of data points</th><th>Total bytes</th></tr>' + ''.join(
    #            ['<tr><td>'+'</td><td>'.join(list(x))+'</td></tr>' for x in table_text]) + '</table>'
    #    topics_div = Div(text=topics_info, width=int(plot_width*0.9))
    #    plots.append(widgetbox(topics_div, width=int(plot_width*0.9)))

    # log messages
    plots.append(get_logged_messages(ulog.logged_messages, plot_width))

    # perf & top output
    top_data = ''
    perf_data = ''
    for state in ['pre', 'post']:
        if 'perf_top_' + state + 'flight' in ulog.msg_info_multiple_dict:
            current_top_data = ulog.msg_info_multiple_dict['perf_top_' +
                                                           state + 'flight'][0]
            flight_data = escape('\n'.join(current_top_data))
            top_data += '<p>' + state.capitalize(
            ) + ' Flight:<br/><pre>' + flight_data + '</pre></p>'
        if 'perf_counter_' + state + 'flight' in ulog.msg_info_multiple_dict:
            current_perf_data = ulog.msg_info_multiple_dict['perf_counter_' +
                                                            state +
                                                            'flight'][0]
            flight_data = escape('\n'.join(current_perf_data))
            perf_data += '<p>' + state.capitalize(
            ) + ' Flight:<br/><pre>' + flight_data + '</pre></p>'

    additional_data_html = ''
    if len(top_data) > 0:
        additional_data_html += '<h5>Processes</h5>' + top_data
    if len(perf_data) > 0:
        additional_data_html += '<h5>Performance Counters</h5>' + perf_data
    if len(additional_data_html) > 0:
        # hide by default & use a button to expand
        additional_data_html = '''
<button class="btn btn-secondary" data-toggle="collapse" style="min-width:0;"
 data-target="#show-additional-data">Show additional Data</button>
<div id="show-additional-data" class="collapse">
{:}
</div>
'''.format(additional_data_html)
        additional_data_div = Div(text=additional_data_html,
                                  width=int(plot_width * 0.9))
        plots.append(
            widgetbox(additional_data_div, width=int(plot_width * 0.9)))

    curdoc().template_variables['plots'] = jinja_plot_data

    return plots
예제 #20
0
count_source = ColumnDataSource(
    data=dict(section_col=df_selected.section, bucket=df_selected.bucket, group_A=df_selected.group_A, group_B=df_selected.group_B))

# Create the figure plot
count_Plot = figure(title="Count plot", tools="",
                    toolbar_location=None, plot_height=400, plot_width=800)

count_Plot.xaxis.axis_label = "Bucket number"
count_Plot.yaxis.axis_label = "Total count"

line_group_A = count_Plot.line('bucket', 'group_A', color='#A6CEE3', legend='Group A', source=count_source)
line_group_B = count_Plot.line('bucket', 'group_B', color='#B2DF8A', legend='Group B', source=count_source)

# Custom java script code will be exected to when Download data buttion will be clicked
code = open(join(dirname(__file__), "download_data.js")).read()
download_button = Button(label="Download data", button_type="success")
download_button.callback = CustomJS(args = dict(source=count_source),
                                    code = code)

# Create the selector for choosing sections
menu = [(x, x) for x in section_list]
selector = Dropdown(label="Select section", button_type="primary", menu=menu, width=350)

# On change in dropdown call selector_change function
selector.on_change('value', selector_change)

# Create div for stats on selected section
div_text = """
    <blockquote>
        <h4>Stats of the selected section</h4>
    </blockquote>
예제 #21
0
p3 = Network(label="label", edges="edges", values="values", color="color", data_source=sourceNetwork, width=650, height=450)

#Widgets
modelSelect = Select(options=modelsList)
tsneMetricSelect = Select(title="metrique", value='cosine', width=120, options=['braycurtis', 'canberra', 'chebyshev', 'cityblock', 'correlation', 'cosine', 'dice', 'euclidean', 'hamming', 'jaccard', 'kulsinski', 'mahalanobis', 'matching', 'minkowski', 'rogerstanimoto', 'russellrao', 'seuclidean', 'sokalmichener', 'sokalsneath', 'sqeuclidean', 'yule'])
tsneLoading = Div()
LoadingDiv = Div()
informationDiv = Div(width=600)
NumberElementsDiv = Div(width=250)
iterationCount = Div(width=100)
minus = Div(text='-',width=15)
plus = Div(text='+',width=15)
word1 = TextInput(width=200, title="Analogie")
word2 = TextInput(width=200, title="-")
word3 = TextInput(width=200, title="+")
calculateAnalogy = Button(label='Calculer', button_type='success', width=60)
equals = Div(text=" ", width=120)
searchBox = TextInput(width=250, placeholder="Rechercher ...")
searchButton = Button(label='Rechercher', button_type='success', width=100)
equals.css_classes = ["center"]
# p3.css_classes = ["blackBorder"]
analogyColumns = [
    TableColumn(field="words", title="Mots"),
    TableColumn(field="similarity", title="Similarit\u00E9"),
]
analogyDataTable = DataTable(source=sourceAnalogy, columns=analogyColumns, index_position=None, width=500, height=200)
analogy = row(column(word1, word2, word3, row(calculateAnalogy, Spacer(width=20), equals)), Spacer(width=40), analogyDataTable)
renderer = p2.select(dict(type=GlyphRenderer))
ds = renderer[0].data_source

d1 = Div(text="<h2>Choix d'un mod\u00E8le</h2>", width=500)
예제 #22
0
파일: create.py 프로젝트: mpmbq2/StimPy
p.add_layout(peak_start)

slider2.callback = CustomJS(args=dict(span=peak_start, slider=slider2), code="""
        span.location = slider.value;
    """)

cb_up = CustomJS(args=dict(span=peak_start, slider=slider2), code="""
        span.location = span.location + 1;
        slider.value = span.location;
    """)
cb_down = CustomJS(args=dict(span=peak_start, slider=slider2), code="""
        span.location = span.location - 1;
        slider.value = span.location;
    """)

button_up = Button(label=">", callback=cb_up)
button_down = Button(label="<", callback=cb_down)

button_group = RadioButtonGroup(
                    labels=["Option 1", "Option 2", "Option 3"],
                    active=0
                    )

select = Select(
            title="Option:",
            value="foo",
            options=["foo", "bar", "baz", "quux"]
            )

button_1 = Button(label="Button 1")
button_2 = Button(label="Button 2")
예제 #23
0
curr_dir = os.path.dirname(os.path.realpath(__file__))
data_dir = os.path.join(curr_dir, 'data')
# check to see if data directory exists, if not make it
if not os.path.isdir(data_dir):
	os.mkdir(data_dir)


def load_pickle_file(gdriveurl, filename):
	pathname = os.path.join(data_dir, filename)
	if not os.path.isfile(pathname):
		gdd.download_file_from_google_drive(file_id=gdriveurl, dest_path=pathname)
	with open(pathname, 'rb') as f:
		return pickle.load(f)

raw_speeches = load_pickle_file('1ghlAIXa9pBq1Qvc2JLfZMlb7uD2v6jCB', 'raw_speeches.pickle')
speechid_to_speaker = load_pickle_file('1j2GGzjTrrzCvoAMpa08mtQnoTNbt4Kbe', 'speechid_to_speaker.pickle')

button = Button(label = "Get Speech")
input = TextInput(value = "Speechid")
output = Paragraph()
output2 = Paragraph()
output3 = Paragraph()

def update():
	output.text = "" + speechid_to_speaker[input.value]
	output2.text = "\r\n"
	output3.text = raw_speeches[input.value]
button.on_click(update)
layout = column(input, button, output, output2, output3)
curdoc().add_root(layout)
예제 #24
0
#    p2= DataTable(source=s2, columns=columns, width=wi, height=400)


    end_slider=max(df.n_vote)
    nvote_slider = Slider(start=0, end=end_slider, value=0,step=10, title="Nombre de votes minimum", callback=filtervote)
    filtervote.args["nvote"] = nvote_slider
    vote_slider = Slider(start=50, end=100, value=50, title="Approbation/rejet(%)", callback=filtervote)
    filtervote.args["vote"] = vote_slider
    
    toggle = Toggle(label="Cacher points non significatifs", callback=filtervote, width=50)
    toggle_expl=Div(text="""Ce bouton masque les propositions dont l'approbation <b>ne peut pas être distinguée statistiquement de 50%</b>. Par exemple, une approbation de 60% ne veut presque rien dire si on la calcule sur 10 votes, par contre sur 5000 on est sûr qu'une majorité des votants est d'accord avec la proposition.Formellement, ce filtrage est obtenu par un test binomial exact bi-directionnel avec correction de Bonferroni.""")
    toggletxt = Toggle(label="Afficher le titre des revendications", callback=filtervote, width=50)
    toggletxt_exp = Div(text="""<b>Attention:</b> Filtrer les points et/ou zoomer avant d'afficher le texte pour que le graphique reste lisible.""")
    filtervote.args["ci"]=toggle
    filtervote.args["txt"]=toggletxt

    dl = Button(label="Télécharger données filtrées", button_type="success")
    dl.callback = CustomJS(args=dict(source=filsource),
                           code=open(join(dirname(__file__), "download.js")).read())

    
    bbox=column([nvote_slider, vote_slider, toggle, toggle_expl, toggletxt, toggletxt_exp, dl])
    
#    l=layout([[p1, bbox]], sizing_mode='stretch_both') # sizing mode is completely broken, fixed widths it is :(
    l=layout([[p1, bbox], [div], [p2]])
    #layout = column(sli1,p1)
    l.sizing_mode = 'scale_width'
    
    #show(l)
    curdoc().add_root(l)
예제 #25
0
mod_fpath = os.path.abspath(__file__)
mod_fname = os.path.split(mod_fpath)[1]
mod_fbase = os.path.splitext(mod_fname)[0]

def close_session():
    global session
    session.close()
    TheDoc.clear()
    #TheDoc.delete_modules()
    print ("Done")

MakeScatterPlot = Toggle(label="MakeScatter")

MessageBox = Paragraph(text="Go")
CloseButton = Button(label="Close")
CloseButton.on_click(close_session)
RowFilter = TextInput(value="")
ColumnChooser = CheckboxButtonGroup()

TheDoc = Document(title="NewDoc")
TheDoc.name = "TheDoc"


def setup(fpath=None):
    global session
    global FilePath
    FilePath = fpath
    TheDoc.title = str(fpath)
    session = push_session(TheDoc)
                       width=220,
                       height=10,
                       title="Enter article query")

get_alert2 = CustomJS(args=dict(text_query=text_query),
                      code="""

var str = text_query.value;
if (str == ""){
    alert("Input cannot be blank")
}
""")

button_query = Button(label='Search articles',
                      width=220,
                      height=10,
                      button_type='success',
                      callback=get_alert2)

empty_div = Div(text="", width=70, height=1)
query_grid = row(text_query,
                 column(empty_div, button_query),
                 name='query_grid')

text_user = TextInput(placeholder='Enter your name', value='saket', width=340)
username = Div(text="Username:"******"""

var usr = text_user.value;
예제 #27
0
파일: widgets.py 프로젝트: Tapiwap/Bokeh
# Import libraries
from bokeh.io import curdoc
from bokeh.models.widgets import (Button, TextInput, Paragraph, CheckboxGroup)
from bokeh.layouts import layout

# Initialise objects
text_input = TextInput(value='Tapiwa')
button = Button(label='Press Me')
check_boxes = CheckboxGroup(labels=['Tapiwa', 'Pat McGroin', 'These Nuts'],
                            active=[0])
output = Paragraph()


# create a method to greet people
def greet():
    for index in check_boxes.active:
        print("Hello, " + check_boxes.labels[index])


# make the button clickable
button.on_click(greet)

lay_out = layout([[button, check_boxes], [output]])
curdoc().add_root(lay_out)
예제 #28
0
def output_tab():

    hh_col = [TableColumn(field=col, title=col) for col in hh_sample.columns[:2]]+\
             [TableColumn(field='income', title='income',formatter=NumberFormatter(format="$0,0.00"))]+\
             [TableColumn(field=col, title=col) for col in hh_sample.columns[3:]]

    per_col = [TableColumn(field=col, title=col) for col in per_sample.columns]
    tour_col = [
        TableColumn(field=col, title=col) for col in iTours_sample.columns
    ]
    trip_col = [
        TableColumn(field=col, title=col) for col in itrips_sample.columns
    ]

    hh_src = ColumnDataSource(hh_sample.sort_values(by='hh_id'))
    per_src = ColumnDataSource(per_sample.sort_values(by='hh_id'))
    tour_src = ColumnDataSource(iTours_sample.sort_values(by='person_id'))
    trip_src = ColumnDataSource(itrips_sample.sort_values(by='person_id'))

    hh_div = Div(
        text=
        """<h3>Household Attribution Results</h3><p>Individual household attributes</p>
                        <ul><li><b>hh_id</b> : Household ID</li>
                        <li><b>maz</b> : Household Subzone</li>
                        <li><b>income</b> : Household Income</li>
                        <li><b>autos</b> : Number of Vehicles</li>
                        <li><b>size</b> : Household Size</li>
                        <li><b>workers</b> : Number of Workers in Household</li>
                        <li><b>auto_suff</b> : Auto Sufficiency</li></ul>""",
        width=int(column_width * .45))
    hh_tbl = DataTable(columns=hh_col,
                       source=hh_src,
                       height=200,
                       selectable=True,
                       width=int(column_width * .45),
                       fit_columns=True,
                       scroll_to_selection=True)

    per_div = Div(
        text=
        """<h3>Person Attribution Results</h3><p>Individual persons within a household</p>
                        <ul><li><b>hh_id</b> : Household ID</li>
                        <li><b>person_id</b> : Person ID</li>
                        <li><b>per_num</b> : Person Number in Household</li>
                        <li><b>age</b> : Age</li>
                        <li><b>gender</b> : Gender</li>
                        <li><b>type</b> : Person Type (worker, student, etc)</li></ul>""",
        width=int(column_width * .45))
    per_tbl = DataTable(columns=per_col,
                        source=per_src,
                        height=200,
                        selectable=True,
                        width=int(column_width * .45),
                        fit_columns=True,
                        scroll_to_selection=True)

    tour_div = Div(
        text="""<h3>Tour Results</h3><p>Tours by person and household</p>
                        <ul><li><b>hh_id</b> : Household ID</li>
                        <li><b>person_id</b> : Person ID</li>
                        <li><b>tour_id</b> : Tour ID (0=first tour, 1 second tour, ect)</li>
                        <li><b>tour_category</b> : Mandatory, Non-Mandatory</li>
                        <li><b>tour_purpose</b> : Purpose of travel</li>
                        <li><b>maz</b> : Origin and destination subzone</li>
                        <li><b>tour_mode</b> : Mode of travel</li></ul>""",
        width=int(column_width * .4))
    tour_tbl = DataTable(columns=tour_col,
                         source=tour_src,
                         height=250,
                         selectable=True,
                         width=int(column_width * .45),
                         fit_columns=True,
                         scroll_to_selection=True)

    line_div = trip_div = Div(text="""<hr>""", width=column_width)
    trip_div = Div(
        text="""<h3>Trip Results</h3><p>Trips by person and household</p>
                        <ul><li><b>hh_id</b> : Household ID</li>
                        <li><b>person_id</b> : Person ID</li>
                        <li><b>tour_id</b> : Tour ID (0=first tour, 1 second tour, ect)</li>
                        <li><b>purpose</b> : Origin and destination trip purpose</li>
                        <li><b>maz</b> : Origin and destination subzone</li>
                        <li><b>trip_mode</b> : Mode of travel</li>
                        <li><b>tap</b> : boarding and alighting transit id</li></ul>""",
        width=int(column_width * .45))
    trip_tbl = DataTable(columns=trip_col,
                         source=trip_src,
                         height=250,
                         selectable=True,
                         width=int(column_width * .45),
                         fit_columns=True,
                         scroll_to_selection=True)

    def hh_select():

        indices = hh_src.selected.indices
        if len(indices) == 1:
            hh_id = hh_src.data["hh_id"][indices[0]]

            new_indices = [
                i for i, h in enumerate(per_src.data["hh_id"]) if h == hh_id
            ]
            per_src.selected.indices = new_indices

    #hh_src.on_change('selected',my_tap_handler)

    per_button = Button(label="Select Person Level", button_type="default")
    per_button.on_click(hh_select)

    def per_select():

        indices = per_src.selected.indices
        if len(indices) == 1:
            per_id = per_src.data["person_id"][indices[0]]

            new_indices = [
                i for i, p in enumerate(tour_src.data["person_id"])
                if p == per_id
            ]
            tour_src.selected.indices = new_indices

    tour_button = Button(label="Select Person Tour", button_type="default")
    tour_button.on_click(per_select)

    def trip_select():

        indices = tour_src.selected.indices
        if len(indices) == 1:
            per_id = tour_src.data["person_id"][indices[0]]
            tour_id = tour_src.data["tour_id"][indices[0]]

            new_indices = []
            i = 0
            while i < len(trip_src.data["person_id"]):
                #trip_src.data["person_id"][i] == per_id
                if trip_src.data["person_id"][i] == per_id:
                    if trip_src.data["tour_id"][i] == tour_id:
                        new_indices.append(i)
                i += 1

            trip_src.selected.indices = new_indices

    trip_button = Button(label="Select Person Trip", button_type="default")
    trip_button.on_click(trip_select)

    output_title = Div(text="""<h1>Model Output Files</h1>""",
                       width=column_width)
    output_description = Div(
        text=
        """<p>The ABM produces output files for modeled householdes, modeled persons,
    mandatory trip locations (work, school, university), trips, tours, ect. Model data calibrated to the
    CMAP Household Travel Survey (2007-2009)<p>""",
        width=column_width)

    #return row(Spacer(width = margin),column(Spacer(height=25),output_title,output_description, hh_div, hh_tbl,  per_div, per_button,per_tbl,
    #             Spacer(height=10),tour_div,tour_button, tour_tbl, Spacer(height=10),trip_div,trip_button, trip_tbl))

    return (row(
        Spacer(width=margin),
        column(
            Spacer(height=25), output_title, output_description,
            row(column(hh_div, hh_tbl, per_button),
                Spacer(width=int(column_width * .1)),
                column(per_div, per_tbl, tour_button)), line_div,
            row(column(tour_div, tour_tbl, trip_button),
                Spacer(width=int(column_width * .1)),
                column(trip_div, trip_tbl)))))
예제 #29
0
    _ = np.seterr(**old_set)


def _customJS(fname, source, script="download.js"):
    return CustomJS(args=dict(source=source, fname=fname),
                    code=open(join(dirname(__file__), script)).read())


sql_query.on_change('value', query_change)
sql_query2.on_change('value', query_change)
log_axes.on_change('active', scale_axes)
x_col.on_change('value', column_change)
y_col.on_change('value', column_change)
plot_type.on_change('value', create_line_plot)

button_dmo_sub = Button(label="Download DMO Query", button_type="primary")
button_dmo_all = Button(label="Download DMO Catalog", button_type="primary")
button_disk_sub = Button(label="Download Disk Query", button_type="danger")
button_disk_all = Button(label="Download Disk Catalog", button_type="danger")
button_dmo_all.callback = _customJS('pelvis_dmo_all.csv', dmo_data)
button_dmo_sub.callback = _customJS('pelvis_dmo_query.csv', dmo_source)
button_disk_all.callback = _customJS('pelvis_disk_all.csv', disk_data)
button_disk_sub.callback = _customJS('pelvis_disk_query.csv', disk_source)
button_list = [
    button_dmo_sub, button_dmo_all, button_disk_sub, button_disk_all
]
download_buttons = widgetbox(button_list, sizing_mode="scale_both")

# Setup the page layout
tab1_desc = Div(text=open(join(dirname(__file__), "tab_1.html")).read(),
                sizing_mode="scale_width")
def initialize(curr_doc: CurrentDoc, max_indep_elements=20, catch_radius=0.15):
    """
    Creates and configures all bokeh objects and starts the web app.
    :param max_indep_elements: maximum number of node independent elements accepted in the input plot (int)
    :param catch_radius: radius in which to select an element in input plot (double)
    :return: none
    """

    curr_doc.catch_radius = catch_radius
    '''
    ###############################
    # TEXT BOXES
    ###############################
    '''
    # Div object showing x and y position of the cursor in the input plot
    div_xy = Div(width=75, height=25)

    # Div object showing hints for the graphical input into the input plot through the element buttons
    div_input_width = curr_doc.plot_input.plot_width - div_xy.width - 10
    curr_doc.div_input = Div(width=div_input_width, height=div_xy.height)

    # Div object showing general text messages to the user
    curr_doc.div_msg = Div(css_classes=["MSG_BOX"],
                           text=" ",
                           width=curr_doc.plot_input.plot_width,
                           height=100)
    # doc.div_msg = Div(css_classes=["MSG_BOX"], text=" ", width=doc.plot_input.plot_width, height=100)
    '''
    ###############################
    # INPUT PLOT
    ###############################
    '''
    # style and configuration of the input plot
    # this plot is used to allow the user to connect mechanical elements
    tooltips = [("name", "@name_user"), ("(x, y)", "(@x{0.0}, @y{0.0})")]
    curr_doc.plot_input = figure(
        # plot_width=600, plot_height=300,
        tools="pan,wheel_zoom,reset,lasso_select,hover,save",
        toolbar_location="above",
        # x_axis_label='x', y_axis_label='y',
        x_minor_ticks=10,
        y_minor_ticks=10,
        x_range=Range1d(start=0, end=5),
        y_range=Range1d(start=0, end=5),
        match_aspect=True,
        aspect_scale=1.0,
        tooltips=tooltips,
    )
    curr_doc.plot_input.toolbar.logo = None
    configure_input_plot(curr_doc, curr_doc.plot_input, div_xy,
                         max_indep_elements)
    '''
    ###############################
    # OUTPUT PLOTS
    ###############################
    '''
    # initialize plots for the output after calculations
    plot_output_width = 800
    plot_output_height = 250
    curr_doc.plot_normal_f = figure(plot_width=plot_output_width,
                                    plot_height=plot_output_height,
                                    active_scroll="wheel_zoom")
    curr_doc.plot_normal_f.toolbar.logo = None
    curr_doc.plot_normal_f.title.text = 'Normal force'

    curr_doc.plot_normal_disp = figure(plot_width=plot_output_width,
                                       plot_height=plot_output_height,
                                       active_scroll="wheel_zoom")
    curr_doc.plot_normal_disp.toolbar.logo = None
    curr_doc.plot_normal_disp.title.text = 'Normal displacement'

    curr_doc.plot_shear_f = figure(plot_width=plot_output_width,
                                   plot_height=plot_output_height,
                                   active_scroll="wheel_zoom")
    curr_doc.plot_shear_f.toolbar.logo = None
    curr_doc.plot_shear_f.title.text = 'Shear force'

    curr_doc.plot_moment = figure(plot_width=plot_output_width,
                                  plot_height=plot_output_height,
                                  active_scroll="wheel_zoom")
    curr_doc.plot_moment.toolbar.logo = None
    curr_doc.plot_moment.title.text = 'Bending moment'

    curr_doc.plot_shear_disp = figure(plot_width=plot_output_width,
                                      plot_height=plot_output_height,
                                      active_scroll="wheel_zoom")
    curr_doc.plot_shear_disp.toolbar.logo = None
    curr_doc.plot_shear_disp.title.text = 'Shear displacement'

    curr_doc.plot_shear_angle = figure(plot_width=plot_output_width,
                                       plot_height=plot_output_height,
                                       active_scroll="wheel_zoom")
    curr_doc.plot_shear_angle.toolbar.logo = None
    curr_doc.plot_shear_angle.title.text = 'Rotation angle'

    curr_doc.plot_list = [
        curr_doc.plot_normal_f, curr_doc.plot_normal_disp,
        curr_doc.plot_shear_f, curr_doc.plot_moment, curr_doc.plot_shear_angle,
        curr_doc.plot_shear_disp
    ]

    # add plot renderer
    ds = ColumnDataSource(data=dict(x=[], y=[]))
    curr_doc.plot_normal_f.circle('x', 'y', source=ds)
    curr_doc.plot_normal_disp.circle('x', 'y', source=ds)
    curr_doc.plot_shear_f.circle('x', 'y', source=ds)
    curr_doc.plot_moment.circle('x', 'y', source=ds)
    curr_doc.plot_shear_disp.circle('x', 'y', source=ds)
    curr_doc.plot_normal_f.circle('x', 'y', source=ds)
    curr_doc.plot_shear_angle.circle('x', 'y', source=ds)
    '''
    ###############################
    # TEST CASES
    ###############################
    '''
    menu_tc = [("Single beam load", "single_beam_load"),
               ("Two beam lineload", "two_beam_lineload"),
               ("Angled structure", "fin_struc_soft_lab")]
    dropdown_tc = Dropdown(label="Show test case", menu=menu_tc, width=150)
    dropdown_tc.on_change('value',
                          partial(vis_cbs.cb_plot_testcase, curr_doc=curr_doc))
    # partial(vis_cbs.cb_get_textinput, key=key_elinfo_n)
    '''
    ###############################
    # CALCULATE AND DELETE BUTTONS
    ###############################
    '''
    # add and configure a button to start calculations
    button_calc = Button(label="Calculate", width=240)
    button_calc.on_click(
        partial(vis_cbs.cb_button_calculation, curr_doc, button_calc))

    # add and configure a button to delete selected elements of the input graph
    b_del_w = int((button_calc.width - 10) / 2)
    button_del_selected = Button(label="Delete selected", width=b_del_w)
    button_del_selected.on_click(
        partial(vis_cbs.cb_button_delete,
                curr_doc=curr_doc,
                all_selected=False))

    # add and configure a button to delete selected elements of the input graph
    button_del_all = Button(label="Delete all", width=b_del_w)
    button_del_all.on_click(
        partial(vis_cbs.cb_button_delete, curr_doc=curr_doc,
                all_selected=True))
    '''
    ############################################
    # BOX OF ELEMENTS TO SELECT FOR INPUT PLOT
    ############################################
    '''
    # titles for groups of mechanical elements
    text_supports = Div(text="Supports:", width=100, height=20)
    text_springs = Div(text="Springs:", width=100, height=20)
    text_node = Div(text="Node:", width=100, height=20)
    text_joints = Div(text="Joints:", width=100, height=20)
    text_elements = Div(text="Line elements:", width=100, height=20)
    text_loads = Div(text="Loads:", width=100, height=20)

    b_height = 50
    b_line_width = 72

    # configure buttons for mechanical supports
    button_support_clamped = Button(
        label="",
        css_classes=[eLnum.ElSupEnum.SUPPORT_CLAMPED.name],
        width=b_height,
        height=b_height)
    curr_doc.buttons[
        eLnum.ElSupEnum.SUPPORT_CLAMPED.value] = button_support_clamped
    button_support_clamped.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.SUPPORT_CLAMPED))

    button_support_normal = Button(
        label="",
        css_classes=[eLnum.ElSupEnum.SUPPORT_NORMAL_FORCE.name],
        width=b_height,
        height=b_height)
    curr_doc.buttons[
        eLnum.ElSupEnum.SUPPORT_NORMAL_FORCE.value] = button_support_normal
    button_support_normal.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.SUPPORT_NORMAL_FORCE))

    button_support_transverse = Button(
        label="",
        css_classes=[eLnum.ElSupEnum.SUPPORT_TRANSVERSE_FORCE.name],
        width=b_height,
        height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.SUPPORT_TRANSVERSE_FORCE.
                     value] = button_support_transverse
    button_support_transverse.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.SUPPORT_TRANSVERSE_FORCE))

    button_support_fixed_conti = Button(
        label="",
        css_classes=[eLnum.ElSupEnum.SUPPORT_FIXED_CONTINUOUS.name],
        width=b_height,
        height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.SUPPORT_FIXED_CONTINUOUS.
                     value] = button_support_fixed_conti
    button_support_fixed_conti.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.SUPPORT_FIXED_CONTINUOUS))

    button_support_fixed_joint = Button(
        label="",
        css_classes=[eLnum.ElSupEnum.SUPPORT_FIXED_JOINT.name],
        width=b_height,
        height=b_height)
    curr_doc.buttons[
        eLnum.ElSupEnum.SUPPORT_FIXED_JOINT.value] = button_support_fixed_joint
    button_support_fixed_joint.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.SUPPORT_FIXED_JOINT))

    button_support_roller_conti = Button(
        label="",
        css_classes=[eLnum.ElSupEnum.SUPPORT_ROLLER_CONTINUOUS.name],
        width=b_height,
        height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.SUPPORT_ROLLER_CONTINUOUS.
                     value] = button_support_roller_conti
    button_support_roller_conti.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.SUPPORT_ROLLER_CONTINUOUS))

    button_support_roller_joint = Button(
        label="",
        css_classes=[eLnum.ElSupEnum.SUPPORT_ROLLER_JOINT.name],
        width=b_height,
        height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.SUPPORT_ROLLER_JOINT.
                     value] = button_support_roller_joint
    button_support_roller_joint.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.SUPPORT_ROLLER_JOINT))

    button_spring_support = Button(
        label="",
        css_classes=[eLnum.ElSupEnum.SPRING_SUPPORT.name],
        width=b_height,
        height=b_height)
    curr_doc.buttons[
        eLnum.ElSupEnum.SPRING_SUPPORT.value] = button_spring_support
    button_spring_support.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.SPRING_SUPPORT))

    button_spring_moment_support = Button(
        label="",
        css_classes=[eLnum.ElSupEnum.SPRING_MOMENT_SUPPORT.name],
        width=b_height,
        height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.SPRING_MOMENT_SUPPORT.
                     value] = button_spring_moment_support
    button_spring_moment_support.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.SPRING_MOMENT_SUPPORT))

    # configure curr_doc.buttons for connectors
    button_node = Button(label="",
                         css_classes=[eLnum.ElSupEnum.NODE.name],
                         width=b_height,
                         height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.NODE.value] = button_node
    button_node.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.NODE))

    button_joint = Button(label="",
                          css_classes=[eLnum.ElSupEnum.JOINT.name],
                          width=b_height,
                          height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.JOINT.value] = button_joint
    button_joint.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.JOINT))

    button_joint_normal = Button(
        label="",
        css_classes=[eLnum.ElSupEnum.JOINT_NORMAL_FORCE.name],
        width=b_height,
        height=b_height)
    curr_doc.buttons[
        eLnum.ElSupEnum.JOINT_NORMAL_FORCE.value] = button_joint_normal
    button_joint_normal.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.JOINT_NORMAL_FORCE))

    button_joint_transverse = Button(
        label="",
        css_classes=[eLnum.ElSupEnum.JOINT_TRANSVERSE_FORCE.name],
        width=b_height,
        height=b_height)
    curr_doc.buttons[
        eLnum.ElSupEnum.JOINT_TRANSVERSE_FORCE.value] = button_joint_transverse
    button_joint_transverse.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.JOINT_TRANSVERSE_FORCE))

    button_spring = Button(label="",
                           css_classes=[eLnum.ElSupEnum.SPRING.name],
                           width=b_line_width,
                           height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.SPRING.value] = button_spring
    button_spring.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.SPRING))

    # configure buttons for mechanical 1D or 2D elements
    # button_rod = Button(label="", css_classes=[eLnum.ElSupEnum.ROD.name], width=b_line_width, height=b_height)
    # curr_doc.buttons[eLnum.ElSupEnum.ROD.value] = button_rod
    # button_rod.on_click(partial(vis_cbs.cb_button_element_click, button_enum=eLnum.ElSupEnum.ROD))

    button_beam = Button(label="",
                         css_classes=[eLnum.ElSupEnum.BEAM.name],
                         width=b_line_width,
                         height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.BEAM.value] = button_beam
    button_beam.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.BEAM))

    # configure buttons for mechanical loads
    button_load_point = Button(label="",
                               css_classes=[eLnum.ElSupEnum.LOAD_POINT.name],
                               width=b_height,
                               height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.LOAD_POINT.value] = button_load_point
    button_load_point.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.LOAD_POINT))

    button_load_moment = Button(label="",
                                css_classes=[eLnum.ElSupEnum.LOAD_MOMENT.name],
                                width=b_height,
                                height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.LOAD_MOMENT.value] = button_load_moment
    button_load_moment.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.LOAD_MOMENT))

    button_load_random = Button(label="",
                                css_classes=[eLnum.ElSupEnum.LOAD_LINE.name],
                                width=b_line_width,
                                height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.LOAD_LINE.value] = button_load_random
    button_load_random.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.LOAD_LINE))

    button_load_temp = Button(label="",
                              css_classes=[eLnum.ElSupEnum.LOAD_TEMP.name],
                              width=b_height,
                              height=b_height)
    curr_doc.buttons[eLnum.ElSupEnum.LOAD_TEMP.value] = button_load_temp
    button_load_temp.on_click(
        partial(vis_cbs.cb_button_element_click,
                curr_doc=curr_doc,
                button_enum=eLnum.ElSupEnum.LOAD_TEMP))
    '''
    ###############################
    # ELEMENT INFO BOX
    ###############################
    '''
    elinfo_object_height = 26
    elinfo_label_width1 = 60
    elinfo_label_width2 = 40
    elinfo_input_width = 60

    # labels for values of an element of the input plot
    text_elinfo_name = Div(text="name:",
                           width=elinfo_label_width1,
                           height=elinfo_object_height)
    text_elinfo_x = Div(text="x:",
                        width=elinfo_label_width1,
                        height=elinfo_object_height)
    curr_doc.div_element_info["x"] = text_elinfo_x
    text_elinfo_y = Div(text="y:",
                        width=elinfo_label_width1,
                        height=elinfo_object_height)
    curr_doc.div_element_info["y"] = text_elinfo_y
    text_elinfo_angle1 = Div(text="angle:",
                             width=elinfo_label_width1,
                             height=elinfo_object_height)
    text_elinfo_angle2 = Div(text="°",
                             width=elinfo_label_width2 - 20,
                             height=elinfo_object_height)
    spacer_y_a = Div(text="",
                     width=text_elinfo_angle2.width,
                     height=elinfo_object_height)
    text_elinfo_k1 = Div(text="spring:",
                         width=elinfo_label_width1,
                         height=elinfo_object_height)
    text_elinfo_k2 = Div(text="* k",
                         width=elinfo_label_width2,
                         height=elinfo_object_height)
    text_elinfo_length1 = Div(text="length:",
                              width=elinfo_label_width1,
                              height=elinfo_object_height)
    text_elinfo_length2 = Div(text="* l",
                              width=elinfo_label_width2,
                              height=elinfo_object_height)
    text_elinfo_force1 = Div(text="force:",
                             width=elinfo_label_width1,
                             height=elinfo_object_height)
    text_elinfo_force2 = Div(text="* F",
                             width=elinfo_label_width2,
                             height=elinfo_object_height)
    text_elinfo_moment1 = Div(text="moment:",
                              width=elinfo_label_width1,
                              height=elinfo_object_height)
    text_elinfo_moment2 = Div(text="* M",
                              width=elinfo_label_width2,
                              height=elinfo_object_height)
    text_elinfo_beam = Div(text="BEAM",
                           width=elinfo_object_height,
                           height=elinfo_label_width1,
                           css_classes=["ELINFO_VERTICAL_TEXT"])
    text_elinfo_h = Div(text="* h",
                        width=elinfo_label_width2,
                        height=elinfo_object_height)
    text_elinfo_ei = Div(text="* EI",
                         width=elinfo_label_width2,
                         height=elinfo_object_height)
    text_elinfo_ea = Div(text="* EA",
                         width=elinfo_label_width2,
                         height=elinfo_object_height)
    text_elinfo_lineload = Div(text="LINE LOAD",
                               width=elinfo_object_height,
                               height=elinfo_label_width1,
                               css_classes=["ELINFO_VERTICAL_TEXT"])
    text_elinfo_xn = Div(text="* n",
                         width=elinfo_label_width2 - 10,
                         height=elinfo_object_height)
    curr_doc.div_element_info["xn"] = text_elinfo_xn
    text_elinfo_yq = Div(text="* q",
                         width=elinfo_label_width2 - 10,
                         height=elinfo_object_height)
    curr_doc.div_element_info["yq"] = text_elinfo_yq
    text_elinfo_temp = Div(text="TEMP.",
                           width=elinfo_object_height,
                           height=elinfo_label_width1,
                           css_classes=["ELINFO_VERTICAL_TEXT"])
    text_elinfo_dt = Div(text="* dT",
                         width=elinfo_label_width2,
                         height=elinfo_object_height)
    text_elinfo_tt = Div(text="* T",
                         width=elinfo_label_width2,
                         height=elinfo_object_height)
    text_elinfo_at = Div(text="* &alpha;T",
                         width=elinfo_label_width2,
                         height=elinfo_object_height)

    # text inputs showing the current value of an input plot element and taking input for a value change
    # name
    input_elinfo_name = TextInput(value="-",
                                  width=elinfo_input_width,
                                  height=elinfo_object_height,
                                  disabled=True)
    key_elinfo_n = "name"
    curr_doc.input_element_info[key_elinfo_n] = input_elinfo_name
    input_elinfo_name.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput, curr_doc=curr_doc, key=key_elinfo_n))

    # xy
    input_elinfo_x = TextInput(value="-",
                               width=elinfo_input_width,
                               height=elinfo_object_height,
                               disabled=True)
    key_elinfo_x = "x"
    curr_doc.input_element_info[key_elinfo_x] = input_elinfo_x
    input_elinfo_x.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput, curr_doc=curr_doc, key=key_elinfo_x))

    input_elinfo_y = TextInput(value="-",
                               width=elinfo_input_width,
                               height=elinfo_object_height,
                               disabled=True)
    key_elinfo_y = "y"
    curr_doc.input_element_info[key_elinfo_y] = input_elinfo_y
    input_elinfo_y.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput, curr_doc=curr_doc, key=key_elinfo_y))

    # angle
    input_elinfo_angle = TextInput(value="-",
                                   width=elinfo_input_width,
                                   height=elinfo_object_height,
                                   disabled=True)
    key_elinfo_angle = "angle"
    curr_doc.input_element_info[key_elinfo_angle] = input_elinfo_angle
    input_elinfo_angle.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput,
                curr_doc=curr_doc,
                key=key_elinfo_angle))

    # spring constant
    input_elinfo_k = TextInput(value="-",
                               width=elinfo_input_width,
                               height=elinfo_object_height,
                               disabled=True)
    key_elinfo_k = "k"
    curr_doc.input_element_info[key_elinfo_k] = input_elinfo_k
    input_elinfo_k.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput, curr_doc=curr_doc, key=key_elinfo_k))

    # length
    input_elinfo_length = TextInput(value="-",
                                    width=elinfo_input_width,
                                    height=elinfo_object_height,
                                    disabled=True)
    key_elinfo_length = "length"
    curr_doc.input_element_info[key_elinfo_length] = input_elinfo_length
    input_elinfo_k.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput,
                curr_doc=curr_doc,
                key=key_elinfo_length))

    # point load
    input_elinfo_force = TextInput(value="-",
                                   width=elinfo_input_width,
                                   height=elinfo_object_height,
                                   disabled=True)
    key_elinfo_f = "force"
    curr_doc.input_element_info[key_elinfo_f] = input_elinfo_force
    input_elinfo_force.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput, curr_doc=curr_doc, key=key_elinfo_f))

    # moment
    input_elinfo_moment = TextInput(value="-",
                                    width=elinfo_input_width,
                                    height=elinfo_object_height,
                                    disabled=True)
    key_elinfo_m = "moment"
    curr_doc.input_element_info[key_elinfo_m] = input_elinfo_moment
    input_elinfo_moment.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput, curr_doc=curr_doc, key=key_elinfo_m))

    # beam
    input_elinfo_h = TextInput(value="-",
                               width=elinfo_input_width,
                               height=elinfo_object_height,
                               disabled=True)
    key_elinfo_h = "h"
    curr_doc.input_element_info[key_elinfo_h] = input_elinfo_h
    input_elinfo_h.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput, curr_doc=curr_doc, key=key_elinfo_h))

    check_elinfo_beam = CheckboxGroup(labels=["EA -> inf.", "EI -> inf."],
                                      active=[],
                                      disabled=True,
                                      width=elinfo_input_width +
                                      elinfo_label_width1)
    curr_doc.group_element_info["beam"] = check_elinfo_beam
    check_elinfo_beam.on_change(
        'active', partial(vis_cbs.cb_elinfo_beam, curr_doc=curr_doc))

    input_elinfo_ea = TextInput(value="-",
                                width=elinfo_input_width,
                                height=elinfo_object_height,
                                disabled=True)
    key_elinfo_ea = "ea"
    curr_doc.input_element_info[key_elinfo_ea] = input_elinfo_ea
    input_elinfo_ea.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput, curr_doc=curr_doc,
                key=key_elinfo_ea))

    input_elinfo_ei = TextInput(value="-",
                                width=elinfo_input_width,
                                height=elinfo_object_height,
                                disabled=True)
    key_elinfo_ei = "ei"
    curr_doc.input_element_info[key_elinfo_ei] = input_elinfo_ei
    input_elinfo_ei.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput, curr_doc=curr_doc,
                key=key_elinfo_ei))

    # line load
    radio_elinfo_ll = RadioGroup(
        labels=["local", "global"],
        active=0,
        disabled=True,  # "angle"
        width=elinfo_input_width + elinfo_label_width1)
    curr_doc.group_element_info["ll"] = radio_elinfo_ll
    radio_elinfo_ll.on_change(
        'active', partial(vis_cbs.cb_elinfo_lineload, curr_doc=curr_doc))

    input_elinfo_xns = TextInput(value="-",
                                 width=elinfo_input_width,
                                 height=elinfo_object_height + 20,
                                 disabled=True,
                                 title="start")
    key_elinfo_xns = "xn_start"
    curr_doc.input_element_info[key_elinfo_xns] = input_elinfo_xns
    input_elinfo_xns.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput,
                curr_doc=curr_doc,
                key=key_elinfo_xns))

    input_elinfo_xne = TextInput(value="-",
                                 width=elinfo_input_width,
                                 height=elinfo_object_height + 20,
                                 disabled=True,
                                 title="end")
    key_elinfo_xne = "xn_end"
    curr_doc.input_element_info[key_elinfo_xne] = input_elinfo_xne
    input_elinfo_xne.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput,
                curr_doc=curr_doc,
                key=key_elinfo_xne))

    input_elinfo_yqs = TextInput(value="-",
                                 width=elinfo_input_width,
                                 height=elinfo_object_height,
                                 disabled=True)
    key_elinfo_yqs = "yq_start"
    curr_doc.input_element_info[key_elinfo_yqs] = input_elinfo_yqs
    input_elinfo_yqs.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput,
                curr_doc=curr_doc,
                key=key_elinfo_yqs))

    input_elinfo_yqe = TextInput(value="-",
                                 width=elinfo_input_width,
                                 height=elinfo_object_height,
                                 disabled=True)
    key_elinfo_yqe = "yq_end"
    curr_doc.input_element_info[key_elinfo_yqe] = input_elinfo_yqe
    input_elinfo_yqe.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput,
                curr_doc=curr_doc,
                key=key_elinfo_yqe))

    # temperature load
    input_elinfo_dt = TextInput(value="-",
                                width=elinfo_input_width,
                                height=elinfo_object_height,
                                disabled=True)
    key_elinfo_dt = "dT"
    curr_doc.input_element_info[key_elinfo_dt] = input_elinfo_dt
    input_elinfo_dt.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput, curr_doc=curr_doc,
                key=key_elinfo_dt))

    input_elinfo_tt = TextInput(value="-",
                                width=elinfo_input_width,
                                height=elinfo_object_height,
                                disabled=True)
    key_elinfo_tt = "T"
    curr_doc.input_element_info[key_elinfo_tt] = input_elinfo_tt
    input_elinfo_tt.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput, curr_doc=curr_doc,
                key=key_elinfo_tt))

    input_elinfo_at = TextInput(value="-",
                                width=elinfo_input_width,
                                height=elinfo_object_height,
                                disabled=True)
    key_elinfo_at = "aT"
    curr_doc.input_element_info[key_elinfo_at] = input_elinfo_at
    input_elinfo_at.on_change(
        'value',
        partial(vis_cbs.cb_get_textinput, curr_doc=curr_doc,
                key=key_elinfo_at))

    # button for deleting an input plot element
    button_elinfo_del = Button(label="Delete element",
                               width=elinfo_label_width1 + elinfo_input_width +
                               elinfo_label_width2,
                               height=elinfo_object_height + 10,
                               disabled=False)
    button_elinfo_del.on_click(
        partial(vis_cbs.cb_button_delete, curr_doc=curr_doc, single=True))
    '''
    ###############################
    # CHECKBOXES FOR OUTPUT PLOTS
    ###############################
    '''
    check_labels = ["Min/ max values", "Start/ end values", "Zero points"]
    check_init_active = [1]

    check_plot_nf = CheckboxGroup(labels=check_labels,
                                  active=check_init_active)  # inline=False
    text_plot_nf = Div(text="", width=100, height=10)
    check_plot_nf.on_change(
        'active',
        partial(vis_cbs.cb_toggle_characteristic_values,
                curr_doc=curr_doc,
                output_plot=curr_doc.plot_normal_f,
                div=text_plot_nf))

    check_plot_nd = CheckboxGroup(labels=check_labels,
                                  active=check_init_active)
    text_plot_nd = Div(text="", width=100, height=10)
    check_plot_nd.on_change(
        'active',
        partial(vis_cbs.cb_toggle_characteristic_values,
                curr_doc=curr_doc,
                output_plot=curr_doc.plot_normal_disp,
                div=text_plot_nd))

    check_plot_sf = CheckboxGroup(labels=check_labels,
                                  active=check_init_active)
    text_plot_sf = Div(text="", width=100, height=10)
    check_plot_sf.on_change(
        'active',
        partial(vis_cbs.cb_toggle_characteristic_values,
                curr_doc=curr_doc,
                output_plot=curr_doc.plot_shear_f,
                div=text_plot_sf))

    check_plot_mo = CheckboxGroup(labels=check_labels,
                                  active=check_init_active)
    text_plot_mo = Div(text="", width=100, height=10)
    check_plot_mo.on_change(
        'active',
        partial(vis_cbs.cb_toggle_characteristic_values,
                curr_doc=curr_doc,
                output_plot=curr_doc.plot_moment,
                div=text_plot_mo))

    check_plot_sa = CheckboxGroup(labels=check_labels,
                                  active=check_init_active)
    text_plot_sa = Div(text="", width=100, height=10)
    check_plot_sa.on_change(
        'active',
        partial(vis_cbs.cb_toggle_characteristic_values,
                curr_doc=curr_doc,
                output_plot=curr_doc.plot_shear_angle,
                div=text_plot_sa))

    check_plot_sd = CheckboxGroup(labels=check_labels,
                                  active=check_init_active)
    text_plot_sd = Div(text="", width=100, height=10)
    check_plot_sd.on_change(
        'active',
        partial(vis_cbs.cb_toggle_characteristic_values,
                curr_doc=curr_doc,
                output_plot=curr_doc.plot_shear_disp,
                div=text_plot_sd))
    '''
    ###############################
    # IMAGES: SIGN CONVENTION
    ###############################
    '''
    sign_convention_N = Div(
        text=
        "<img src='/System_of_Beams/static/images/sign_convention_N_u.png' width=100 height=60>",
        width=100,
        height=60)
    sign_convention_u = Div(
        text=
        "<img src='/System_of_Beams/static/images/sign_convention_N_u.png' width=100 height=60>",
        width=100,
        height=60)
    sign_convention_SF = Div(
        text=
        "<img src='/System_of_Beams/static/images/sign_convention_SF_w.png' width=100 height=60>",
        width=100,
        height=60)
    sign_convention_M = Div(
        text=
        "<img src='/System_of_Beams/static/images/sign_convention_M.png' width=100 height=60>",
        width=100,
        height=60)
    sign_convention_phi = Div(
        text=
        "<img src='/System_of_Beams/static/images/sign_convention_phi.png' width=100 height=60>",
        width=100,
        height=60)
    sign_convention_w = Div(
        text=
        "<img src='/System_of_Beams/static/images/sign_convention_SF_w.png' width=100 height=60>",
        width=100,
        height=60)
    '''
    ###############################
    # HTML  LATEX DESCRIPTION
    ###############################
    '''
    # latex packages not working with updated bokeh!
    # description_filename = join(dirname(__file__), "description.html")
    # description = LatexDiv(text=open(description_filename).read(), render_as_text=False, width=910)
    '''
    ####################################
    # CREATE LAYOUT AND START DOCUMENT
    ####################################
    '''
    spacer = Div(text="", width=20, height=20)
    minispacer = Div(text="", width=0, height=0)

    # element buttons
    layout_supports_1 = row(button_support_clamped, button_support_normal,
                            button_support_transverse)
    layout_supports_2 = row(button_support_fixed_joint,
                            button_support_fixed_conti,
                            button_support_roller_joint,
                            button_support_roller_conti)
    layout_springs = row(button_spring_support, button_spring_moment_support)
    layout_node = row(button_node)
    layout_joints = row(button_joint, button_joint_normal,
                        button_joint_transverse, button_spring)
    layout_elements = row(button_beam)  # button_rod,
    layout_loads = row(button_load_point, button_load_moment,
                       button_load_random, button_load_temp)
    layout_input_elements = column(
        spacer, text_supports, layout_supports_1, layout_supports_2,
        row(column(text_springs, layout_springs), spacer, minispacer,
            column(text_node, layout_node)), text_joints, layout_joints,
        text_elements, layout_elements, text_loads, layout_loads)

    # element info box
    elinfo_name = row(text_elinfo_name, input_elinfo_name)
    curr_doc.children_element_info[key_elinfo_n] = elinfo_name
    elinfo_xy = row(text_elinfo_x, input_elinfo_x, spacer_y_a, text_elinfo_y,
                    input_elinfo_y)
    curr_doc.children_element_info[key_elinfo_x] = elinfo_xy
    elinfo_angle_length = row(text_elinfo_angle1, input_elinfo_angle,
                              text_elinfo_angle2, text_elinfo_length1,
                              input_elinfo_length, text_elinfo_length2)
    curr_doc.children_element_info[key_elinfo_angle] = elinfo_angle_length
    elinfo_k = row(text_elinfo_k1, input_elinfo_k, text_elinfo_k2)
    curr_doc.children_element_info[key_elinfo_k] = elinfo_k
    elinfo_force = row(text_elinfo_force1, input_elinfo_force,
                       text_elinfo_force2)
    curr_doc.children_element_info[key_elinfo_f] = elinfo_force
    elinfo_moment = row(text_elinfo_moment1, input_elinfo_moment,
                        text_elinfo_moment2)
    curr_doc.children_element_info[key_elinfo_m] = elinfo_moment
    elinfo_beam = row(
        minispacer, column(minispacer, text_elinfo_beam),
        column(check_elinfo_beam, row(input_elinfo_h, text_elinfo_h)),
        column(row(input_elinfo_ea, text_elinfo_ea),
               row(input_elinfo_ei, text_elinfo_ei)))
    curr_doc.children_element_info[key_elinfo_h] = elinfo_beam
    elinfo_lineload = row(
        minispacer, column(spacer, text_elinfo_lineload),
        column(spacer, radio_elinfo_ll),
        column(row(input_elinfo_xns, input_elinfo_xne),
               row(input_elinfo_yqs, input_elinfo_yqe)),
        column(spacer, text_elinfo_xn, text_elinfo_yq))
    curr_doc.children_element_info[key_elinfo_ei] = elinfo_lineload
    elinfo_dt = row(
        minispacer, column(minispacer, text_elinfo_temp),
        column(
            row(input_elinfo_dt, text_elinfo_dt, minispacer, input_elinfo_at,
                text_elinfo_at), row(input_elinfo_tt, text_elinfo_tt)))
    curr_doc.children_element_info[key_elinfo_dt] = elinfo_dt
    curr_doc.layout_element_info = row(
        minispacer,
        column(minispacer, elinfo_name, elinfo_xy, elinfo_angle_length, spacer,
               elinfo_k, elinfo_force, elinfo_moment, spacer, elinfo_beam,
               spacer, elinfo_lineload, spacer, elinfo_dt, spacer,
               button_elinfo_del, minispacer),
        minispacer,
        css_classes=["ELEMENT_INFO_BOX"],
        margin=(20, 0, 0, 20),
        visible=True)

    # input plot with element buttons, delete and calculation buttons and divs
    user_input = row(curr_doc.plot_input, spacer, layout_input_elements)
    user_input_info = row(curr_doc.div_input, div_xy, spacer,
                          button_del_selected, button_del_all)
    user_msg = row(curr_doc.div_msg, spacer, button_calc)

    # output plots and check boxes for characteristic values
    user_output = column(
        row(curr_doc.plot_normal_f, spacer,
            column(spacer, check_plot_nf, sign_convention_N)),
        row(curr_doc.plot_normal_disp, spacer,
            column(spacer, check_plot_nd, sign_convention_u)),
        row(curr_doc.plot_shear_f, spacer,
            column(spacer, check_plot_sf, sign_convention_SF)),
        row(curr_doc.plot_moment, spacer,
            column(spacer, check_plot_mo, sign_convention_M)),
        row(curr_doc.plot_shear_angle, spacer,
            column(spacer, check_plot_sa, sign_convention_phi)),
        row(curr_doc.plot_shear_disp, spacer,
            column(spacer, check_plot_sd, sign_convention_w)))

    # assemble complete layout
    doc_layout = column(
        spacer, row(spacer, spacer, dropdown_tc),
        row(column(user_input, user_input_info, user_msg), minispacer,
            curr_doc.layout_element_info), spacer, user_output)

    # add layout
    curr_doc.curr_doc.add_root(doc_layout)
    # set title of browser tab
    curr_doc.curr_doc.title = split(dirname(__file__))[-1].replace(
        '_', ' ').replace('-', ' ')
    doc_title = split(dirname(__file__))[-1].replace('_',
                                                     ' ').replace('-', ' ')