예제 #1
0
def addGeneLabels(fig, sourceData):
    labels = LabelSet(x='x_label',
                      y='y_label',
                      text='label',
                      source=sourceData,
                      render_mode='canvas',
                      text_font_size="18px")
    slider_font = Slider(start=0,
                         end=64,
                         value=16,
                         step=1,
                         title="Gene label font size in px")
    slider_angle = Slider(start=0,
                          end=pi / 2,
                          value=0,
                          step=0.01,
                          title="Gene label angle in radian")

    radio_label_type = RadioGroup(labels=[
        "name", "product", "family", "local identifier", "gene ID", "none"
    ],
                                  active=0)

    slider_angle.js_link('value', labels, 'angle')

    slider_font.js_on_change(
        'value',
        CustomJS(args=dict(other=labels),
                 code="other.text_font_size = this.value+'px';"))

    radio_label_type.js_on_click(
        CustomJS(args=dict(other=labels, source=sourceData),
                 code="""
                if(this.active == 5){
                    source.data['label'] = [];
                    for(var i=0;i<source.data['name'].length;i++){
                        source.data['label'].push('');
                    }
                }else if(this.active == 3){
                    source.data['label'] = source.data['gene_local_ID'];
                }else if(this.active == 4){
                    source.data['label'] = source.data['gene_ID'];
                }
                else{
                    source.data['label'] = source.data[this.labels[this.active]];
                }
                other.source = source;
                source.change.emit();
                """))

    label_header = Div(text="<b>Gene labels:</b>")
    radio_title = Div(text="""Gene labels to use:""", width=200, height=100)
    labels_block = column(label_header, row(slider_font, slider_angle),
                          column(radio_title, radio_label_type))

    fig.add_layout(labels)

    return labels_block, labels
예제 #2
0
def sliderPlot():
    plot = figure(
        title="Adjustable Radius Slider Plot",
        sizing_mode="fixed",
        plot_width=400,
        plot_height=400,
    )
    r = plot.circle(
        [
            1,
            2,
            3,
            4,
            5,
        ],
        [3, 2, 5, 6, 4],
        radius=0.2,
        alpha=0.5,
    )

    slider = Slider(start=0.1, end=2, step=0.01, value=0.2)
    slider.js_link("value", r.glyph, "radius")
    return column(plot, slider)
def create():
    doc = curdoc()
    det_data = {}
    cami_meta = {}

    def proposal_textinput_callback(_attr, _old, new):
        nonlocal cami_meta
        proposal = new.strip()
        for zebra_proposals_path in pyzebra.ZEBRA_PROPOSALS_PATHS:
            proposal_path = os.path.join(zebra_proposals_path, proposal)
            if os.path.isdir(proposal_path):
                # found it
                break
        else:
            raise ValueError(f"Can not find data for proposal '{proposal}'.")

        file_list = []
        for file in os.listdir(proposal_path):
            if file.endswith(".hdf"):
                file_list.append((os.path.join(proposal_path, file), file))
        file_select.options = file_list

        cami_meta = {}

    proposal_textinput = TextInput(title="Proposal number:", width=210)
    proposal_textinput.on_change("value", proposal_textinput_callback)

    def upload_button_callback(_attr, _old, new):
        nonlocal cami_meta
        with io.StringIO(base64.b64decode(new).decode()) as file:
            cami_meta = pyzebra.parse_h5meta(file)
            file_list = cami_meta["filelist"]
            file_select.options = [(entry, os.path.basename(entry))
                                   for entry in file_list]

    upload_div = Div(text="or upload .cami file:", margin=(5, 5, 0, 5))
    upload_button = FileInput(accept=".cami", width=200)
    upload_button.on_change("value", upload_button_callback)

    def update_image(index=None):
        if index is None:
            index = index_spinner.value

        current_image = det_data["data"][index]
        proj_v_line_source.data.update(x=np.arange(0, IMAGE_W) + 0.5,
                                       y=np.mean(current_image, axis=0))
        proj_h_line_source.data.update(x=np.mean(current_image, axis=1),
                                       y=np.arange(0, IMAGE_H) + 0.5)

        image_source.data.update(
            h=[np.zeros((1, 1))],
            k=[np.zeros((1, 1))],
            l=[np.zeros((1, 1))],
        )
        image_source.data.update(image=[current_image])

        if main_auto_checkbox.active:
            im_min = np.min(current_image)
            im_max = np.max(current_image)

            display_min_spinner.value = im_min
            display_max_spinner.value = im_max

            image_glyph.color_mapper.low = im_min
            image_glyph.color_mapper.high = im_max

        if "mf" in det_data:
            metadata_table_source.data.update(mf=[det_data["mf"][index]])
        else:
            metadata_table_source.data.update(mf=[None])

        if "temp" in det_data:
            metadata_table_source.data.update(temp=[det_data["temp"][index]])
        else:
            metadata_table_source.data.update(temp=[None])

        gamma, nu = calculate_pol(det_data, index)
        omega = np.ones((IMAGE_H, IMAGE_W)) * det_data["omega"][index]
        image_source.data.update(gamma=[gamma], nu=[nu], omega=[omega])

    def update_overview_plot():
        h5_data = det_data["data"]
        n_im, n_y, n_x = h5_data.shape
        overview_x = np.mean(h5_data, axis=1)
        overview_y = np.mean(h5_data, axis=2)

        overview_plot_x_image_source.data.update(image=[overview_x],
                                                 dw=[n_x],
                                                 dh=[n_im])
        overview_plot_y_image_source.data.update(image=[overview_y],
                                                 dw=[n_y],
                                                 dh=[n_im])

        if proj_auto_checkbox.active:
            im_min = min(np.min(overview_x), np.min(overview_y))
            im_max = max(np.max(overview_x), np.max(overview_y))

            proj_display_min_spinner.value = im_min
            proj_display_max_spinner.value = im_max

            overview_plot_x_image_glyph.color_mapper.low = im_min
            overview_plot_y_image_glyph.color_mapper.low = im_min
            overview_plot_x_image_glyph.color_mapper.high = im_max
            overview_plot_y_image_glyph.color_mapper.high = im_max

        frame_range.start = 0
        frame_range.end = n_im
        frame_range.reset_start = 0
        frame_range.reset_end = n_im
        frame_range.bounds = (0, n_im)

        scan_motor = det_data["scan_motor"]
        overview_plot_y.axis[1].axis_label = f"Scanning motor, {scan_motor}"

        var = det_data[scan_motor]
        var_start = var[0]
        var_end = var[-1] + (var[-1] - var[0]) / (n_im - 1)

        scanning_motor_range.start = var_start
        scanning_motor_range.end = var_end
        scanning_motor_range.reset_start = var_start
        scanning_motor_range.reset_end = var_end
        # handle both, ascending and descending sequences
        scanning_motor_range.bounds = (min(var_start,
                                           var_end), max(var_start, var_end))

    def file_select_callback(_attr, old, new):
        nonlocal det_data
        if not new:
            # skip empty selections
            return

        # Avoid selection of multiple indicies (via Shift+Click or Ctrl+Click)
        if len(new) > 1:
            # drop selection to the previous one
            file_select.value = old
            return

        if len(old) > 1:
            # skip unnecessary update caused by selection drop
            return

        det_data = pyzebra.read_detector_data(new[0])

        if cami_meta and "crystal" in cami_meta:
            det_data["ub"] = cami_meta["crystal"]["UB"]

        index_spinner.value = 0
        index_spinner.high = det_data["data"].shape[0] - 1
        index_slider.end = det_data["data"].shape[0] - 1

        zebra_mode = det_data["zebra_mode"]
        if zebra_mode == "nb":
            metadata_table_source.data.update(geom=["normal beam"])
        else:  # zebra_mode == "bi"
            metadata_table_source.data.update(geom=["bisecting"])

        update_image(0)
        update_overview_plot()

    file_select = MultiSelect(title="Available .hdf files:",
                              width=210,
                              height=250)
    file_select.on_change("value", file_select_callback)

    def index_callback(_attr, _old, new):
        update_image(new)

    index_slider = Slider(value=0, start=0, end=1, show_value=False, width=400)

    index_spinner = Spinner(title="Image index:", value=0, low=0, width=100)
    index_spinner.on_change("value", index_callback)

    index_slider.js_link("value_throttled", index_spinner, "value")
    index_spinner.js_link("value", index_slider, "value")

    plot = Plot(
        x_range=Range1d(0, IMAGE_W, bounds=(0, IMAGE_W)),
        y_range=Range1d(0, IMAGE_H, bounds=(0, IMAGE_H)),
        plot_height=IMAGE_PLOT_H,
        plot_width=IMAGE_PLOT_W,
        toolbar_location="left",
    )

    # ---- tools
    plot.toolbar.logo = None

    # ---- axes
    plot.add_layout(LinearAxis(), place="above")
    plot.add_layout(LinearAxis(major_label_orientation="vertical"),
                    place="right")

    # ---- grid lines
    plot.add_layout(Grid(dimension=0, ticker=BasicTicker()))
    plot.add_layout(Grid(dimension=1, ticker=BasicTicker()))

    # ---- rgba image glyph
    image_source = ColumnDataSource(
        dict(
            image=[np.zeros((IMAGE_H, IMAGE_W), dtype="float32")],
            h=[np.zeros((1, 1))],
            k=[np.zeros((1, 1))],
            l=[np.zeros((1, 1))],
            gamma=[np.zeros((1, 1))],
            nu=[np.zeros((1, 1))],
            omega=[np.zeros((1, 1))],
            x=[0],
            y=[0],
            dw=[IMAGE_W],
            dh=[IMAGE_H],
        ))

    h_glyph = Image(image="h", x="x", y="y", dw="dw", dh="dh", global_alpha=0)
    k_glyph = Image(image="k", x="x", y="y", dw="dw", dh="dh", global_alpha=0)
    l_glyph = Image(image="l", x="x", y="y", dw="dw", dh="dh", global_alpha=0)
    gamma_glyph = Image(image="gamma",
                        x="x",
                        y="y",
                        dw="dw",
                        dh="dh",
                        global_alpha=0)
    nu_glyph = Image(image="nu",
                     x="x",
                     y="y",
                     dw="dw",
                     dh="dh",
                     global_alpha=0)
    omega_glyph = Image(image="omega",
                        x="x",
                        y="y",
                        dw="dw",
                        dh="dh",
                        global_alpha=0)

    plot.add_glyph(image_source, h_glyph)
    plot.add_glyph(image_source, k_glyph)
    plot.add_glyph(image_source, l_glyph)
    plot.add_glyph(image_source, gamma_glyph)
    plot.add_glyph(image_source, nu_glyph)
    plot.add_glyph(image_source, omega_glyph)

    image_glyph = Image(image="image", x="x", y="y", dw="dw", dh="dh")
    plot.add_glyph(image_source, image_glyph, name="image_glyph")

    # ---- projections
    proj_v = Plot(
        x_range=plot.x_range,
        y_range=DataRange1d(),
        plot_height=150,
        plot_width=IMAGE_PLOT_W,
        toolbar_location=None,
    )

    proj_v.add_layout(LinearAxis(major_label_orientation="vertical"),
                      place="right")
    proj_v.add_layout(LinearAxis(major_label_text_font_size="0pt"),
                      place="below")

    proj_v.add_layout(Grid(dimension=0, ticker=BasicTicker()))
    proj_v.add_layout(Grid(dimension=1, ticker=BasicTicker()))

    proj_v_line_source = ColumnDataSource(dict(x=[], y=[]))
    proj_v.add_glyph(proj_v_line_source,
                     Line(x="x", y="y", line_color="steelblue"))

    proj_h = Plot(
        x_range=DataRange1d(),
        y_range=plot.y_range,
        plot_height=IMAGE_PLOT_H,
        plot_width=150,
        toolbar_location=None,
    )

    proj_h.add_layout(LinearAxis(), place="above")
    proj_h.add_layout(LinearAxis(major_label_text_font_size="0pt"),
                      place="left")

    proj_h.add_layout(Grid(dimension=0, ticker=BasicTicker()))
    proj_h.add_layout(Grid(dimension=1, ticker=BasicTicker()))

    proj_h_line_source = ColumnDataSource(dict(x=[], y=[]))
    proj_h.add_glyph(proj_h_line_source,
                     Line(x="x", y="y", line_color="steelblue"))

    # add tools
    hovertool = HoverTool(tooltips=[
        ("intensity", "@image"),
        ("gamma", "@gamma"),
        ("nu", "@nu"),
        ("omega", "@omega"),
        ("h", "@h"),
        ("k", "@k"),
        ("l", "@l"),
    ])

    box_edit_source = ColumnDataSource(dict(x=[], y=[], width=[], height=[]))
    box_edit_glyph = Rect(x="x",
                          y="y",
                          width="width",
                          height="height",
                          fill_alpha=0,
                          line_color="red")
    box_edit_renderer = plot.add_glyph(box_edit_source, box_edit_glyph)
    boxedittool = BoxEditTool(renderers=[box_edit_renderer], num_objects=1)

    def box_edit_callback(_attr, _old, new):
        if new["x"]:
            h5_data = det_data["data"]
            x_val = np.arange(h5_data.shape[0])
            left = int(np.floor(new["x"][0]))
            right = int(np.ceil(new["x"][0] + new["width"][0]))
            bottom = int(np.floor(new["y"][0]))
            top = int(np.ceil(new["y"][0] + new["height"][0]))
            y_val = np.sum(h5_data[:, bottom:top, left:right], axis=(1, 2))
        else:
            x_val = []
            y_val = []

        roi_avg_plot_line_source.data.update(x=x_val, y=y_val)

    box_edit_source.on_change("data", box_edit_callback)

    wheelzoomtool = WheelZoomTool(maintain_focus=False)
    plot.add_tools(
        PanTool(),
        BoxZoomTool(),
        wheelzoomtool,
        ResetTool(),
        hovertool,
        boxedittool,
    )
    plot.toolbar.active_scroll = wheelzoomtool

    # shared frame ranges
    frame_range = Range1d(0, 1, bounds=(0, 1))
    scanning_motor_range = Range1d(0, 1, bounds=(0, 1))

    det_x_range = Range1d(0, IMAGE_W, bounds=(0, IMAGE_W))
    overview_plot_x = Plot(
        title=Title(text="Projections on X-axis"),
        x_range=det_x_range,
        y_range=frame_range,
        extra_y_ranges={"scanning_motor": scanning_motor_range},
        plot_height=400,
        plot_width=IMAGE_PLOT_W - 3,
    )

    # ---- tools
    wheelzoomtool = WheelZoomTool(maintain_focus=False)
    overview_plot_x.toolbar.logo = None
    overview_plot_x.add_tools(
        PanTool(),
        BoxZoomTool(),
        wheelzoomtool,
        ResetTool(),
    )
    overview_plot_x.toolbar.active_scroll = wheelzoomtool

    # ---- axes
    overview_plot_x.add_layout(LinearAxis(axis_label="Coordinate X, pix"),
                               place="below")
    overview_plot_x.add_layout(LinearAxis(axis_label="Frame",
                                          major_label_orientation="vertical"),
                               place="left")

    # ---- grid lines
    overview_plot_x.add_layout(Grid(dimension=0, ticker=BasicTicker()))
    overview_plot_x.add_layout(Grid(dimension=1, ticker=BasicTicker()))

    # ---- rgba image glyph
    overview_plot_x_image_source = ColumnDataSource(
        dict(image=[np.zeros((1, 1), dtype="float32")],
             x=[0],
             y=[0],
             dw=[IMAGE_W],
             dh=[1]))

    overview_plot_x_image_glyph = Image(image="image",
                                        x="x",
                                        y="y",
                                        dw="dw",
                                        dh="dh")
    overview_plot_x.add_glyph(overview_plot_x_image_source,
                              overview_plot_x_image_glyph,
                              name="image_glyph")

    det_y_range = Range1d(0, IMAGE_H, bounds=(0, IMAGE_H))
    overview_plot_y = Plot(
        title=Title(text="Projections on Y-axis"),
        x_range=det_y_range,
        y_range=frame_range,
        extra_y_ranges={"scanning_motor": scanning_motor_range},
        plot_height=400,
        plot_width=IMAGE_PLOT_H + 22,
    )

    # ---- tools
    wheelzoomtool = WheelZoomTool(maintain_focus=False)
    overview_plot_y.toolbar.logo = None
    overview_plot_y.add_tools(
        PanTool(),
        BoxZoomTool(),
        wheelzoomtool,
        ResetTool(),
    )
    overview_plot_y.toolbar.active_scroll = wheelzoomtool

    # ---- axes
    overview_plot_y.add_layout(LinearAxis(axis_label="Coordinate Y, pix"),
                               place="below")
    overview_plot_y.add_layout(
        LinearAxis(
            y_range_name="scanning_motor",
            axis_label="Scanning motor",
            major_label_orientation="vertical",
        ),
        place="right",
    )

    # ---- grid lines
    overview_plot_y.add_layout(Grid(dimension=0, ticker=BasicTicker()))
    overview_plot_y.add_layout(Grid(dimension=1, ticker=BasicTicker()))

    # ---- rgba image glyph
    overview_plot_y_image_source = ColumnDataSource(
        dict(image=[np.zeros((1, 1), dtype="float32")],
             x=[0],
             y=[0],
             dw=[IMAGE_H],
             dh=[1]))

    overview_plot_y_image_glyph = Image(image="image",
                                        x="x",
                                        y="y",
                                        dw="dw",
                                        dh="dh")
    overview_plot_y.add_glyph(overview_plot_y_image_source,
                              overview_plot_y_image_glyph,
                              name="image_glyph")

    roi_avg_plot = Plot(
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=150,
        plot_width=IMAGE_PLOT_W,
        toolbar_location="left",
    )

    # ---- tools
    roi_avg_plot.toolbar.logo = None

    # ---- axes
    roi_avg_plot.add_layout(LinearAxis(), place="below")
    roi_avg_plot.add_layout(LinearAxis(major_label_orientation="vertical"),
                            place="left")

    # ---- grid lines
    roi_avg_plot.add_layout(Grid(dimension=0, ticker=BasicTicker()))
    roi_avg_plot.add_layout(Grid(dimension=1, ticker=BasicTicker()))

    roi_avg_plot_line_source = ColumnDataSource(dict(x=[], y=[]))
    roi_avg_plot.add_glyph(roi_avg_plot_line_source,
                           Line(x="x", y="y", line_color="steelblue"))

    cmap_dict = {
        "gray": Greys256,
        "gray_reversed": Greys256[::-1],
        "plasma": Plasma256,
        "cividis": Cividis256,
    }

    def colormap_callback(_attr, _old, new):
        image_glyph.color_mapper = LinearColorMapper(palette=cmap_dict[new])
        overview_plot_x_image_glyph.color_mapper = LinearColorMapper(
            palette=cmap_dict[new])
        overview_plot_y_image_glyph.color_mapper = LinearColorMapper(
            palette=cmap_dict[new])

    colormap = Select(title="Colormap:",
                      options=list(cmap_dict.keys()),
                      width=210)
    colormap.on_change("value", colormap_callback)
    colormap.value = "plasma"

    STEP = 1

    def main_auto_checkbox_callback(state):
        if state:
            display_min_spinner.disabled = True
            display_max_spinner.disabled = True
        else:
            display_min_spinner.disabled = False
            display_max_spinner.disabled = False

        update_image()

    main_auto_checkbox = CheckboxGroup(labels=["Main Auto Range"],
                                       active=[0],
                                       width=145,
                                       margin=[10, 5, 0, 5])
    main_auto_checkbox.on_click(main_auto_checkbox_callback)

    def display_max_spinner_callback(_attr, _old_value, new_value):
        display_min_spinner.high = new_value - STEP
        image_glyph.color_mapper.high = new_value

    display_max_spinner = Spinner(
        low=0 + STEP,
        value=1,
        step=STEP,
        disabled=bool(main_auto_checkbox.active),
        width=100,
        height=31,
    )
    display_max_spinner.on_change("value", display_max_spinner_callback)

    def display_min_spinner_callback(_attr, _old_value, new_value):
        display_max_spinner.low = new_value + STEP
        image_glyph.color_mapper.low = new_value

    display_min_spinner = Spinner(
        low=0,
        high=1 - STEP,
        value=0,
        step=STEP,
        disabled=bool(main_auto_checkbox.active),
        width=100,
        height=31,
    )
    display_min_spinner.on_change("value", display_min_spinner_callback)

    PROJ_STEP = 0.1

    def proj_auto_checkbox_callback(state):
        if state:
            proj_display_min_spinner.disabled = True
            proj_display_max_spinner.disabled = True
        else:
            proj_display_min_spinner.disabled = False
            proj_display_max_spinner.disabled = False

        update_overview_plot()

    proj_auto_checkbox = CheckboxGroup(labels=["Projections Auto Range"],
                                       active=[0],
                                       width=145,
                                       margin=[10, 5, 0, 5])
    proj_auto_checkbox.on_click(proj_auto_checkbox_callback)

    def proj_display_max_spinner_callback(_attr, _old_value, new_value):
        proj_display_min_spinner.high = new_value - PROJ_STEP
        overview_plot_x_image_glyph.color_mapper.high = new_value
        overview_plot_y_image_glyph.color_mapper.high = new_value

    proj_display_max_spinner = Spinner(
        low=0 + PROJ_STEP,
        value=1,
        step=PROJ_STEP,
        disabled=bool(proj_auto_checkbox.active),
        width=100,
        height=31,
    )
    proj_display_max_spinner.on_change("value",
                                       proj_display_max_spinner_callback)

    def proj_display_min_spinner_callback(_attr, _old_value, new_value):
        proj_display_max_spinner.low = new_value + PROJ_STEP
        overview_plot_x_image_glyph.color_mapper.low = new_value
        overview_plot_y_image_glyph.color_mapper.low = new_value

    proj_display_min_spinner = Spinner(
        low=0,
        high=1 - PROJ_STEP,
        value=0,
        step=PROJ_STEP,
        disabled=bool(proj_auto_checkbox.active),
        width=100,
        height=31,
    )
    proj_display_min_spinner.on_change("value",
                                       proj_display_min_spinner_callback)

    def hkl_button_callback():
        index = index_spinner.value
        h, k, l = calculate_hkl(det_data, index)
        image_source.data.update(h=[h], k=[k], l=[l])

    hkl_button = Button(label="Calculate hkl (slow)", width=210)
    hkl_button.on_click(hkl_button_callback)

    def events_list_callback(_attr, _old, new):
        doc.events_list_spind.value = new

    events_list = TextAreaInput(rows=7, width=830)
    events_list.on_change("value", events_list_callback)
    doc.events_list_hdf_viewer = events_list

    def add_event_button_callback():
        diff_vec = []
        p0 = [1.0, 0.0, 1.0]
        maxfev = 100000

        wave = det_data["wave"]
        ddist = det_data["ddist"]

        gamma = det_data["gamma"][0]
        omega = det_data["omega"][0]
        nu = det_data["nu"][0]
        chi = det_data["chi"][0]
        phi = det_data["phi"][0]

        scan_motor = det_data["scan_motor"]
        var_angle = det_data[scan_motor]

        x0 = int(np.floor(det_x_range.start))
        xN = int(np.ceil(det_x_range.end))
        y0 = int(np.floor(det_y_range.start))
        yN = int(np.ceil(det_y_range.end))
        fr0 = int(np.floor(frame_range.start))
        frN = int(np.ceil(frame_range.end))
        data_roi = det_data["data"][fr0:frN, y0:yN, x0:xN]

        cnts = np.sum(data_roi, axis=(1, 2))
        coeff, _ = curve_fit(gauss,
                             range(len(cnts)),
                             cnts,
                             p0=p0,
                             maxfev=maxfev)

        m = cnts.mean()
        sd = cnts.std()
        snr_cnts = np.where(sd == 0, 0, m / sd)

        frC = fr0 + coeff[1]
        var_F = var_angle[math.floor(frC)]
        var_C = var_angle[math.ceil(frC)]
        frStep = frC - math.floor(frC)
        var_step = var_C - var_F
        var_p = var_F + var_step * frStep

        if scan_motor == "gamma":
            gamma = var_p
        elif scan_motor == "omega":
            omega = var_p
        elif scan_motor == "nu":
            nu = var_p
        elif scan_motor == "chi":
            chi = var_p
        elif scan_motor == "phi":
            phi = var_p

        intensity = coeff[1] * abs(
            coeff[2] * var_step) * math.sqrt(2) * math.sqrt(np.pi)

        projX = np.sum(data_roi, axis=(0, 1))
        coeff, _ = curve_fit(gauss,
                             range(len(projX)),
                             projX,
                             p0=p0,
                             maxfev=maxfev)
        x_pos = x0 + coeff[1]

        projY = np.sum(data_roi, axis=(0, 2))
        coeff, _ = curve_fit(gauss,
                             range(len(projY)),
                             projY,
                             p0=p0,
                             maxfev=maxfev)
        y_pos = y0 + coeff[1]

        ga, nu = pyzebra.det2pol(ddist, gamma, nu, x_pos, y_pos)
        diff_vector = pyzebra.z1frmd(wave, ga, omega, chi, phi, nu)
        d_spacing = float(pyzebra.dandth(wave, diff_vector)[0])
        diff_vector = diff_vector.flatten() * 1e10
        dv1, dv2, dv3 = diff_vector

        diff_vec.append(diff_vector)

        if events_list.value and not events_list.value.endswith("\n"):
            events_list.value = events_list.value + "\n"

        events_list.value = (
            events_list.value +
            f"{x_pos} {y_pos} {intensity} {snr_cnts} {dv1} {dv2} {dv3} {d_spacing}"
        )

    add_event_button = Button(label="Add spind event")
    add_event_button.on_click(add_event_button_callback)

    metadata_table_source = ColumnDataSource(
        dict(geom=[""], temp=[None], mf=[None]))
    num_formatter = NumberFormatter(format="0.00", nan_format="")
    metadata_table = DataTable(
        source=metadata_table_source,
        columns=[
            TableColumn(field="geom", title="Geometry", width=100),
            TableColumn(field="temp",
                        title="Temperature",
                        formatter=num_formatter,
                        width=100),
            TableColumn(field="mf",
                        title="Magnetic Field",
                        formatter=num_formatter,
                        width=100),
        ],
        width=300,
        height=50,
        autosize_mode="none",
        index_position=None,
    )

    # Final layout
    import_layout = column(proposal_textinput, upload_div, upload_button,
                           file_select)
    layout_image = column(
        gridplot([[proj_v, None], [plot, proj_h]], merge_tools=False))
    colormap_layout = column(
        colormap,
        main_auto_checkbox,
        row(display_min_spinner, display_max_spinner),
        proj_auto_checkbox,
        row(proj_display_min_spinner, proj_display_max_spinner),
    )

    layout_controls = column(
        row(metadata_table, index_spinner,
            column(Spacer(height=25), index_slider)),
        row(add_event_button, hkl_button),
        row(events_list),
    )

    layout_overview = column(
        gridplot(
            [[overview_plot_x, overview_plot_y]],
            toolbar_options=dict(logo=None),
            merge_tools=True,
            toolbar_location="left",
        ), )

    tab_layout = row(
        column(import_layout, colormap_layout),
        column(layout_overview, layout_controls),
        column(roi_avg_plot, layout_image),
    )

    return Panel(child=tab_layout, title="hdf viewer")
예제 #4
0
# Create our Bokeh figure
p = figure(plot_height=800, plot_width=800, title = "Protocol bytes vs packets",
           tools="pan,wheel_zoom,box_zoom,reset,hover", 
           tooltips="Bytes = @dst_bytes - Packets = @dst_packets, Port = @dst_port", 
           toolbar_location="below")
# Add scatter object to our figure
s = p.scatter("dst_bytes", "dst_packets", source=ColumnDataSource(scatter_data), legend_field="dst_port", fill_alpha=0.8, size=7,
          fill_color='colors', line_color='colors')

# Format axes
p.xaxis.axis_label = 'Bytes'
p.yaxis.axis_label = 'Packets'

# Link the value of our slider to the size value in our scatter object
slider.js_link('value', s.glyph, 'size')

# Display the slider and plot togeher in a column layout
show(column(slider, p))

Bokeh also has a number of integrations to make plotting simple. One of these that is particularly useful when investigating network data is [integration with Networkx]("https://docs.bokeh.org/en/latest/docs/user_guide/graph.html?highlight=networkx").</br> Bokeh can take a Networkx graph and plot it on a figure, in addition you can apply a number of Bokeh's interactive options to this allowing for interactive networkx plots.

# Create a edgelist from our dataset
edgelist= pd.DataFrame({"source": clean_data['src_ip'].to_list(), "target": clean_data['dst_ip'].to_list(), "weight":clean_data['total_bytes'].to_list()})
# Create networkx graph from our edgelist
G = nx.from_pandas_edgelist(edgelist)

# Create our Bokeh figure
p = figure(title="Network node communication graph", x_range=(-2.5,2.5), y_range=(-2.5,2.5))
# Set our hover items and add it to the plot
node_hover_tool = HoverTool(tooltips=[("IP address", "@index")])
                        start=0,
                        end=90,
                        step=10)

# plotting widgets
row_color_widget = ColorPicker(title="Row Color")
column_color_widget = ColorPicker(title="Column Color")
row_color_widget.js_link('color', horizontal_lines.glyph, 'line_color')
column_color_widget.js_link('color', vertical_lines.glyph, 'line_color')

line_thickness = Slider(title="Line Thickness",
                        value=1,
                        start=0,
                        end=10,
                        step=1)
line_thickness.js_link('value', vertical_lines.glyph, 'line_width')
line_thickness.js_link('value', horizontal_lines.glyph, 'line_width')


# Set up callbacks
def update_data(attrname, old, new):

    # Get the current slider values
    ll = line_length.value
    lg = line_gap.value
    rd = row_density.value
    cd = column_density.value

    lines.make_lines(ll, lg, rd, cd)

    horizontal_source.data = dict(
예제 #6
0
# create another new plot and add a renderer
right = figure(tools=TOOLS, plot_width=300, plot_height=300, title=None)
right.circle('x', 'y1', source=source)

p = gridplot([[left, right]])

show(p)

# Linked properties - Link values of Bokeh model properties together, so they
# remain synchronzed, using js_link.

output_file("JS_link.html")

plot = figure(plot_width=400, plot_height=400)
r = plot.circle([1, 2, 3, 4, 5], [3, 2, 5, 6, 4], radius=0.2, alpha=0.5)

slider = Slider(start=0.1, end=2, step=0.01, value=0.2)

# method js_link(attr, other, other_attr)
# @brief Link 2 Bokeh model properties using JavaScript.
# @details This is a convenience method that simplifies adding a CustomJS
# callback to update 1 Bokeh model property whenever another changes value.
# Parameters * attr(str) - The name of a Bokeh property on this model
# * other (Model) - A Bokeh model to link to self.attr
# * other_attr(str) - The property on other to link together.

slider.js_link('value', r.glyph, 'radius')

show(column(plot, slider))
예제 #7
0
def mast_bokeh(eph, mast_results, stcs=None, display=False):
    # Function to produce a Bokeh plot of MAST results with the target path

    p = figure(plot_width=700,
               x_axis_label="RA (deg)",
               y_axis_label="Dec (deg)")

    # Target path
    eph_data = {
        'eph_x': eph['RA'],
        'eph_y': eph['DEC'],
        'Date': eph['datetime_str']
    }
    eph_plot1 = p.line(x='eph_x',
                       y='eph_y',
                       source=eph_data,
                       line_width=2,
                       line_color='black',
                       legend=eph['targetname'][0])
    eph_plot2 = p.circle(x='eph_x',
                         y='eph_y',
                         source=eph_data,
                         fill_color="black",
                         size=12,
                         legend=eph['targetname'][0])
    p.add_tools(
        HoverTool(renderers=[eph_plot1, eph_plot2],
                  tooltips=[('Date', "@Date")]))

    # Target footprint
    patch_xs = parse_s_region(stcs)['ra']
    patch_ys = parse_s_region(stcs)['dec']

    stcs_data = {'stcs_x': [patch_xs], 'stcs_y': [patch_ys]}
    p.patches('stcs_x',
              'stcs_y',
              source=stcs_data,
              fill_alpha=0.,
              line_color="grey",
              line_width=0.8,
              line_dash='dashed',
              legend='Search Area')

    # Prepare MAST footprints
    obsDF = mast_results.to_pandas()
    obsDF['coords'] = obsDF.apply(lambda x: parse_s_region(x['s_region']),
                                  axis=1)
    for col in mast_results.colnames:
        if isinstance(obsDF[col][0], bytes):
            obsDF[col] = obsDF[col].str.decode('utf-8')

    # Loop over missions, coloring each separately
    mast_plots = []
    for mission, color in zip(obsDF['obs_collection'].unique(), palette):
        ind = obsDF['obs_collection'] == mission

        # Some missions have very complex STCS and need to be treated separately
        if mission in ('Kepler', 'K2', 'K2FFI'):
            plot_data = _individual_plot_data(obsDF[ind])
            for data in plot_data:
                mast_plots.append(
                    p.patches('x',
                              'y',
                              source=data,
                              legend=mission,
                              fill_color=color,
                              fill_alpha=0.3,
                              line_color="white",
                              line_width=0.5))
        else:
            # Add patches with the observation footprings
            patch_xs = [c['ra'] for c in obsDF['coords'][ind]]
            patch_ys = [c['dec'] for c in obsDF['coords'][ind]]

            data = {
                'x': patch_xs,
                'y': patch_ys,
                'obs_collection': obsDF['obs_collection'][ind],
                'instrument_name': obsDF['instrument_name'][ind],
                'obs_id': obsDF['obs_id'][ind],
                'target_name': obsDF['target_name'][ind],
                'proposal_pi': obsDF['proposal_pi'][ind],
                'obs_mid_date': obsDF['obs_mid_date'][ind],
                'filters': obsDF['filters'][ind]
            }
            mast_plots.append(
                p.patches('x',
                          'y',
                          source=data,
                          legend=mission,
                          fill_color=color,
                          fill_alpha=0.3,
                          line_color="white",
                          line_width=0.5))

    # Add hover tooltip for MAST observations
    tooltip = [("obs_id", "@obs_id"), ("target_name", "@target_name"),
               ("instrument_name", "@instrument_name"),
               ("filters", "@filters"), ('obs_mid_date', '@obs_mid_date')]
    p.add_tools(HoverTool(renderers=mast_plots, tooltips=tooltip))

    # Additional settings
    p.legend.click_policy = "hide"
    p.x_range.flipped = True

    # Slider for alpha settings
    slider = Slider(start=0,
                    end=1,
                    step=0.01,
                    value=0.3,
                    title="Footprint opacity")
    for i in range(len(mast_plots)):
        slider.js_link('value', mast_plots[i].glyph, 'fill_alpha')
    final = column(p, slider)

    if display:
        output_notebook()
        show(final)
    else:
        return final
r_by_station = plot_by_station.circle(
    grouped_data_by_start_station['Station'],
    grouped_data_by_start_station['Tripduration'] % 60,
    line_color=mapper_y,
    color=mapper_y,
    alpha=0.5)

plot_by_station.xaxis.major_label_orientation = 1.2
plot_by_station.toolbar_location = None

hover = HoverTool()
hover.tooltips = [('Duration', '@y')]
plot_by_station.add_tools(hover)

slider = Slider(start=0.1, end=2, step=0.01, value=0.3)
slider.js_link('value', r_by_station.glyph, 'radius')

color_bar = ColorBar(color_mapper=mapper_y['transform'],
                     width=8,
                     location=(0, 0))
plot_by_station.add_layout(color_bar, 'right')

# The amount of trips by station
amount_of_trips = df.groupby('Station').size().to_frame().reset_index()
amount_of_trips.columns = ["Station", "Trips"]

plot_trips_by_stations = figure(
    plot_width=900,
    plot_height=800,
    x_range=amount_of_trips['Station'],
    title="Amount of trips done in December 2019 from stations")
예제 #9
0
# create another new plot and add a renderer
right = figure(tools=TOOLS, plot_width=300, plot_height=300, title=None)
right.circle('x', 'y1', source=source)

p = gridplot([[left, right]])

show(p)

# Linked properties - Link values of Bokeh model properties together, so they
# remain synchronzed, using js_link.

output_file("JS_link.html")

plot = figure(plot_width=400, plot_height=400)
r = plot.circle([1,2,3,4,5], [3,2,5,6,4], radius=0.2, alpha=0.5)

slider = Slider(start=0.1, end=2, step=0.01, value=0.2)

# method js_link(attr, other, other_attr)
# @brief Link 2 Bokeh model properties using JavaScript.
# @details This is a convenience method that simplifies adding a CustomJS
# callback to update 1 Bokeh model property whenever another changes value.
# Parameters * attr(str) - The name of a Bokeh property on this model
# * other (Model) - A Bokeh model to link to self.attr
# * other_attr(str) - The property on other to link together.

slider.js_link('value', r.glyph, 'radius')

show(column(plot, slider))
m.circle(x=-9754910, y=5142738, size=10, color='orange')

show(m)
Interactive Widgets
In [91]:
# change size of scatter plot circles
from bokeh.layouts import column
from bokeh.models import Slider

# create figure and plot
change_plot_size = figure(plot_width=600, plot_height=300)
change_plot_size_r = change_plot_size.circle([1,2,3,4,5], [3,2,5,6,4], radius=0.1, alpha=0.5)

# create widget and link
slider = Slider(start=0.1, end=1, step=0.01, value=0.2)
slider.js_link('value', change_plot_size_r.glyph, 'radius')

show(column(change_plot_size, slider))
In [86]:
from sklearn import linear_model
from bokeh.layouts import layout
from bokeh.models import Toggle
import numpy as np

output_notebook()

# data
x = [1,2,3,4,5,6,7,8,9,10]
X = np.array(x).reshape(-1, 1)
y = [2,2,4,1,5,6,8,2,3,7]
Y = np.array(y).reshape(-1, 1)
예제 #11
0
def addGenomeTools(fig, geneRecs, genomeRecs, geneSource, genomeSource, nb,
                   geneLabels):
    # add genome labels
    genomeLabels = LabelSet(x='x_label',
                            y='y',
                            x_offset=-20,
                            text='name',
                            text_align="right",
                            source=genomeSource,
                            render_mode='canvas',
                            text_font_size="16px")
    fig.add_layout(genomeLabels)

    slider_font = Slider(start=0,
                         end=64,
                         value=16,
                         step=1,
                         title="Genome label font size in px")
    slider_font.js_on_change(
        'value',
        CustomJS(args=dict(other=genomeLabels),
                 code="other.text_font_size = this.value+'px';"))

    slider_offset = Slider(start=-400,
                           end=0,
                           value=-20,
                           step=1,
                           title="Genome label offset")
    slider_offset.js_link('value', genomeLabels, 'x_offset')

    slider_spacing = Slider(start=1,
                            end=40,
                            value=10,
                            step=1,
                            title="Genomes spacing")
    slider_spacing.js_on_change(
        'value',
        CustomJS(args=dict(geneRecs=geneRecs,
                           geneSource=geneSource,
                           genomeRecs=genomeRecs,
                           genomeSource=genomeSource,
                           nb_elements=nb,
                           genomeLabels=genomeLabels,
                           geneLabels=geneLabels),
                 code="""
            var current_val = genomeSource.data['y'][genomeSource.data['y'].length - 1] / (nb_elements-1);
            for (let i=0 ; i < genomeSource.data['y'].length ; i++){
                genomeSource.data['y'][i] =  (genomeSource.data['y'][i] * this.value) / current_val;
            }
            for (let i=0 ; i < geneSource.data['y'].length ; i++){
                if((geneSource.data['ordered'][i] == 'True' && geneSource.data['strand'][i] == '+') || (geneSource.data['ordered'][i] == 'False' && geneSource.data['strand'][i] == '-') ){
                    geneSource.data['y'][i] = (((geneSource.data['y'][i]-1) * this.value) / current_val) +1;
                    geneSource.data['y_label'][i] = (((geneSource.data['y_label'][i]-1-1.5) * this.value) / current_val) + 1 + 1.5;
                }else{
                    geneSource.data['y'][i] = (((geneSource.data['y'][i]+1) * this.value) / current_val) -1;
                    geneSource.data['y_label'][i] = (((geneSource.data['y_label'][i]+1-1.5) * this.value) / current_val) -1 + 1.5;

                }
            }
            geneRecs.source = geneSource;
            genomeRecs.source = genomeSource;
            geneLabels.source = geneSource;
            genomeLabels.source = genomeSource;
            geneSource.change.emit();
            genomeSource.change.emit();
        """))

    genome_header = Div(text="<b>Genomes:</b>")
    return column(genome_header, slider_spacing, slider_font, slider_offset)