コード例 #1
0
ファイル: test_annotations.py プロジェクト: alamont/bokeh
def test_can_add_multiple_glyph_renderers_to_legend_item():
    legend_item = LegendItem()
    gr_1 = GlyphRenderer()
    gr_2 = GlyphRenderer()
    legend_item.renderers = [gr_1, gr_2]
    with mock.patch('bokeh.core.validation.check.logger') as mock_logger:
        check_integrity([legend_item])
        assert mock_logger.error.call_count == 0
コード例 #2
0
def test_legend_item_with_field_label_raises_error_if_field_not_in_cds():
    legend_item = LegendItem()
    gr_1 = GlyphRenderer(data_source=ColumnDataSource())
    legend_item.label = field('label')
    legend_item.renderers = [gr_1]
    with mock.patch('bokeh.core.validation.check.logger') as mock_logger:
        check_integrity([legend_item])
        assert mock_logger.error.call_count == 1
コード例 #3
0
ファイル: test_annotations.py プロジェクト: alamont/bokeh
def test_legend_item_with_field_label_raises_error_if_field_not_in_cds():
    legend_item = LegendItem()
    gr_1 = GlyphRenderer(data_source=ColumnDataSource())
    legend_item.label = field('label')
    legend_item.renderers = [gr_1]
    with mock.patch('bokeh.core.validation.check.logger') as mock_logger:
        check_integrity([legend_item])
        assert mock_logger.error.call_count == 1
コード例 #4
0
def test_can_add_multiple_glyph_renderers_to_legend_item():
    legend_item = LegendItem()
    gr_1 = GlyphRenderer()
    gr_2 = GlyphRenderer()
    legend_item.renderers = [gr_1, gr_2]
    with mock.patch('bokeh.core.validation.check.logger') as mock_logger:
        check_integrity([legend_item])
        assert mock_logger.error.call_count == 0
コード例 #5
0
def test_legend_item_with_value_label_and_different_data_sources_does_not_raise_a_validation_error():
    legend_item = LegendItem()
    gr_1 = GlyphRenderer(data_source=ColumnDataSource())
    gr_2 = GlyphRenderer(data_source=ColumnDataSource())
    legend_item.label = value('label')
    legend_item.renderers = [gr_1, gr_2]
    with mock.patch('bokeh.core.validation.check.logger') as mock_logger:
        check_integrity([legend_item])
        assert mock_logger.error.call_count == 0
コード例 #6
0
ファイル: test_annotations.py プロジェクト: alamont/bokeh
def test_legend_item_with_value_label_and_different_data_sources_does_not_raise_a_validation_error():
    legend_item = LegendItem()
    gr_1 = GlyphRenderer(data_source=ColumnDataSource())
    gr_2 = GlyphRenderer(data_source=ColumnDataSource())
    legend_item.label = value('label')
    legend_item.renderers = [gr_1, gr_2]
    with mock.patch('bokeh.core.validation.check.logger') as mock_logger:
        check_integrity([legend_item])
        assert mock_logger.error.call_count == 0
    def cleanLabels(self, nLabels=_MAX_NUMBER_OF_LINES):
        """
        The function cleans all unused labels from the legend. nLabels specifies how
        many plots shall remain in the graph.
        :param nLabels: int
        :return:
        """

        for i in range(nLabels, VibroP_GraphObject._MAX_NUMBER_OF_LINES):
            self.Graph.legend[0].items[i] = LegendItem(label="")
            self.Lines[i].glyph.line_color = 'white'
    def defineLine(self, ID, Name, Color, Style):
        """
        The function defines properties of a line. The user has to specify the line ID
        the class contains in order to change properties of a particular line. It is
        important to keep the order i.e. you have to start from the line with ID = 0,
        and iterate with the step 1.
        :param ID: int
        :param Name: string
        :param Color: string (according the bokeh documentation)
        :param Style: string (according the bokeh documentation)
        :return:
        """

        self.Lines[ID].glyph.line_color = Color
        self.Lines[ID].glyph.line_dash = Style
        self.Graph.legend[0].items[ID] = LegendItem(
            label=Name, renderers=[
                self.Lines[ID]
            ])  #self.Graph.legend[ 0 ].items[ ID ].label[ 'value' ] = Name
コード例 #9
0
def codon(enrichments=None,
          group_by='codon',
          groupings=None,
          colors=None,
          y_max=5,
          x_lims=(-25, 25),
          unselected_alpha=0.2,
          initial_menu_selection=None,
          initial_top_group_selections=None,
          initial_sub_group_selections=None,
          intial_resolution='codon',
         ):
    ''' An interactive plot of metacodon enrichment profiles using bokeh. Call
    without any arguments for an example using data from Jan et al. Science
    2014.

    Args:

        enrichments: A multi-level dictionary of enrichment values to plot, laid
            out like:
            
            enrichments = {
                'codon': {
                    'xs': [list of codon offset values],
                    'experiment_1': {
                        'TTT': [list of codon-resolution enrichments],
                        'TTC': ...,
                        ...,
                    },
                    'experiment_2': {...},
                },
                'nucleotide': {
                    'xs': [list of nucleotide offset values],
                    'experiment_1': {
                        'TTT': [list of nucleotide-resolution enrichments],
                        'TTC': ...,
                        ...,
                    },
                    'experiment_2': {...},
                },
            }

            See example_metacodon_enrichments.json in the same directory as this
            file for an example. (If enrichments == None, loads this file, which
            contains processed data from Jan et al. Science 2014, as an example.
            Other arguments are overwritten to highlight interesting features.)
        
        group_by: If 'codon', plot enrichments around one codon for all
            experiments. If 'experiment', plot enrichments around all codons for
            one experiment.

        groupings: If not None, a dictionary of groups of experiments/codons to
            list together for convenient selection.
            If None and group_by == 'experiment', experiment names will be
            grouped by name.split(':')[0].
            If None and group_by == 'codon', codons will be grouped by amino
            acid.
    '''
    if initial_top_group_selections is None:
        initial_top_group_selections = []
    if initial_sub_group_selections is None:
        initial_sub_group_selections = []
    
    if enrichments is None:
        # Load example data
        dirname = os.path.dirname(__file__)
        fn = os.path.join(dirname, 'example_metacodon_enrichments.json')
        with open(fn) as fh:
            enrichments = json.load(fh)

        # Prepare example groupings.
        exp_names = set(enrichments['codon'].keys())
        exp_names.remove('xs')
        group_names = ['-CHX', '+CHX_2min', '+CHX_7min']
        groupings = {}
        for group_name in group_names:
            groupings[group_name] = [n for n in exp_names if group_name in n]

        # Overrule other arguments to highlight interesting features in data.
        x_lims = (-18, 81)
        y_max = 3.2
        group_by = 'experiment'
        initial_menu_selection = 'CGA'
        initial_sub_group_selections = [
            'BirA_+CHX_2minBiotin_input',
            'BirAmVenusUbc6_+CHX_7minBiotin_input',
            'sec63mVenusBirA_-CHX_1minBiotin_input',
        ]

    # enrichments has experiments as top level keys and codons as lower level
    # keys. Building ColumnDataSource's below assumes a dictionary with
    # checkbox_names as the top keys, so if grouping by experiment, don't need
    # to do anything. If grouping by codon, need to invert the order of the
    # dictionary.

    # Copy enrichments since xs will be popped.
    enrichments = copy.deepcopy(enrichments)

    xs = {
        'codon': enrichments['codon'].pop('xs'),
        'nucleotide': enrichments['nucleotide'].pop('xs'),
    }
    
    exp_names = sorted(enrichments['codon'])

    if group_by == 'codon':
        if groupings is None:
            groupings = {aa: cs for aa, cs in genetic_code.full_back_table.items() if aa != '*'}

        menu_options = exp_names
        checkbox_names = genetic_code.non_stop_codons
        
        inverted = {}
        for resolution in enrichments:
            inverted[resolution] = {}
            for checkbox_name in checkbox_names:
                inverted[resolution][checkbox_name] = {}
                for menu_name in menu_options:
                    inverted[resolution][checkbox_name][menu_name] = enrichments[resolution][menu_name][checkbox_name]

        enrichments = inverted
    
    elif group_by == 'experiment':
        menu_options = genetic_code.non_stop_codons
        checkbox_names = sorted(enrichments['codon'])
        
        if groupings is None:
            groupings = defaultdict(list)
            for checkbox_name in sorted(checkbox_names):
                group_name = checkbox_name.split(':')[0]
                groupings[group_name].append(checkbox_name)

    if colors is None:
        colors = dict(zip(checkbox_names, cycle(colors_list)))

    if initial_menu_selection is None:
        initial_menu_selection = menu_options[0]
    if initial_menu_selection not in menu_options:
        raise ValueError('{0} not in {1}'.format(initial_menu_selection, menu_options))

    # Select all members of any initially selected top_group. 
    initial_sub_group_selections = set(initial_sub_group_selections)
    for top_name, sub_names in sorted(groupings.items()):
        if top_name in initial_top_group_selections:
            initial_sub_group_selections.update(sub_names)
    
    # Build ColumnDataSource's from enrichments.
    sources = {}
    for key in ['plotted', 'codon', 'nucleotide']:
        if key == 'plotted':
            resolution = intial_resolution
        else:
            resolution = key
        
        sources[key] = {}
        for checkbox_name in sorted(enrichments[resolution]):
            source = bokeh.models.ColumnDataSource(enrichments[resolution][checkbox_name])
            source.data['x'] = xs[resolution]
            source.data['y'] = source.data[initial_menu_selection]
            source.data['name'] = [checkbox_name] * len(xs[resolution])
            source.name = 'source_{0}_{1}'.format(checkbox_name, key)
            sources[key][checkbox_name] = source
   

    # Set up the actual plot.
    tools = [
        'pan',
        'tap',
        'box_zoom',
        'wheel_zoom',
        'save',
        'reset',
        'undo',
    ]

    fig = bokeh.plotting.figure(plot_width=1200,
                                plot_height=800,
                                tools=tools,
                                active_scroll='wheel_zoom',
                                name='figure',
                               )
    fig.toolbar.logo = None

    fig.grid.grid_line_alpha = 0.4

    fig.y_range = bokeh.models.Range1d(0, y_max)
    fig.y_range.name = 'y_range'
    fig.x_range = bokeh.models.Range1d(*x_lims)
    fig.x_range.name = 'x_range'

    range_callback = build_callback('metacodon_range')
    fig.y_range.callback = range_callback
    fig.x_range.callback = range_callback

    fig.xaxis.axis_label = 'Offset ({0}s)'.format(intial_resolution)
    fig.yaxis.axis_label = 'Mean relative enrichment'

    fig.xaxis.name = 'x_axis'
    fig.yaxis.name = 'y_axis'

    fig.xaxis.axis_label_text_font_style = 'normal'
    fig.yaxis.axis_label_text_font_style = 'normal'
    
    fig.xaxis[0].ticker = bokeh.models.tickers.SingleIntervalTicker(interval=3, num_minor_ticks=3)

    legend_items = []
    initial_legend_items = []
    lines = []
    for checkbox_name, source in sources['plotted'].items():
        if checkbox_name in initial_sub_group_selections:
            color = colors[checkbox_name]
            line_width = 2
            line_alpha = 0.95
            circle_visible = True
        else:
            color ='black'
            line_width = 1
            circle_visible = False
            if len(initial_sub_group_selections) > 0:
                line_alpha = unselected_alpha
            else:
                line_alpha = 0.6

        line = fig.line(x='x',
                        y='y',
                        color=color,
                        source=source,
                        line_width=line_width,
                        line_alpha=line_alpha,
                        line_join='round',
                        nonselection_line_color=colors[checkbox_name],
                        nonselection_line_alpha=unselected_alpha,
                        hover_alpha=1.0,
                        hover_color=colors[checkbox_name],
                       )
        line.hover_glyph.line_width = 3
        line.name = 'line_{0}'.format(checkbox_name)
        lines.append(line)
        
        circle = fig.circle(x='x',
                            y='y',
                            color=colors[checkbox_name],
                            source=source,
                            size=2.5,
                            fill_alpha=0.95,
                            line_alpha=0.95,
                            visible=circle_visible,
                            hover_alpha=0.95,
                            hover_color=colors[checkbox_name],
                           )
        circle.hover_glyph.visible = True
        circle.name = 'circle_{0}'.format(checkbox_name)
    
        legend_item = LegendItem(label=checkbox_name, renderers=[line])
        legend_items.append(legend_item)
        if checkbox_name in initial_sub_group_selections:
            initial_legend_items.append(legend_item)
        
    legend = ToggleLegend(name='legend',
                          items=initial_legend_items,
                          all_items=legend_items,
                         )
    fig.add_layout(legend)
    fig.legend.location = 'top_right'
    fig.legend.background_fill_alpha = 0.5

    source_callback = build_callback('metacodon_selection')
    for source in sources['plotted'].values():
        source.callback = source_callback

    hover = bokeh.models.HoverTool(line_policy='interp',
                                   renderers=lines,
                                  )
    hover.tooltips = [('name', '@name')]
    fig.add_tools(hover)

    # Draw horizontal and vertical lines.
    zero_x = bokeh.models.annotations.Span(location=0,
                                           dimension='height',
                                           line_color='black',
                                           line_alpha=0.8,
                                          )
    fig.renderers.append(zero_x)

    one_y = bokeh.models.annotations.Span(location=1,
                                          dimension='width',
                                          line_color='black',
                                          line_alpha=0.8,
                                         )
    fig.renderers.append(one_y)

    menu_title = 'Codon:' if group_by == 'experiment' else 'Experiment:'
    menu = bokeh.models.widgets.MultiSelect(options=menu_options,
                                            value=[initial_menu_selection],
                                            size=min(30, len(menu_options)),
                                            title=menu_title,
                                           )
    menu.callback = build_callback('metacodon_menu')

    sub_group_callback = build_callback('metacodon_sub_group',
                                        format_kwargs=dict(color_unselected='false'),
                                       )

    top_group_callback = build_callback('metacodon_top_group')

    top_groups = []
    sub_groups = []

    for top_name, sub_names in sorted(groupings.items()):
        width = int(75 + max(len(l) for l in sub_names) * 6.5)

        top_active = [0] if top_name in initial_top_group_selections else []
        top = bokeh.models.widgets.CheckboxGroup(labels=[top_name],
                                                 active=top_active,
                                                 width=width,
                                                 name='top_{0}'.format(top_name),
                                                 callback=top_group_callback,
                                                )
        top_groups.append(top)

        sub_active = [i for i, n in enumerate(sub_names) if n in initial_sub_group_selections]
        sub = bokeh.models.widgets.CheckboxGroup(labels=sub_names,
                                                 active=sub_active,
                                                 width=width,
                                                 callback=sub_group_callback,
                                                 name='sub_{0}'.format(top_name),
                                                )
        sub_groups.append(sub)

    highest_level_chooser = bokeh.models.widgets.RadioGroup(labels=['codon resolution', 'nucleotide resolution'],
                                                            active=0 if intial_resolution == 'codon' else 1,
                                                            name='highest_level_chooser',
                                                           )

    injection_sources = []
    for resolution in ['codon', 'nucleotide']:
        injection_sources.extend(sources[resolution].values())
    injection = {'ensure_no_collision_{0}'.format(i): v for i, v in enumerate(injection_sources)}

    highest_level_chooser.callback = build_callback('metacodon_resolution',
                                                    args=injection,
                                                   )

    clear_selection = bokeh.models.widgets.Button(label='Clear selection')
    clear_selection.callback = build_callback('metacodon_clear_selection')
    
    alpha_slider = bokeh.models.Slider(start=0.,
                                       end=1.,
                                       value=unselected_alpha,
                                       step=.05,
                                       title='unselected alpha',
                                      )
    alpha_slider.callback = build_callback('lengths_unselected_alpha')

    widgets = [
        menu,
        highest_level_chooser,
        alpha_slider,
        clear_selection,
    ]

    grid = [
        top_groups,
        sub_groups,
        [fig, bokeh.layouts.widgetbox(widgets)],
    ]

    bokeh.io.show(bokeh.layouts.layout(grid))
コード例 #10
0
ファイル: timeline.py プロジェクト: weichea/msticpy
def _display_timeline_dict(data: dict,
                           **kwargs) -> figure:  # noqa: C901, MC0001
    """
    Display a timeline of events.

    Parameters
    ----------
    data : dict
        Data points to plot on the timeline.
            Need to contain:
                Key - Name of data type to be displayed in legend
                Value - dict of data containing:
                    data : pd.DataFrame
                        Data to plot
                    time_column : str
                        Name of the timestamp column
                    source_columns : list
                        List of source columns to use in tooltips
                    color: str
                        Color of datapoints for this data
    Other Parameters
    ----------------
    ref_time : datetime, optional
        Input reference line to display (the default is None)
    title : str, optional
        Title to display (the default is None)
    time_column : str, optional
        Name of the timestamp column
        (the default is 'TimeGenerated')
    legend: str, optional
        Where to position the legend
        None, left, right or inline (default is None)
    yaxis : bool, optional
        Whether to show the yaxis and labels
    range_tool : bool, optional
        Show the the range slider tool (default is True)
    source_columns : list, optional
        List of default source columns to use in tooltips
        (the default is None)
    height : int, optional
        The height of the plot figure
        (the default is auto-calculated height)
    width : int, optional
        The width of the plot figure (the default is 900)

    Returns
    -------
    figure
        The bokeh plot figure.

    """
    reset_output()
    output_notebook()

    height: int = kwargs.pop("height", None)
    width: int = kwargs.pop("width", 900)
    ref_time: Any = kwargs.pop("ref_time", None)
    ref_label: str = kwargs.pop("ref_label", None)
    title: str = kwargs.pop("title", None)
    legend_pos: str = kwargs.pop("legend", None)
    show_yaxis: bool = kwargs.pop("yaxis", False)
    show_range: bool = kwargs.pop("range_tool", True)
    xgrid: bool = kwargs.pop("xgrid", True)
    ygrid: bool = kwargs.pop("ygrid", False)
    hide: bool = kwargs.pop("hide", False)

    tool_tip_columns, min_time, max_time = _unpack_data_series_dict(
        data, **kwargs)
    series_count = len(data)

    tooltips, formatters = _create_tool_tips(data, tool_tip_columns)
    hover = HoverTool(tooltips=tooltips, formatters=formatters)

    title = f"Timeline: {title}" if title else "Event Timeline"
    try:
        start_range = min_time - ((max_time - min_time) * 0.1)
        end_range = max_time + ((max_time - min_time) * 0.1)
    except OutOfBoundsDatetime:
        min_time = min_time.to_pydatetime()
        max_time = max_time.to_pydatetime()
        start_range = min_time - ((max_time - min_time) * 0.1)
        end_range = max_time + ((max_time - min_time) * 0.1)
    height = height if height else _calc_auto_plot_height(len(data))
    y_range = ((-1 / series_count), series_count - 1 + (1 / series_count))
    plot = figure(
        x_range=(start_range, end_range),
        y_range=y_range,
        min_border_left=50,
        plot_height=height,
        plot_width=width,
        x_axis_label="Event Time",
        x_axis_type="datetime",
        x_minor_ticks=10,
        tools=[hover, "xwheel_zoom", "box_zoom", "reset", "save", "xpan"],
        title=title,
    )
    plot.yaxis.visible = show_yaxis
    if show_yaxis:
        if data:
            y_labels = {
                ser_def["y_index"]: str(lbl)
                for lbl, ser_def in data.items()
            }
            plot.yaxis.major_label_overrides = y_labels
    if ygrid:
        plot.ygrid.minor_grid_line_color = "navy"
        plot.ygrid.minor_grid_line_alpha = 0.1
        plot.ygrid.grid_line_color = "navy"
        plot.ygrid.grid_line_alpha = 0.3
    else:
        plot.ygrid.grid_line_color = None
    if xgrid:
        plot.xgrid.minor_grid_line_color = "navy"
        plot.xgrid.minor_grid_line_alpha = 0.3
    else:
        plot.xgrid.grid_line_color = None

    # Create plot bar to act as as range selector
    rng_select = _create_range_tool(
        data=data,
        min_time=min_time,
        max_time=max_time,
        plot_range=plot.x_range,
        width=width,
        height=height,
    )

    # set the tick datetime formatter
    plot.xaxis[0].formatter = _get_tick_formatter()

    if series_count > 1 and not legend_pos:
        legend_pos = "left"

    # plot groups individually so that we can create an interactive legend
    # if legend_pos is "inline", we add add the normal legend inside the plot
    # if legend_pos is "left" or "right", we add the legend to the side
    legend_items = []
    for ser_name, series_def in data.items():
        if legend_pos == "inline":
            p_series = plot.diamond(
                x=series_def["time_column"],
                y="y_index",
                color=series_def["color"],
                alpha=0.5,
                size=10,
                source=series_def["source"],
                legend_label=str(ser_name),
            )
        else:
            p_series = plot.diamond(
                x=series_def["time_column"],
                y="y_index",
                color=series_def["color"],
                alpha=0.5,
                size=10,
                source=series_def["source"],
            )
        if legend_pos in ["left", "right"]:
            legend_items.append(
                LegendItem(
                    label=str(ser_name),
                    renderers=[p_series],
                ))

    if legend_pos == "inline":
        # Position the inline legend
        plot.legend.location = "center_left"
        plot.legend.click_policy = "hide"
    elif legend_pos in ["left", "right"]:
        # Create the legend box outside of the plot area
        ext_legend = Legend(
            items=
            legend_items[::-1],  # the legend is in the wrong order otherwise
            location="center",
            click_policy="hide",
            label_text_font_size="8pt",
        )
        plot.add_layout(ext_legend, legend_pos)

    if ref_time is not None:
        _add_ref_line(plot, ref_time, ref_label, len(data))

    if show_range:
        plot_layout = column(plot, rng_select)
    else:
        plot_layout = plot

    if not hide:
        show(plot_layout)

    return plot_layout
コード例 #11
0
def plotModesInBand(GraphInstance):
    """
    At the beginning the function cleans the GraphInstance from the previous plot. Then
    it adjusts the following lines with corresponding labels and colors on the plot:
        ModesInBand - bending
        ModesInBand - shear
        ModesInBand - compressional
    :param GraphInstance: an instance of GraphObject class
    :return:
    """

    GraphInstance.cleanGraph()
    GraphInstance.cleanLabels(3)
    GraphInstance.Graph.yaxis.axis_label = "Number of Modes per one-third octave band"
    GraphInstance.Graph.xaxis.axis_label = "Frequency in Hz"

    # ............................ bending_np graph ............................
    # 'Effective bending (thick plate)'
    GraphInstance.GraphData[ 0 ].data \
        = dict( XData = GraphInstance.Containers[ "ModesInBand" ][ "freq_T" ],
                YData = GraphInstance.Containers[ "ModesInBand" ][ "bending" ] )

    GraphInstance.defineLine(0, 'Effective bending (thick plate)', GREEN,
                             'solid')


    GraphInstance.Circles[ 0 ].data_source.data.\
        update({"x" : GraphInstance.GraphData[ 0 ].data[ "XData" ],
                "y" : GraphInstance.GraphData[ 0 ].data[ "YData" ]})

    GraphInstance.Graph.legend[ 0 ].items[ 0 ] \
        = LegendItem( label = 'Effective bending (thick plate)',
                      renderers = [ GraphInstance.Lines[ 0 ], GraphInstance.Circles[ 0 ] ] )

    GraphInstance.Circles[0].glyph.line_color = GREEN
    GraphInstance.Circles[0].glyph.fill_color = GREEN

    # ............................ compressional_np graph ......................
    # 'Shear, in-plane'
    GraphInstance.GraphData[ 1 ].data \
        = dict( XData = GraphInstance.Containers[ "ModesInBand" ][ "freq_T" ],
                YData = GraphInstance.Containers[ "ModesInBand" ][ "shear" ] )

    GraphInstance.defineLine(1, 'Shear, in-plane', LIGHT_BLUE, 'solid')

    GraphInstance.Circles[ 1 ].data_source.\
        data.update({"x" : GraphInstance.GraphData[ 1 ].data[ "XData" ],
                     "y" : GraphInstance.GraphData[ 1 ].data[ "YData" ]})



    GraphInstance.Graph.legend[ 0 ].items[ 1 ] \
        = LegendItem( label = 'Shear, in-plane',
                      renderers = [ GraphInstance.Lines[ 1 ], GraphInstance.Circles[ 1 ] ] )

    GraphInstance.Circles[1].glyph.line_color = LIGHT_BLUE
    GraphInstance.Circles[1].glyph.fill_color = LIGHT_BLUE

    # ............................ shear_np graph ..............................
    # 'Quasi-longitudial, in plane'


    GraphInstance.GraphData[ 2 ].data \
        = dict( XData = GraphInstance.Containers[ "ModesInBand" ][ "freq_T" ],
                YData = GraphInstance.Containers[ "ModesInBand" ][ "compressional" ] )

    GraphInstance.defineLine(2, 'Quasi-longitudinal, in plane', DARK_BLUE,
                             'solid')



    GraphInstance.Circles[ 2 ].data_source.data.\
        update({"x" : GraphInstance.GraphData[ 2 ].data[ "XData" ],
                "y" : GraphInstance.GraphData[ 2 ].data[ "YData" ]})



    GraphInstance.Graph.legend[ 0 ].items[ 2 ] \
        = LegendItem( label = 'Quasi-longitudial, in plane',
                      renderers = [ GraphInstance.Lines[ 2 ], GraphInstance.Circles[ 2 ] ] )

    GraphInstance.Circles[2].glyph.line_color = DARK_BLUE
    GraphInstance.Circles[2].glyph.fill_color = DARK_BLUE
コード例 #12
0
def gene(enrichments=None,
         groupings=None,
         y_max=5,
         unselected_alpha=0.2,
         initial_resolution='nucleotide',
         initial_top_group_selections=None,
         initial_sub_group_selections=None,
        ):
    ''' An interactive plot of metagene enrichment profiles using bokeh. Call
    without any arguments for an example using data from Jan et al. Science
    2014.

    Args:

        enrichments: A multi-level dictionary of enrichment values to plot, laid
            out like:
            
            enrichments = {
                'codon': {
                    'start_codon': {
                        'xs': [list of codon offset values relative to start codon],
                        'experiment_1': [list of enrichment values],
                        'experiment_2': [...],
                        ...,
                    },
                    'stop_codon': {...}
                },
                'nucleotide': {...}
            }

            See example_metagene_enrichments.json in the same directory as this
            file for an example. (If enrichments == None, loads this file, which
            contains processed data from Jan et al. Science 2014, as an 
            example.)
        
        groupings: If not None, a dictionary of groups of experiments to list
            together for convenient selection.
            If None, experiment names will be grouped by name.split(':')[0].
    '''
    if initial_top_group_selections is None:
        initial_top_group_selections = []
    if initial_sub_group_selections is None:
        initial_sub_group_selections = []

    if enrichments is None:
        # Load example data
        dirname = os.path.dirname(__file__)
        fn = os.path.join(dirname, 'example_metagene_enrichments.json')
        with open(fn) as fh:
            enrichments = json.load(fh)

        # Prepare example groupings.
        exp_names = set(enrichments['codon']['start_codon'].keys())
        exp_names.remove('xs')
        group_names = ['-CHX', '+CHX_2min', '+CHX_7min']
        groupings = {}
        for group_name in group_names:
            groupings[group_name] = [n for n in exp_names if group_name in n]

        # Overrule other arguments to highlight interesting features in data.
        initial_resolution = 'codon'
        y_max = 18
        initial_sub_group_selections = [
            'BirA_+CHX_2minBiotin_input',
            'BirAmVenusUbc6_+CHX_7minBiotin_input',
            'sec63mVenusBirA_-CHX_1minBiotin_input',
        ]
    
    initial_sub_group_selections = set(initial_sub_group_selections)
    for top_name, sub_names in sorted(groupings.items()):
        if top_name in initial_top_group_selections:
            initial_sub_group_selections.update(sub_names)

    enrichments = copy.deepcopy(enrichments)

    highest_level_keys = sorted(enrichments)

    all_xs = {}
    for key in highest_level_keys:
        all_xs[key] = {}
        for landmark in enrichments[key]:
            all_xs[key][landmark] = enrichments[key][landmark].pop('xs')

    exp_names = sorted(enrichments[highest_level_keys[0]]['start_codon'])
    sources = {}

    for key in ['plotted'] + highest_level_keys:
        if key == 'plotted':
            resolution = initial_resolution
        else:
            resolution = key
        
        sources[key] = {}
        for exp_name in exp_names:
            source = bokeh.models.ColumnDataSource()
            for landmark in ['start_codon', 'stop_codon']:
                xs = all_xs[resolution][landmark]
                ys = enrichments[resolution][landmark][exp_name]

                source.data['xs_{0}'.format(landmark)] = xs
                source.data['ys_{0}'.format(landmark)] = ys
                source.data['name'] = [exp_name] * len(xs)
            
            source.name = 'source_{0}_{1}'.format(exp_name, key)
            sources[key][exp_name] = source

    initial_before = 20
    initial_after = 150

    initial_lims = {
        'start_codon': (-initial_before, initial_after),
        'stop_codon': (-initial_after, initial_before),
    }

    x_ranges = {}
    x_range_callback = build_callback('metagene_x_range')
    for landmark in ('start_codon', 'stop_codon'):
        x_range = bokeh.models.Range1d(*initial_lims[landmark])
        x_range.name = 'x_range_{0}'.format(landmark)
        x_range.callback = x_range_callback
        x_ranges[landmark] = x_range

    y_range = bokeh.models.Range1d(0, y_max)
    y_range.name = 'y_range'
    y_range.callback = build_callback('metagene_y_range')

    tools = [
        'pan',
        'tap',
        'box_zoom',
        'wheel_zoom',
        'save',
        'reset',
        'undo',
    ]

    figs = {}
    for key, y_axis_location in [('start_codon', 'left'), ('stop_codon', 'right')]:
        figs[key] = bokeh.plotting.figure(plot_width=800,
                                          plot_height=600,
                                          x_range=x_ranges[key],
                                          y_range=y_range,
                                          y_axis_location=y_axis_location,
                                          tools=tools,
                                          active_scroll='wheel_zoom',
                                         )

    lines = {
        'start_codon': [],
        'stop_codon': [],
    }

    legend_items = []
    initial_legend_items = []

    colors = dict(zip(exp_names, cycle(colors_list)))
    for exp_name in exp_names:
        if exp_name in initial_sub_group_selections:
            color = colors[exp_name]
            line_width = 2
            line_alpha = 0.95
            circle_visible = True
        else:
            color = 'black'
            line_width = 1
            circle_visible = False
            if len(initial_sub_group_selections) > 0:
                line_alpha = unselected_alpha
            else:
                line_alpha = 0.6

        for landmark in ('start_codon', 'stop_codon'):
            line = figs[landmark].line(x='xs_{0}'.format(landmark),
                                       y='ys_{0}'.format(landmark),
                                       source=sources['plotted'][exp_name],
                                       color=color,
                                       nonselection_line_color=colors[exp_name],
                                       nonselection_line_alpha=unselected_alpha,
                                       hover_alpha=1.0,
                                       hover_color=colors[exp_name],
                                       line_width=line_width,
                                       line_alpha=line_alpha,
                                      )
            line.hover_glyph.line_width = 4
            line.name = 'line_{0}'.format(exp_name)
            lines[landmark].append(line)
            
            circle = figs[landmark].circle(x='xs_{0}'.format(landmark),
                                           y='ys_{0}'.format(landmark),
                                           source=sources['plotted'][exp_name],
                                           size=2,
                                           color=colors[exp_name],
                                           fill_alpha=0.9,
                                           line_alpha=0.9,
                                           visible=circle_visible,
                                           hover_alpha=1.0,
                                           hover_color=colors[exp_name],
                                          )
            circle.hover_glyph.visible = True
            circle.name = 'circle_{0}'.format(exp_name)

            if landmark == 'stop_codon':
                legend_item = LegendItem(label=exp_name, renderers=[line])
                legend_items.append(legend_item)
                if exp_name in initial_sub_group_selections:
                    initial_legend_items.append(legend_item)

    legend = ToggleLegend(name='legend',
                          items=initial_legend_items,
                          all_items=legend_items,
                         )
    figs['stop_codon'].add_layout(legend)
    figs['stop_codon'].legend.location = 'top_left'
    figs['stop_codon'].legend.background_fill_alpha = 0.5
    
    for landmark, fig in figs.items():
        zero_x = bokeh.models.annotations.Span(location=0,
                                               dimension='height',
                                               line_color='black',
                                               line_alpha=0.5,
                                              )
        fig.renderers.append(zero_x)

        one_y = bokeh.models.annotations.Span(location=1,
                                               dimension='width',
                                               line_color='black',
                                               line_alpha=0.5,
                                              )
        fig.renderers.append(one_y)
        
        
        remove_underscore = ' '.join(landmark.split('_'))
        fig.xaxis.axis_label = 'Offset from {0}'.format(remove_underscore)
        fig.xaxis.axis_label_text_font_style = 'normal'
        
        fig.grid.grid_line_alpha = 0.4

    figs['start_codon'].yaxis.axis_label = 'Mean relative enrichment'
    figs['start_codon'].yaxis.axis_label_text_font_style = 'normal'
    
    source_callback = build_callback('metacodon_selection')
    for source in sources['plotted'].values():
        source.callback = source_callback

    for landmark in ['start_codon', 'stop_codon']:
        hover = bokeh.models.HoverTool(line_policy='interp',
                                       renderers=lines[landmark],
                                      )
        hover.tooltips = [('name', '@name')]
        figs[landmark].add_tools(hover)

    resolution = bokeh.models.widgets.RadioGroup(labels=['codon resolution', 'nucleotide resolution'],
                                                 active=0 if initial_resolution == 'codon' else 1,
                                                )
    resolution.name = 'resolution'
    
    injection_sources = []
    for key in highest_level_keys:
        injection_sources.extend(sources[key].values())
    injection = {'ensure_no_collision_{0}'.format(i): v for i, v in enumerate(injection_sources)}

    resolution.callback = build_callback('metacodon_resolution',
                                         args=injection,
                                        )
    
    sub_group_callback = build_callback('metacodon_sub_group',
                                        format_kwargs=dict(color_unselected='false'),
                                       )

    top_group_callback = build_callback('metacodon_top_group')

    top_groups = []
    sub_groups = []
    for top_name, sub_names in sorted(groupings.items()):
        width = int(75 + max(len(l) for l in sub_names) * 6.5)
        
        top_active = [0] if top_name in initial_top_group_selections else []
        top = bokeh.models.widgets.CheckboxGroup(labels=[top_name],
                                                 active=top_active,
                                                 width=width,
                                                 name='top_{0}'.format(top_name),
                                                 callback=top_group_callback,
                                                )
        top_groups.append(top)

        sub_active = [i for i, n in enumerate(sub_names) if n in initial_sub_group_selections]
        sub = bokeh.models.widgets.CheckboxGroup(labels=sorted(sub_names),
                                                 active=sub_active,
                                                 width=width,
                                                 callback=sub_group_callback,
                                                 name='sub_{0}'.format(top_name),
                                                )
        sub_groups.append(sub)
    
    alpha_slider = bokeh.models.Slider(start=0.,
                                       end=1.,
                                       value=unselected_alpha,
                                       step=.05,
                                       title='unselected alpha',
                                      )
    alpha_slider.callback = build_callback('lengths_unselected_alpha')

    plots = bokeh.layouts.gridplot([[figs['start_codon'], figs['stop_codon']]])
    plots.children[0].logo = None

    grid = [
        top_groups,
        sub_groups,
        [plots, bokeh.layouts.widgetbox([resolution, alpha_slider])],
    ]
    bokeh.io.show(bokeh.layouts.layout(grid))
コード例 #13
0
 def create_plot_figure(self, active_tab):
     """
     create a new plot and insert it in given tab.
     """
     #find table name of active tab and its bokeh instances
     test = active_tab.name#contains csv filename
     x_sel=active_tab.select_one({'name':'x_sel'}) 
     y_sel=active_tab.select_one({'name':'y_sel'}) 
     y_sel2=active_tab.select_one({'name':'y_sel2'}) 
     plot_df = self.plot_dfs[test]
     source = ColumnDataSource(plot_df) 
      
     #Replace entirely p with a new plot 
     p = Plot( 
              x_range=DataRange1d(),  
              y_range=DataRange1d(),  
              plot_height=600, 
              plot_width=600, 
              title=Title(text=self.sel_csv), 
              name='plot')
     p.add_tools(BoxZoomTool(),
                 SaveTool(),
                 ResetTool(),
                 PanTool(),
                 HoverTool(tooltips=[('x','$x'),
                                     ('y','$y')]))
      
     #see https://bokeh.github.io/blog/2017/7/5/idiomatic_bokeh/ 
     x_axis = LinearAxis( 
             axis_label = x_sel.value, 
             ticker=BasicTicker(desired_num_ticks =10), 
             name='x_axis') 
     y_axis = LinearAxis( 
             axis_label = y_sel.value, 
             ticker=BasicTicker(desired_num_ticks =10), 
             name='y_axis') 
     
     #primary y-axis 
     ly = p.add_glyph(source, 
                Line(x=x_sel.value,  
                y=y_sel.value,  
                line_width=2,
                line_color='black'),
                name = 'ly'
                ) 
     
     p.add_layout(x_axis,'below') 
      
     p.add_layout(y_axis,'left') 
     p.y_range.renderers = [ly]
     #secondary y-axis          
     if y_sel2.value.strip() != 'None':#secondary y-axis             
         y_axis2 = LinearAxis( 
                 axis_label = y_sel2.value, 
                 ticker=BasicTicker(desired_num_ticks=10), 
                 name='y_axis2', 
                 y_range_name='right_axis') 
         p.add_layout(y_axis2,'right') 
         p.extra_y_ranges = {"right_axis": DataRange1d()} 
         ly2 = p.add_glyph(source, 
                            Line(x=x_sel.value, 
                                y=y_sel2.value, 
                                line_width=2, 
                                line_color='red'), 
                            y_range_name='right_axis', 
                            name = 'ly2'
                           ) 
         p.extra_y_ranges['right_axis'].renderers = [ly2] 
         leg_items = [LegendItem(label=y_sel.value, 
                                      renderers=[ly]),
                      LegendItem(label=y_sel2.value,
                                 renderers=[ly2])]
     else: 
         leg_items = [LegendItem(label=y_sel.value, 
                                              renderers=[ly])] 
     
     p.add_layout(Legend(items=leg_items, 
                             location='top_right') 
                  )
     active_tab.child.children[1] = p
     return p
コード例 #14
0
def plot(exps,
         initial_sub_group_selections=None,
         unselected_alpha=0.2,
        ):
    if initial_sub_group_selections is None:
        initial_sub_group_selections = []
    groupings = {group_name: sorted(exps['raw'][group_name]) for group_name in exps['raw']}

    sources = {}
    colors = {}
    color_iter = cycle(colors_list)

    highest_level_keys = [k for k in sorted(exps) if k != 'descriptions']

    for key in ['plotted'] + highest_level_keys:
        if key == 'plotted':
            normalization = 'raw'
        else:
            normalization = key
        
        sources[key] = {}
        for group_name in sorted(exps[normalization]):
            for sample_name in sorted(exps[normalization][group_name]):
                if sample_name not in colors:
                    colors[sample_name] = color_iter.next()
                series = exps[normalization][group_name][sample_name]
                source = bokeh.models.ColumnDataSource()
                source.data['x'] = list(series.index)
                source.data['y'] = list(series)
                source.data['name'] = [sample_name] * len(series)
                source.name = 'source_{0}_{1}'.format(sample_name, key)
                sources[key][sample_name] = source
    
    sample_names = []
    descriptions = []
    for group_name, group in sorted(exps['descriptions'].items()):
        for sample_name, description in sorted(group.items()):
            sample_names.append(sample_name)
            descriptions.append(description)

    full_source = bokeh.models.ColumnDataSource(name='full_source')
    full_source.data = {
        'sample_name': sample_names,
        'description': descriptions,
    }

    tools = [
        'pan',
        'tap',
        'box_zoom',
        'wheel_zoom',
        'save',
        'reset',
        'undo',
    ]

    x_range = bokeh.models.Range1d(17, 70, bounds=(17, 70))
    fig = bokeh.plotting.figure(plot_width=1200,
                                plot_height=600,
                                tools=tools, active_scroll='wheel_zoom',
                                x_range=x_range,
                               )

    random_group = exps['raw'].keys()[0]
    series = exps['raw'][random_group]['{0}:12_Ladder'.format(random_group)]
    peak_times = extract_ladder_peak_times(series)
    
    for time, nt in peak_times.items():
        line = bokeh.models.annotations.Span(location=time,
                                             dimension='height',
                                             line_color='black',
                                             line_alpha=0.8,
                                             line_dash='dashed',
                                            )
        fig.renderers.append(line)

    fig.xgrid.grid_line_color = None
    fig.ygrid.grid_line_color = None

    convert_tick = '''
    peak_times = {dict};
    return peak_times[tick];
    '''.format(dict=peak_times)
    fig.xaxis.formatter = bokeh.models.FuncTickFormatter(code=convert_tick)
    fig.xaxis.ticker = bokeh.models.FixedTicker(ticks=list(peak_times))

    all_legend_items = []
    initial_legend_items = []
    lines = []
    for sample_name, source in sources['plotted'].items():
        if sample_name in initial_sub_group_selections:
            color = colors[sample_name]
            line_width = 2
            line_alpha = 0.95
        else:
            color = 'black'
            line_width = 1
            if len(initial_sub_group_selections) > 0:
                line_alpha = unselected_alpha
            else:
                line_alpha = 0.6

        line = fig.line(x='x',
                        y='y',
                        color=color,
                        source=source,
                        line_width=line_width,
                        line_alpha=line_alpha,
                        line_join='round',
                        nonselection_line_color=colors[sample_name],
                        nonselection_line_alpha=unselected_alpha,
                        hover_alpha=1.0,
                        hover_color=colors[sample_name],
                       )

        line.hover_glyph.line_width = 4
        line.name = 'line_{0}'.format(sample_name)
        lines.append(line)

        legend_item = LegendItem(label=sample_name, renderers=[line])
        all_legend_items.append(legend_item)
        if sample_name in initial_sub_group_selections:
            initial_legend_items.append(legend_item)
        
    legend = ToggleLegend(name='legend',
                          items=initial_legend_items,
                          all_items=all_legend_items,
                         )
    fig.add_layout(legend)
    
    source_callback = external_coffeescript('bioanalyzer_selection',
                                            args=dict(full_source=full_source),
                                           )
    for source in sources['plotted'].values():
        source.callback = source_callback

    hover = bokeh.models.HoverTool(line_policy='interp',
                                   renderers=lines,
                                  )
    hover.tooltips = [('name', '@name')]
    fig.add_tools(hover)

    sub_group_callback = external_coffeescript('bioanalyzer_sub_group',
                                               args=dict(full_source=full_source),
                                              )

    top_group_callback = external_coffeescript('bioanalyzer_top_group',
                                               args=dict(full_source=full_source),
                                              )

    top_groups = []
    sub_groups = []
    for top_name, sub_names in sorted(groupings.items()):
        width = 75 + max(len(l) for l in sub_names) * 6
        top = bokeh.models.widgets.CheckboxGroup(labels=[top_name],
                                                 active=[],
                                                 width=width,
                                                 name='top_{0}'.format(top_name),
                                                 callback=top_group_callback,
                                                )
        top_groups.append(top)

        sub_active = [i for i, n in enumerate(sub_names) if n in initial_sub_group_selections]
        sub = bokeh.models.widgets.CheckboxGroup(labels=sub_names,
                                                 active=sub_active,
                                                 width=width,
                                                 callback=sub_group_callback,
                                                 name='sub_{0}'.format(top_name),
                                                )
        sub_groups.append(sub)

    
    clear_selection = bokeh.models.widgets.Button(label='Clear selection')
    clear_selection.callback = external_coffeescript('bioanalyzer_clear_selection',
                                                     args=dict(full_source=full_source),
                                                    )
    
    highest_level_chooser = bokeh.models.widgets.Select(options=highest_level_keys,
                                                        value=highest_level_keys[2],
                                                       )
    callback_name = 'metacodon_highest_level'
    
    injection_sources = []
    for key in highest_level_keys:
        injection_sources.extend(sources[key].values())
    injection = {'ensure_no_collision_{0}'.format(i): v for i, v in enumerate(injection_sources)}

    highest_level_chooser.callback = external_coffeescript(callback_name,
                                                           args=injection,
                                                          )
    table_col_names = [
        ('sample_name', 250),
        ('description', 850),
    ]

    columns = []
    for col_name, width in table_col_names:
        column = bokeh.models.widgets.TableColumn(field=col_name,
                                                  title=col_name,
                                                  formatter=None,
                                                  width=width,
                                                 )
        columns.append(column)

    filtered_data = {k: [] for k, _ in table_col_names}
    filtered_source = bokeh.models.ColumnDataSource(data=filtered_data, name='table_source')

    table = bokeh.models.widgets.DataTable(source=filtered_source,
                                           columns=columns,
                                           width=1200,
                                           height=400,
                                           sortable=False,
                                           name='table',
                                           row_headers=False,
                                          )
    grid = bokeh.layouts.layout([
        sub_groups + [bokeh.layouts.widgetbox([highest_level_chooser, clear_selection])],
        [fig],
        [table],
    ])

    bokeh.io.show(grid)
コード例 #15
0
ファイル: theto.py プロジェクト: vericast/theto
    def add_path(self,
                 source_label,
                 links=None,
                 edge_type='curved',
                 tooltips=None,
                 legend=None,
                 **kwargs):
        """
        Connect all points in the datasource in a path (to show order).
        `self.prepare_plot` must have been called previous to this.
        
        Parameters:
        
        source_label (str): string corresponding to a label previously 
            called in `self.add_source`
        order_col: the column of a data source specifying the order of the records
        tooltips: string or list of tuples (passed to Bokeh HoverTool)
        legend (str): name to assign to this layer in the plot legend
        kwargs: options passed to the objected for `bokeh_model`
        
        This method allows two special kwargs: 'color' and 'alpha'. When 
            used with a bokeh model that has 'fill_color' and 'line_color' 
            and 'fill_alpha' and 'line_alpha' properties, calling the special 
            kwarg will use the same value for both.
        
        """

        self._validate_workflow('add_path')

        source = self.sources[source_label].copy()

        suffix = '_transform' if type(self.plot) != GMapPlot else ''
        x_point_label = 'x_coord_point{}'.format(suffix)
        y_point_label = 'y_coord_point{}'.format(suffix)

        if all(isinstance(x, (int, float)) for x in source[links].tolist()):
            x1 = source.sort_values(links)[x_point_label].values
            y1 = source.sort_values(links)[y_point_label].values
            x2 = x1[1:]
            y2 = y1[1:]
            x1 = x1[:-1]
            y1 = y1[:-1]
            x3 = (x1 + x2) / 2
            y3 = (y1 + y2) / 2
            xc = x3 + abs(y3 - y2)
            yc = y3 + abs(x3 - x2)

            new_source = {
                'x1': x1,
                'x2': x2,
                'xc': xc,
                'y1': y1,
                'y2': y2,
                'yc': yc
            }

            for c in source.columns:
                if (c not in self.omit_columns) and c not in new_source:
                    new_source[c] = source[c].values[:-1]
        elif all(
                isinstance(x, (list, tuple, set))
                for x in source[links].tolist()):
            if 'uid' not in source.columns:
                raise ValueError(
                    'Source must contain column `uid` when links is a list of iterables.'
                )

            nodes = source['uid'].tolist()
            edges = source[links].tolist()
            node_x = source.set_index('uid')[x_point_label].to_dict()
            node_y = source.set_index('uid')[y_point_label].to_dict()

            a_vals, x1, x2, y1, y2 = zip(*[(a, node_x[a], node_x[b], node_y[a],
                                            node_y[b])
                                           for a, bs in zip(nodes, edges)
                                           for b in bs])
            x1, x2, y1, y2 = array(x1), array(x2), array(y1), array(y2)
            x3 = (x1 + x2) / 2
            y3 = (y1 + y2) / 2
            xc = x3 + abs(y3 - y2)
            yc = y3 + abs(x3 - x2)

            new_source = {
                'x1': x1,
                'x2': x2,
                'xc': xc,
                'y1': y1,
                'y2': y2,
                'yc': yc
            }

            for c in source.columns:
                if (c not in self.omit_columns) and c not in new_source:
                    col_dict = source.set_index('uid', drop=False)[c].to_dict()
                    new_source[c] = [col_dict[v] for v in a_vals]
        else:
            raise ValueError(
                'Values of `links` field must be numeric or a list, set, or tuple of values from the `uid` field.'
            )

        if 'color' in kwargs.keys():
            color = kwargs.pop('color')
            for v in Quadratic.dataspecs():
                if 'color' in v:
                    kwargs[v] = color

        if 'alpha' in kwargs.keys():
            alpha = kwargs.pop('alpha')
            for v in Quadratic.dataspecs():
                if 'alpha' in v:
                    kwargs[v] = alpha

        if edge_type == 'curved':
            model_object = Quadratic(x0='x1',
                                     y0='y1',
                                     x1="x2",
                                     y1="y2",
                                     cx="xc",
                                     cy="yc",
                                     name=source_label,
                                     **kwargs)
        elif edge_type == 'straight':
            model_object = Segment(x0='x1',
                                   y0='y1',
                                   x1="x2",
                                   y1="y2",
                                   name=source_label,
                                   **kwargs)
        else:
            raise ValueError(
                'Keyword `edge_type` must be either "curved" or "straight".')

        source = ColumnDataSource(new_source, name=source_label)
        rend = self.plot.add_glyph(source, model_object)

        if legend is not None:
            li = LegendItem(label=legend, renderers=[rend])
            self.legend.items.append(li)

        if tooltips is not None:
            self.plot.add_tools(HoverTool(tooltips=tooltips, renderers=[rend]))

        return self
コード例 #16
0
ファイル: theto.py プロジェクト: vericast/theto
    def add_layer(self,
                  source_label,
                  bokeh_model='MultiPolygons',
                  tooltips=None,
                  legend=None,
                  click_for_map=None,
                  start_hex='#ff0000',
                  end_hex='#0000ff',
                  mid_hex='#ffffff',
                  color_transform=None,
                  **kwargs):
        """
        Add bokeh models (glyphs or markers) to `self.plot`. 
        `self.prepare_plot` must have been called previous to this.
        
        Parameters:
        
        source_label (str): string corresponding to a label previously 
            called in `self.add_source`
        bokeh_model: any Bokeh model or glyph class
        tooltips: string or list of tuples (passed to Bokeh HoverTool)
        legend (str): name to assign to this layer in the plot legend
        start_hex (str): the color with which to start a color gradient
        end_hex (str): the color with which to end a color gradient
        mid_hex (str): the color to use for zero in a color gradient if 
            the basis of that gradient contains both positive and negative 
            values
        color_transform (callable): any function that can transform a 
            numpy array (log, log10, etc.)
        kwargs: options passed to the objected for `bokeh_model`
        
        This method allows two special kwargs: 'color' and 'alpha'. When 
        used with a bokeh model that has 'fill_color' and 'line_color' and 
        'fill_alpha' and 'line_alpha' properties, calling the special kwarg 
        will use the same value for both.
        
        """

        self._validate_workflow('add_layer')

        if self.plot is None:
            raise AssertionError(
                'self.plot is null; call `self.prepare_plot`.')

        if bokeh_model not in bokeh_utils.MODELS:
            raise ValueError('Valid values for `bokeh_model` are: {}'.format(
                ', '.join([repr(x) for x in bokeh_utils.MODELS.keys()])))

        bokeh_model = bokeh_utils.MODELS[bokeh_model]
        kwargs, hover_kwargs, new_fields, colorbar = bokeh_utils.prepare_properties(
            bokeh_model,
            kwargs,
            self.sources[source_label],
            bar_height=self.plot.frame_height,
            start_hex=start_hex,
            end_hex=end_hex,
            mid_hex=mid_hex,
            color_transform=color_transform,
        )

        if self.colorbar is None:
            self.colorbar = colorbar

        source = self.columndatasources[source_label]

        for k, v in new_fields.items():
            self.columndatasources[source_label].data[k] = v

        hover_object = None
        if bokeh_model == bokeh_utils.MODELS['MultiPolygons']:
            if type(self.plot) == GMapPlot:
                raise ValueError(
                    'The `MultiPolygon` glyph cannot yet be used with a Google Maps plot.'
                )
            model_object = bokeh_model(xs='xsf',
                                       ys='ysf',
                                       name=source_label,
                                       **kwargs)

            if len(hover_kwargs) > 0:
                for k, v in hover_kwargs.items():
                    kwargs[k] = v
                hover_object = bokeh_model(xs='xsf',
                                           ys='ysf',
                                           name=source_label,
                                           **kwargs)

            if 'f' in self.remove_columns[source_label]:
                _ = self.remove_columns[source_label].pop(
                    self.remove_columns[source_label].index('f'))

        else:

            model_object = bokeh_model(x='xsp',
                                       y='ysp',
                                       name=source_label,
                                       **kwargs)

            if len(hover_kwargs) > 0:
                for k, v in hover_kwargs:
                    kwargs[k] = v
                hover_object = bokeh_model(xs='xsf',
                                           ys='ysf',
                                           name=source_label,
                                           **kwargs)

            if 'p' in self.remove_columns[source_label]:
                _ = self.remove_columns[source_label].pop(
                    self.remove_columns[source_label].index('p'))

        if source_label in self.views:
            if len(hover_kwargs) > 0:
                rend = self.plot.add_glyph(source,
                                           model_object,
                                           hover_glyph=hover_object,
                                           view=self.views[source_label])
            else:
                rend = self.plot.add_glyph(source,
                                           model_object,
                                           view=self.views[source_label])
        else:
            if len(hover_kwargs) > 0:
                rend = self.plot.add_glyph(source,
                                           model_object,
                                           hover_glyph=hover_object)
            else:
                rend = self.plot.add_glyph(source, model_object)

        if legend is not None:
            li = LegendItem(label=legend, renderers=[rend])
            self.legend.items.append(li)

        if tooltips is not None:
            if tooltips == 'all':
                tooltips = [(k, '@{}'.format(k)) for k in source.data.keys()
                            if k not in ('xsf', 'ysf', 'xsp', 'ysp')]
            elif tooltips == 'point':
                tooltips = [(k, '@{}'.format(k)) for k in source.data.keys()
                            if k not in ('xsf', 'ysf', 'xsp', 'ysp',
                                         'raw_data')]
            elif tooltips == 'raw_data':
                tooltips = [(k, '@{}'.format(k)) for k in source.data.keys()
                            if k not in ('xsf', 'ysf', 'xsp', 'ysp',
                                         'x_coord_point', 'y_coord_point')]
            elif tooltips == 'meta':
                tooltips = [
                    (k, '@{}'.format(k)) for k in source.data.keys()
                    if k not in ('xsf', 'ysf', 'xsp', 'ysp', 'x_coord_point',
                                 'y_coord_point', 'raw_data')
                ]

        self.plot.add_tools(HoverTool(tooltips=tooltips, renderers=[rend]))

        if click_for_map is not None:
            taptool = self.plot.select(type=TapTool)
            if click_for_map == 'google':
                url = 'https://maps.google.com/maps?q=@y_coord_point,@x_coord_point'
                taptool.callback = OpenURL(url=url)
            elif click_for_map == 'bing':
                url = 'https://bing.com/maps/default.aspx?sp=point.'
                url += '@{y_coord_point}_@{x_coord_point}_Selected point&style=r'
                taptool.callback = OpenURL(url=url)
            else:
                raise NotImplementedError(
                    'Value for `click_for_map` must be "bing", "google" or None.'
                )

        self.validation['add_layer'] = True

        return self
コード例 #17
0
ファイル: main.py プロジェクト: rshashidhara/digitalgemba
cmplot = figure(plot_width=500,
                plot_height=400,
                y_range=(0, 13),
                name="cmplot")
cmplot.vbar_stack(stackers=['mc', 'fp', 'nd'],
                  x='yr',
                  source=cmdata,
                  color=("green", "yellow", "red"),
                  width=0.5,
                  line_color="black")

cmplot.toolbar_location = None
cmplot.xaxis.axis_label = "Year"
cmplot.yaxis.axis_label = "Number of Meetings"

li1 = LegendItem(label=' Done', renderers=[cmplot.renderers[0]])
li2 = LegendItem(label=' Planed', renderers=[cmplot.renderers[1]])
li3 = LegendItem(label='Not Done', renderers=[cmplot.renderers[2]])
legend1 = Legend(items=[li1, li2, li3], location='bottom_center')
cmplot.add_layout(legend1)

new_legend = cmplot.legend[0]
cmplot.add_layout(new_legend, 'below')
cmplot.legend.orientation = "horizontal"

#show(cmplot)
#curdoc().add_root(cmplot)

####  teacher qualification  ####

sheet_teach = client.open("teacher_qualification").sheet1
コード例 #18
0
def lengths(raw_counts,
            group_by='experiment',
            groupings=None,
            initial_top_group_selections=None,
            initial_sub_group_selections=None,
            types=None,
            max_length=1000,
            x_max=500,
           ):
    ys = {
        'raw_counts': raw_counts,
        'by_type': {},
        'by_exp': {},
    }

    if types is None:
        types = raw_counts.values()[0].keys()

    for exp_name in ys['raw_counts']:
        total_counts = sum(ys['raw_counts'][exp_name]['insert_lengths'])

        ys['by_type'][exp_name] = {}
        ys['by_exp'][exp_name] = {}

        for type_name in raw_counts[exp_name]:
            raw = raw_counts[exp_name][type_name]
            ys['by_type'][exp_name][type_name] = np.true_divide(raw, sum(raw))
            ys['by_exp'][exp_name][type_name] = np.true_divide(raw, total_counts)

    first_exp_name = ys['raw_counts'].keys()[0]

    # ys has experiments as top level keys and types as lower level keys.
    # Need a dictionary with checkbox names as the top keys, so if grouping by
    # type, don't need to do anything. If grouping by experiment, need to invert
    # the order.
    # 2017_03_06: this comment doesnt seem to make sense.

    if group_by == 'experiment':
        menu_options = sorted(ys['raw_counts'])
        checkbox_names = sorted(ys['raw_counts'][first_exp_name])
        
        rekeyed_ys = {}
        for normalization in ys:
            rekeyed_ys[normalization] = {}
            for checkbox_name in checkbox_names:
                rekeyed_ys[normalization][checkbox_name] = {}
                for menu_name in menu_options:
                    rekeyed_ys[normalization][checkbox_name][menu_name] = ys[normalization][menu_name][checkbox_name]

        ys = rekeyed_ys

    elif group_by == 'type':
        menu_options = types
        checkbox_names = sorted(ys['raw_counts'])

    if initial_sub_group_selections is None:
        initial_sub_group_selections = checkbox_names

    if initial_top_group_selections is None:
        initial_top_group_selections = []

    if groupings is None:
        groupings = {n: [n] for n in checkbox_names}

    colors = dict(zip(checkbox_names, cycle(colors_list)))

    initial_menu_selection = None
    if initial_menu_selection is None:
        initial_menu_selection = menu_options[0]

    if initial_menu_selection not in menu_options:
        raise ValueError('{0} not in {1}'.format(initial_menu_selection, menu_options))

    sources = {}
    for key in ['plotted'] + ys.keys():
        if key == 'plotted':
            normalization = 'raw_counts'
        else:
            normalization = key

        sources[key] = {}
        for checkbox_name in checkbox_names:
            data = {}
            for menu_name in ys[normalization][checkbox_name]:
                full_list = list(ys[normalization][checkbox_name][menu_name])
                if len(full_list) > max_length:
                    full_list[max_length] = sum(full_list[max_length:])
                elif len(full_list < max_length):
                    full_list.extend([0]*(max_length + 1 - len(full_list)))

                data[menu_name] = full_list[:max_length + 1]
            source = bokeh.models.ColumnDataSource(data)

            xs = range(max_length + 1)
            source.data['x'] = xs

            source.data['y'] = source.data[initial_menu_selection]

            source.data['name'] = [checkbox_name] * len(xs)
            source.name = 'source_{0}_{1}'.format(checkbox_name, key)
            sources[key][checkbox_name] = source

    tools = [
        'pan',
        'tap',
        'box_zoom',
        'wheel_zoom',
        'save',
        'reset',
        'undo',
    ]

    fig = bokeh.plotting.figure(plot_width=1200,
                                plot_height=800,
                                tools=tools,
                                active_scroll='wheel_zoom',
                                name='figure',
                               )

    fig.grid.grid_line_alpha = 0.4

    fig.y_range.name = 'y_range'
    fig.x_range.name = 'x_range'
    fig.x_range.end = x_max

    range_callback = build_callback('lengths_range')
    fig.y_range.callback = range_callback
    fig.x_range.callback = range_callback

    fig.xaxis.axis_label = 'Length'
    fig.yaxis.axis_label = 'y'

    fig.xaxis.name = 'x_axis'
    fig.yaxis.name = 'y_axis'

    fig.xaxis.axis_label_text_font_style = 'normal'
    fig.yaxis.axis_label_text_font_style = 'normal'

    legend_items = []
    initial_legend_items = []
    lines = []
    for checkbox_name, source in sources['plotted'].items():
        if checkbox_name in initial_sub_group_selections:
            color = colors[checkbox_name]
            line_width = 2
            line_alpha = 0.95
            circle_visible = True
        else:
            color = colors[checkbox_name]
            line_width = 1
            circle_visible = False
            if len(initial_sub_group_selections) > 0:
                line_alpha = unselected_alpha
            else:
                line_alpha = 0.6

        line = fig.line(x='x',
                        y='y',
                        color=color,
                        source=source,
                        line_width=line_width,
                        line_alpha=line_alpha,
                        line_join='round',
                        nonselection_line_color=colors[checkbox_name],
                        nonselection_line_alpha=0.5,
                        hover_alpha=1.0,
                        hover_color=colors[checkbox_name],
                       )
        line.hover_glyph.line_width = 3
        line.name = 'line_{0}'.format(checkbox_name)
        lines.append(line)
        
        circle = fig.circle(x='x',
                            y='y',
                            color=colors[checkbox_name],
                            source=source,
                            size=1,
                            fill_alpha=0.95,
                            line_alpha=0.95,
                            visible=circle_visible,
                            hover_alpha=0.95,
                            hover_color=colors[checkbox_name],
                           )
        circle.hover_glyph.visible = True
        circle.name = 'circle_{0}'.format(checkbox_name)
    
        legend_item = LegendItem(label=checkbox_name, renderers=[line])
        legend_items.append(legend_item)
        if checkbox_name in initial_sub_group_selections:
            initial_legend_items.append(legend_item)
        
    legend = bokeh.models.Legend(name='legend',
                                 items=legend_items,
                                )
    fig.add_layout(legend)
    
    source_callback = build_callback('metacodon_selection')
    for source in sources['plotted'].values():
        source.callback = source_callback
    
    hover = bokeh.models.HoverTool(line_policy='interp',
                                   renderers=lines,
                                  )
    hover.tooltips = [('name', '@name')]
    fig.add_tools(hover)
    
    menu = bokeh.models.widgets.MultiSelect(options=menu_options,
                                            value=[initial_menu_selection],
                                            size=min(40, len(menu_options)),
                                           )
    menu.callback = build_callback('metacodon_menu')
    
    sub_group_callback = build_callback('metacodon_sub_group',
                                        format_kwargs=dict(color_unselected='true'),
                                       )
    top_group_callback = build_callback('metacodon_top_group')

    top_groups = []
    sub_groups = []
    width = 100
    for top_name, sub_names in sorted(groupings.items()):
        width = 75 + max(len(l) for l in sub_names) * 6
        
        top_active = [0] if top_name in initial_top_group_selections else []
        top = bokeh.models.widgets.CheckboxGroup(labels=[top_name],
                                                 active=top_active,
                                                 width=width,
                                                 name='top_{0}'.format(top_name),
                                                 callback=top_group_callback,
                                                )
        top_groups.append(top)

        sub_active = [i for i, n in enumerate(sub_names) if n in initial_sub_group_selections]
        sub = bokeh.models.widgets.CheckboxGroup(labels=sorted(sub_names),
                                                 active=sub_active,
                                                 width=width,
                                                 callback=sub_group_callback,
                                                 name='sub_{0}'.format(top_name),
                                                )
        sub_groups.append(sub)
    
    alpha_slider = bokeh.models.Slider(start=0.,
                                       end=1.,
                                       value=0.5,
                                       step=.05,
                                       title='alpha',
                                      )
    alpha_slider.callback = build_callback('lengths_unselected_alpha')
    
    highest_level_chooser = bokeh.models.widgets.Select(options=ys.keys(),
                                                        value='raw_counts',
                                                       )

    injection_sources = []
    for key in ys:
        injection_sources.extend(sources[key].values())
    # Note: use throwaway names instead of source names to ensure no illegal
    # characters in names.
    injection = {'ensure_no_collision_{0}'.format(i): v for i, v in enumerate(injection_sources)}

    highest_level_chooser.callback = build_callback('metacodon_highest_level',
                                                    args=injection,
                                                   )

    grid = [
        top_groups,
        sub_groups,
        [fig, bokeh.layouts.widgetbox([menu, highest_level_chooser, alpha_slider])],
    ]
    bokeh.io.show(bokeh.layouts.layout(grid))