예제 #1
0
def create_lines_chart(data,
                       title,
                       x_name,
                       y_name,
                       y2_name,
                       hover_tool=None,
                       width=1100,
                       height=400):
    """Creates a bar chart plot with the exact styling for the centcom
       dashboard. Pass in data as a dictionary, desired plot title,
       name of x axis, y axis and the hover tool HTML.
    """
    source = ColumnDataSource(data)
    xdr = FactorRange(factors=list(data[x_name]))
    ydr = Range1d(start=0,
                  end=max(max(data[y_name]), max(data[y2_name])) * 1.05)

    tools = []
    if hover_tool:
        tools = [
            hover_tool,
        ]

    plot = figure(title=title,
                  x_range=xdr,
                  y_range=ydr,
                  plot_width=width,
                  plot_height=height,
                  min_border=0,
                  toolbar_location="above",
                  tools=tools,
                  outline_line_color="#666666")

    glyph = Line(x=x_name,
                 y=y_name,
                 line_width=6,
                 line_alpha=0.6,
                 line_color="#ffc0cb")
    glyph2 = Line(x=x_name,
                  y=y2_name,
                  line_width=6,
                  line_alpha=0.6,
                  line_color="#013220")
    glyph1a = Scatter(x=x_name,
                      y=y_name,
                      size=7,
                      marker="square",
                      fill_color="#ffc0cb")
    glyph2a = Scatter(x=x_name,
                      y=y2_name,
                      size=7,
                      marker="square",
                      fill_color="#013220")

    plot.add_glyph(source, glyph)
    plot.add_glyph(source, glyph2)
    plot.add_glyph(source, glyph1a)
    plot.add_glyph(source, glyph2a)
    plot.add_tools(WheelZoomTool())
    plot.add_tools(BoxZoomTool())
    plot.add_tools(ZoomOutTool())

    xaxis = LinearAxis()
    yaxis = LinearAxis()

    plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
    plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
    plot.toolbar.logo = None
    plot.min_border_top = 0
    plot.xgrid.grid_line_color = None
    plot.ygrid.grid_line_color = "#999999"
    plot.yaxis.axis_label = "Observed and Fitted"
    plot.ygrid.grid_line_alpha = 0.1
    plot.xaxis.axis_label = ""
    plot.xaxis.major_label_orientation = 1
    return plot
예제 #2
0
def create(palm):
    doc = curdoc()

    # Calibration averaged waveforms per photon energy
    waveform_plot = Plot(
        title=Title(text="eTOF calibration waveforms"),
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=760,
        plot_width=PLOT_CANVAS_WIDTH,
        toolbar_location="right",
    )

    # ---- tools
    waveform_plot.toolbar.logo = None
    waveform_plot_hovertool = HoverTool(
        tooltips=[("energy, eV", "@en"), ("eTOF bin", "$x{0.}")])

    waveform_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(),
                            ResetTool(), waveform_plot_hovertool)

    # ---- axes
    waveform_plot.add_layout(LinearAxis(axis_label="eTOF time bin"),
                             place="below")
    waveform_plot.add_layout(LinearAxis(axis_label="Intensity",
                                        major_label_orientation="vertical"),
                             place="left")

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

    # ---- multiline glyphs
    waveform_ref_source = ColumnDataSource(dict(xs=[], ys=[], en=[]))
    waveform_ref_multiline = waveform_plot.add_glyph(
        waveform_ref_source, MultiLine(xs="xs", ys="ys", line_color="blue"))

    waveform_str_source = ColumnDataSource(dict(xs=[], ys=[], en=[]))
    waveform_str_multiline = waveform_plot.add_glyph(
        waveform_str_source, MultiLine(xs="xs", ys="ys", line_color="red"))

    # ---- legend
    waveform_plot.add_layout(
        Legend(items=[(
            "reference",
            [waveform_ref_multiline]), ("streaked",
                                        [waveform_str_multiline])]))
    waveform_plot.legend.click_policy = "hide"

    # ---- vertical spans
    photon_peak_ref_span = Span(location=0,
                                dimension="height",
                                line_dash="dashed",
                                line_color="blue")
    photon_peak_str_span = Span(location=0,
                                dimension="height",
                                line_dash="dashed",
                                line_color="red")
    waveform_plot.add_layout(photon_peak_ref_span)
    waveform_plot.add_layout(photon_peak_str_span)

    # Calibration fit plot
    fit_plot = Plot(
        title=Title(text="eTOF calibration fit"),
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=PLOT_CANVAS_HEIGHT,
        plot_width=PLOT_CANVAS_WIDTH,
        toolbar_location="right",
    )

    # ---- tools
    fit_plot.toolbar.logo = None
    fit_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(), ResetTool())

    # ---- axes
    fit_plot.add_layout(LinearAxis(axis_label="Photoelectron peak shift"),
                        place="below")
    fit_plot.add_layout(LinearAxis(axis_label="Photon energy, eV",
                                   major_label_orientation="vertical"),
                        place="left")

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

    # ---- circle glyphs
    fit_ref_circle_source = ColumnDataSource(dict(x=[], y=[]))
    fit_ref_circle = fit_plot.add_glyph(
        fit_ref_circle_source, Circle(x="x", y="y", line_color="blue"))
    fit_str_circle_source = ColumnDataSource(dict(x=[], y=[]))
    fit_str_circle = fit_plot.add_glyph(fit_str_circle_source,
                                        Circle(x="x", y="y", line_color="red"))

    # ---- line glyphs
    fit_ref_line_source = ColumnDataSource(dict(x=[], y=[]))
    fit_ref_line = fit_plot.add_glyph(fit_ref_line_source,
                                      Line(x="x", y="y", line_color="blue"))
    fit_str_line_source = ColumnDataSource(dict(x=[], y=[]))
    fit_str_line = fit_plot.add_glyph(fit_str_line_source,
                                      Line(x="x", y="y", line_color="red"))

    # ---- legend
    fit_plot.add_layout(
        Legend(items=[
            ("reference", [fit_ref_circle, fit_ref_line]),
            ("streaked", [fit_str_circle, fit_str_line]),
        ]))
    fit_plot.legend.click_policy = "hide"

    # Calibration results datatables
    def datatable_ref_source_callback(_attr, _old_value, new_value):
        for en, ps, use in zip(new_value["energy"], new_value["peak_pos_ref"],
                               new_value["use_in_fit"]):
            palm.etofs["0"].calib_data.loc[
                en, "calib_tpeak"] = ps if ps != "NaN" else np.nan
            palm.etofs["0"].calib_data.loc[en, "use_in_fit"] = use

        calib_res = {}
        for etof_key in palm.etofs:
            calib_res[etof_key] = palm.etofs[etof_key].fit_calibration_curve()
        update_calibration_plot(calib_res)

    datatable_ref_source = ColumnDataSource(
        dict(energy=["", "", ""],
             peak_pos_ref=["", "", ""],
             use_in_fit=[True, True, True]))
    datatable_ref_source.on_change("data", datatable_ref_source_callback)

    datatable_ref = DataTable(
        source=datatable_ref_source,
        columns=[
            TableColumn(field="energy",
                        title="Photon Energy, eV",
                        editor=IntEditor()),
            TableColumn(field="peak_pos_ref",
                        title="Reference Peak",
                        editor=IntEditor()),
            TableColumn(field="use_in_fit",
                        title=" ",
                        editor=CheckboxEditor(),
                        width=80),
        ],
        index_position=None,
        editable=True,
        height=300,
        width=250,
    )

    def datatable_str_source_callback(_attr, _old_value, new_value):
        for en, ps, use in zip(new_value["energy"], new_value["peak_pos_str"],
                               new_value["use_in_fit"]):
            palm.etofs["1"].calib_data.loc[
                en, "calib_tpeak"] = ps if ps != "NaN" else np.nan
            palm.etofs["1"].calib_data.loc[en, "use_in_fit"] = use

        calib_res = {}
        for etof_key in palm.etofs:
            calib_res[etof_key] = palm.etofs[etof_key].fit_calibration_curve()
        update_calibration_plot(calib_res)

    datatable_str_source = ColumnDataSource(
        dict(energy=["", "", ""],
             peak_pos_str=["", "", ""],
             use_in_fit=[True, True, True]))
    datatable_str_source.on_change("data", datatable_str_source_callback)

    datatable_str = DataTable(
        source=datatable_str_source,
        columns=[
            TableColumn(field="energy",
                        title="Photon Energy, eV",
                        editor=IntEditor()),
            TableColumn(field="peak_pos_str",
                        title="Streaked Peak",
                        editor=IntEditor()),
            TableColumn(field="use_in_fit",
                        title=" ",
                        editor=CheckboxEditor(),
                        width=80),
        ],
        index_position=None,
        editable=True,
        height=350,
        width=250,
    )

    # eTOF calibration folder path text input
    def path_textinput_callback(_attr, _old_value, _new_value):
        path_periodic_update()
        update_load_dropdown_menu()

    path_textinput = TextInput(title="eTOF calibration path:",
                               value=os.path.join(os.path.expanduser("~")),
                               width=510)
    path_textinput.on_change("value", path_textinput_callback)

    # eTOF calibration eco scans dropdown
    def scans_dropdown_callback(_attr, _old_value, new_value):
        scans_dropdown.label = new_value

    scans_dropdown = Dropdown(label="ECO scans",
                              button_type="default",
                              menu=[])
    scans_dropdown.on_change("value", scans_dropdown_callback)

    # ---- etof scans periodic update
    def path_periodic_update():
        new_menu = []
        if os.path.isdir(path_textinput.value):
            for entry in os.scandir(path_textinput.value):
                if entry.is_file() and entry.name.endswith(".json"):
                    new_menu.append((entry.name, entry.name))
        scans_dropdown.menu = sorted(new_menu, reverse=True)

    doc.add_periodic_callback(path_periodic_update, 5000)

    # Calibrate button
    def calibrate_button_callback():
        try:
            palm.calibrate_etof_eco(eco_scan_filename=os.path.join(
                path_textinput.value, scans_dropdown.value))
        except Exception:
            palm.calibrate_etof(folder_name=path_textinput.value)

        datatable_ref_source.data.update(
            energy=palm.etofs["0"].calib_data.index.tolist(),
            peak_pos_ref=palm.etofs["0"].calib_data["calib_tpeak"].tolist(),
            use_in_fit=palm.etofs["0"].calib_data["use_in_fit"].tolist(),
        )

        datatable_str_source.data.update(
            energy=palm.etofs["0"].calib_data.index.tolist(),
            peak_pos_str=palm.etofs["1"].calib_data["calib_tpeak"].tolist(),
            use_in_fit=palm.etofs["1"].calib_data["use_in_fit"].tolist(),
        )

    def update_calibration_plot(calib_res):
        etof_ref = palm.etofs["0"]
        etof_str = palm.etofs["1"]

        shift_val = 0
        etof_ref_wf_shifted = []
        etof_str_wf_shifted = []
        for wf_ref, wf_str in zip(etof_ref.calib_data["waveform"],
                                  etof_str.calib_data["waveform"]):
            shift_val -= max(wf_ref.max(), wf_str.max())
            etof_ref_wf_shifted.append(wf_ref + shift_val)
            etof_str_wf_shifted.append(wf_str + shift_val)

        waveform_ref_source.data.update(
            xs=len(etof_ref.calib_data) *
            [list(range(etof_ref.internal_time_bins))],
            ys=etof_ref_wf_shifted,
            en=etof_ref.calib_data.index.tolist(),
        )

        waveform_str_source.data.update(
            xs=len(etof_str.calib_data) *
            [list(range(etof_str.internal_time_bins))],
            ys=etof_str_wf_shifted,
            en=etof_str.calib_data.index.tolist(),
        )

        photon_peak_ref_span.location = etof_ref.calib_t0
        photon_peak_str_span.location = etof_str.calib_t0

        def plot_fit(time, calib_a, calib_b):
            time_fit = np.linspace(np.nanmin(time), np.nanmax(time), 100)
            en_fit = (calib_a / time_fit)**2 + calib_b
            return time_fit, en_fit

        def update_plot(calib_results, circle, line):
            (a, c), x, y = calib_results
            x_fit, y_fit = plot_fit(x, a, c)
            circle.data.update(x=x, y=y)
            line.data.update(x=x_fit, y=y_fit)

        update_plot(calib_res["0"], fit_ref_circle_source, fit_ref_line_source)
        update_plot(calib_res["1"], fit_str_circle_source, fit_str_line_source)

        calib_const_div.text = f"""
        a_str = {etof_str.calib_a:.2f}<br>
        b_str = {etof_str.calib_b:.2f}<br>
        <br>
        a_ref = {etof_ref.calib_a:.2f}<br>
        b_ref = {etof_ref.calib_b:.2f}
        """

    calibrate_button = Button(label="Calibrate eTOF",
                              button_type="default",
                              width=250)
    calibrate_button.on_click(calibrate_button_callback)

    # Photon peak noise threshold value text input
    def phot_peak_noise_thr_spinner_callback(_attr, old_value, new_value):
        if new_value > 0:
            for etof in palm.etofs.values():
                etof.photon_peak_noise_thr = new_value
        else:
            phot_peak_noise_thr_spinner.value = old_value

    phot_peak_noise_thr_spinner = Spinner(title="Photon peak noise threshold:",
                                          value=1,
                                          step=0.1)
    phot_peak_noise_thr_spinner.on_change(
        "value", phot_peak_noise_thr_spinner_callback)

    # Electron peak noise threshold value text input
    def el_peak_noise_thr_spinner_callback(_attr, old_value, new_value):
        if new_value > 0:
            for etof in palm.etofs.values():
                etof.electron_peak_noise_thr = new_value
        else:
            el_peak_noise_thr_spinner.value = old_value

    el_peak_noise_thr_spinner = Spinner(title="Electron peak noise threshold:",
                                        value=10,
                                        step=0.1)
    el_peak_noise_thr_spinner.on_change("value",
                                        el_peak_noise_thr_spinner_callback)

    # Save calibration button
    def save_button_callback():
        palm.save_etof_calib(path=path_textinput.value)
        update_load_dropdown_menu()

    save_button = Button(label="Save", button_type="default", width=250)
    save_button.on_click(save_button_callback)

    # Load calibration button
    def load_dropdown_callback(_attr, _old_value, new_value):
        if new_value:
            palm.load_etof_calib(os.path.join(path_textinput.value, new_value))

            datatable_ref_source.data.update(
                energy=palm.etofs["0"].calib_data.index.tolist(),
                peak_pos_ref=palm.etofs["0"].calib_data["calib_tpeak"].tolist(
                ),
                use_in_fit=palm.etofs["0"].calib_data["use_in_fit"].tolist(),
            )

            datatable_str_source.data.update(
                energy=palm.etofs["0"].calib_data.index.tolist(),
                peak_pos_str=palm.etofs["1"].calib_data["calib_tpeak"].tolist(
                ),
                use_in_fit=palm.etofs["1"].calib_data["use_in_fit"].tolist(),
            )

            # Drop selection, so that this callback can be triggered again on the same dropdown menu
            # item from the user perspective
            load_dropdown.value = ""

    def update_load_dropdown_menu():
        new_menu = []
        calib_file_ext = ".palm_etof"
        if os.path.isdir(path_textinput.value):
            for entry in os.scandir(path_textinput.value):
                if entry.is_file() and entry.name.endswith((calib_file_ext)):
                    new_menu.append(
                        (entry.name[:-len(calib_file_ext)], entry.name))
            load_dropdown.button_type = "default"
            load_dropdown.menu = sorted(new_menu, reverse=True)
        else:
            load_dropdown.button_type = "danger"
            load_dropdown.menu = new_menu

    doc.add_next_tick_callback(update_load_dropdown_menu)
    doc.add_periodic_callback(update_load_dropdown_menu, 5000)

    load_dropdown = Dropdown(label="Load", menu=[], width=250)
    load_dropdown.on_change("value", load_dropdown_callback)

    # eTOF fitting equation
    fit_eq_div = Div(
        text="""Fitting equation:<br><br><img src="/palm/static/5euwuy.gif">"""
    )

    # Calibration constants
    calib_const_div = Div(text=f"""
        a_str = {0}<br>
        b_str = {0}<br>
        <br>
        a_ref = {0}<br>
        b_ref = {0}
        """)

    # assemble
    tab_layout = column(
        row(
            column(waveform_plot, fit_plot),
            Spacer(width=30),
            column(
                path_textinput,
                scans_dropdown,
                calibrate_button,
                phot_peak_noise_thr_spinner,
                el_peak_noise_thr_spinner,
                row(save_button, load_dropdown),
                row(datatable_ref, datatable_str),
                calib_const_div,
                fit_eq_div,
            ),
        ))

    return Panel(child=tab_layout, title="eTOF Calibration")
예제 #3
0
def create():
    det_data = []
    fit_params = {}
    js_data = ColumnDataSource(data=dict(content=["", ""], fname=["", ""]))

    def proposal_textinput_callback(_attr, _old, new):
        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((".ccl", ".dat")):
                file_list.append((os.path.join(proposal_path, file), file))
        file_select.options = file_list
        file_open_button.disabled = False
        file_append_button.disabled = False

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

    def _init_datatable():
        scan_list = [s["idx"] for s in det_data]
        file_list = []
        for scan in det_data:
            file_list.append(os.path.basename(scan["original_filename"]))

        scan_table_source.data.update(
            file=file_list,
            scan=scan_list,
            param=[None] * len(scan_list),
            fit=[0] * len(scan_list),
            export=[True] * len(scan_list),
        )
        scan_table_source.selected.indices = []
        scan_table_source.selected.indices = [0]

        scan_motor_select.options = det_data[0]["scan_motors"]
        scan_motor_select.value = det_data[0]["scan_motor"]
        param_select.value = "user defined"

    file_select = MultiSelect(title="Available .ccl/.dat files:",
                              width=210,
                              height=250)

    def file_open_button_callback():
        nonlocal det_data
        det_data = []
        for f_name in file_select.value:
            with open(f_name) as file:
                base, ext = os.path.splitext(f_name)
                if det_data:
                    append_data = pyzebra.parse_1D(file, ext)
                    pyzebra.normalize_dataset(append_data,
                                              monitor_spinner.value)
                    det_data.extend(append_data)
                else:
                    det_data = pyzebra.parse_1D(file, ext)
                    pyzebra.normalize_dataset(det_data, monitor_spinner.value)
                    js_data.data.update(
                        fname=[base + ".comm", base + ".incomm"])

        _init_datatable()
        append_upload_button.disabled = False

    file_open_button = Button(label="Open New", width=100, disabled=True)
    file_open_button.on_click(file_open_button_callback)

    def file_append_button_callback():
        for f_name in file_select.value:
            with open(f_name) as file:
                _, ext = os.path.splitext(f_name)
                append_data = pyzebra.parse_1D(file, ext)

            pyzebra.normalize_dataset(append_data, monitor_spinner.value)
            det_data.extend(append_data)

        _init_datatable()

    file_append_button = Button(label="Append", width=100, disabled=True)
    file_append_button.on_click(file_append_button_callback)

    def upload_button_callback(_attr, _old, new):
        nonlocal det_data
        det_data = []
        for f_str, f_name in zip(new, upload_button.filename):
            with io.StringIO(base64.b64decode(f_str).decode()) as file:
                base, ext = os.path.splitext(f_name)
                if det_data:
                    append_data = pyzebra.parse_1D(file, ext)
                    pyzebra.normalize_dataset(append_data,
                                              monitor_spinner.value)
                    det_data.extend(append_data)
                else:
                    det_data = pyzebra.parse_1D(file, ext)
                    pyzebra.normalize_dataset(det_data, monitor_spinner.value)
                    js_data.data.update(
                        fname=[base + ".comm", base + ".incomm"])

        _init_datatable()
        append_upload_button.disabled = False

    upload_div = Div(text="or upload new .ccl/.dat files:",
                     margin=(5, 5, 0, 5))
    upload_button = FileInput(accept=".ccl,.dat", multiple=True, width=200)
    upload_button.on_change("value", upload_button_callback)

    def append_upload_button_callback(_attr, _old, new):
        for f_str, f_name in zip(new, append_upload_button.filename):
            with io.StringIO(base64.b64decode(f_str).decode()) as file:
                _, ext = os.path.splitext(f_name)
                append_data = pyzebra.parse_1D(file, ext)

            pyzebra.normalize_dataset(append_data, monitor_spinner.value)
            det_data.extend(append_data)

        _init_datatable()

    append_upload_div = Div(text="append extra files:", margin=(5, 5, 0, 5))
    append_upload_button = FileInput(accept=".ccl,.dat",
                                     multiple=True,
                                     width=200,
                                     disabled=True)
    append_upload_button.on_change("value", append_upload_button_callback)

    def monitor_spinner_callback(_attr, _old, new):
        if det_data:
            pyzebra.normalize_dataset(det_data, new)
            _update_plot()

    monitor_spinner = Spinner(title="Monitor:",
                              mode="int",
                              value=100_000,
                              low=1,
                              width=145)
    monitor_spinner.on_change("value", monitor_spinner_callback)

    def scan_motor_select_callback(_attr, _old, new):
        if det_data:
            for scan in det_data:
                scan["scan_motor"] = new
            _update_plot()

    scan_motor_select = Select(title="Scan motor:", options=[], width=145)
    scan_motor_select.on_change("value", scan_motor_select_callback)

    def _update_table():
        fit_ok = [(1 if "fit" in scan else 0) for scan in det_data]
        scan_table_source.data.update(fit=fit_ok)

    def _update_plot():
        _update_single_scan_plot(_get_selected_scan())
        _update_overview()

    def _update_single_scan_plot(scan):
        scan_motor = scan["scan_motor"]

        y = scan["counts"]
        x = scan[scan_motor]

        plot.axis[0].axis_label = scan_motor
        plot_scatter_source.data.update(x=x,
                                        y=y,
                                        y_upper=y + np.sqrt(y),
                                        y_lower=y - np.sqrt(y))

        fit = scan.get("fit")
        if fit is not None:
            x_fit = np.linspace(x[0], x[-1], 100)
            plot_fit_source.data.update(x=x_fit, y=fit.eval(x=x_fit))

            x_bkg = []
            y_bkg = []
            xs_peak = []
            ys_peak = []
            comps = fit.eval_components(x=x_fit)
            for i, model in enumerate(fit_params):
                if "linear" in model:
                    x_bkg = x_fit
                    y_bkg = comps[f"f{i}_"]

                elif any(val in model
                         for val in ("gaussian", "voigt", "pvoigt")):
                    xs_peak.append(x_fit)
                    ys_peak.append(comps[f"f{i}_"])

            plot_bkg_source.data.update(x=x_bkg, y=y_bkg)
            plot_peak_source.data.update(xs=xs_peak, ys=ys_peak)

            fit_output_textinput.value = fit.fit_report()

        else:
            plot_fit_source.data.update(x=[], y=[])
            plot_bkg_source.data.update(x=[], y=[])
            plot_peak_source.data.update(xs=[], ys=[])
            fit_output_textinput.value = ""

    def _update_overview():
        xs = []
        ys = []
        param = []
        x = []
        y = []
        par = []
        for s, p in enumerate(scan_table_source.data["param"]):
            if p is not None:
                scan = det_data[s]
                scan_motor = scan["scan_motor"]
                xs.append(scan[scan_motor])
                x.extend(scan[scan_motor])
                ys.append(scan["counts"])
                y.extend([float(p)] * len(scan[scan_motor]))
                param.append(float(p))
                par.extend(scan["counts"])

        if det_data:
            scan_motor = det_data[0]["scan_motor"]
            ov_plot.axis[0].axis_label = scan_motor
            ov_param_plot.axis[0].axis_label = scan_motor

        ov_plot_mline_source.data.update(xs=xs,
                                         ys=ys,
                                         param=param,
                                         color=color_palette(len(xs)))

        if y:
            mapper["transform"].low = np.min([np.min(y) for y in ys])
            mapper["transform"].high = np.max([np.max(y) for y in ys])
        ov_param_plot_scatter_source.data.update(x=x, y=y, param=par)

        if y:
            interp_f = interpolate.interp2d(x, y, par)
            x1, x2 = min(x), max(x)
            y1, y2 = min(y), max(y)
            image = interp_f(
                np.linspace(x1, x2, ov_param_plot.inner_width // 10),
                np.linspace(y1, y2, ov_param_plot.inner_height // 10),
                assume_sorted=True,
            )
            ov_param_plot_image_source.data.update(image=[image],
                                                   x=[x1],
                                                   y=[y1],
                                                   dw=[x2 - x1],
                                                   dh=[y2 - y1])
        else:
            ov_param_plot_image_source.data.update(image=[],
                                                   x=[],
                                                   y=[],
                                                   dw=[],
                                                   dh=[])

    def _update_param_plot():
        x = []
        y = []
        fit_param = fit_param_select.value
        for s, p in zip(det_data, scan_table_source.data["param"]):
            if "fit" in s and fit_param:
                x.append(p)
                y.append(s["fit"].values[fit_param])

        param_plot_scatter_source.data.update(x=x, y=y)

    # Main plot
    plot = Plot(
        x_range=DataRange1d(),
        y_range=DataRange1d(only_visible=True),
        plot_height=450,
        plot_width=700,
    )

    plot.add_layout(LinearAxis(axis_label="Counts"), place="left")
    plot.add_layout(LinearAxis(axis_label="Scan motor"), place="below")

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

    plot_scatter_source = ColumnDataSource(
        dict(x=[0], y=[0], y_upper=[0], y_lower=[0]))
    plot_scatter = plot.add_glyph(
        plot_scatter_source, Scatter(x="x", y="y", line_color="steelblue"))
    plot.add_layout(
        Whisker(source=plot_scatter_source,
                base="x",
                upper="y_upper",
                lower="y_lower"))

    plot_fit_source = ColumnDataSource(dict(x=[0], y=[0]))
    plot_fit = plot.add_glyph(plot_fit_source, Line(x="x", y="y"))

    plot_bkg_source = ColumnDataSource(dict(x=[0], y=[0]))
    plot_bkg = plot.add_glyph(
        plot_bkg_source,
        Line(x="x", y="y", line_color="green", line_dash="dashed"))

    plot_peak_source = ColumnDataSource(dict(xs=[[0]], ys=[[0]]))
    plot_peak = plot.add_glyph(
        plot_peak_source,
        MultiLine(xs="xs", ys="ys", line_color="red", line_dash="dashed"))

    fit_from_span = Span(location=None, dimension="height", line_dash="dashed")
    plot.add_layout(fit_from_span)

    fit_to_span = Span(location=None, dimension="height", line_dash="dashed")
    plot.add_layout(fit_to_span)

    plot.add_layout(
        Legend(
            items=[
                ("data", [plot_scatter]),
                ("best fit", [plot_fit]),
                ("peak", [plot_peak]),
                ("linear", [plot_bkg]),
            ],
            location="top_left",
            click_policy="hide",
        ))

    plot.add_tools(PanTool(), WheelZoomTool(), ResetTool())
    plot.toolbar.logo = None

    # Overview multilines plot
    ov_plot = Plot(x_range=DataRange1d(),
                   y_range=DataRange1d(),
                   plot_height=450,
                   plot_width=700)

    ov_plot.add_layout(LinearAxis(axis_label="Counts"), place="left")
    ov_plot.add_layout(LinearAxis(axis_label="Scan motor"), place="below")

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

    ov_plot_mline_source = ColumnDataSource(
        dict(xs=[], ys=[], param=[], color=[]))
    ov_plot.add_glyph(ov_plot_mline_source,
                      MultiLine(xs="xs", ys="ys", line_color="color"))

    hover_tool = HoverTool(tooltips=[("param", "@param")])
    ov_plot.add_tools(PanTool(), WheelZoomTool(), hover_tool, ResetTool())

    ov_plot.add_tools(PanTool(), WheelZoomTool(), ResetTool())
    ov_plot.toolbar.logo = None

    # Overview perams plot
    ov_param_plot = Plot(x_range=DataRange1d(),
                         y_range=DataRange1d(),
                         plot_height=450,
                         plot_width=700)

    ov_param_plot.add_layout(LinearAxis(axis_label="Param"), place="left")
    ov_param_plot.add_layout(LinearAxis(axis_label="Scan motor"),
                             place="below")

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

    ov_param_plot_image_source = ColumnDataSource(
        dict(image=[], x=[], y=[], dw=[], dh=[]))
    ov_param_plot.add_glyph(
        ov_param_plot_image_source,
        Image(image="image", x="x", y="y", dw="dw", dh="dh"))

    ov_param_plot_scatter_source = ColumnDataSource(dict(x=[], y=[], param=[]))
    mapper = linear_cmap(field_name="param", palette=Turbo256, low=0, high=50)
    ov_param_plot.add_glyph(
        ov_param_plot_scatter_source,
        Scatter(x="x", y="y", line_color=mapper, fill_color=mapper, size=10),
    )

    ov_param_plot.add_tools(PanTool(), WheelZoomTool(), ResetTool())
    ov_param_plot.toolbar.logo = None

    # Parameter plot
    param_plot = Plot(x_range=DataRange1d(),
                      y_range=DataRange1d(),
                      plot_height=400,
                      plot_width=700)

    param_plot.add_layout(LinearAxis(axis_label="Fit parameter"), place="left")
    param_plot.add_layout(LinearAxis(axis_label="Parameter"), place="below")

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

    param_plot_scatter_source = ColumnDataSource(dict(x=[], y=[]))
    param_plot.add_glyph(param_plot_scatter_source, Scatter(x="x", y="y"))

    param_plot.add_tools(PanTool(), WheelZoomTool(), ResetTool())
    param_plot.toolbar.logo = None

    def fit_param_select_callback(_attr, _old, _new):
        _update_param_plot()

    fit_param_select = Select(title="Fit parameter", options=[], width=145)
    fit_param_select.on_change("value", fit_param_select_callback)

    # Plot tabs
    plots = Tabs(tabs=[
        Panel(child=plot, title="single scan"),
        Panel(child=ov_plot, title="overview"),
        Panel(child=ov_param_plot, title="overview map"),
        Panel(child=column(param_plot, row(fit_param_select)),
              title="parameter plot"),
    ])

    # Scan select
    def scan_table_select_callback(_attr, old, new):
        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
            scan_table_source.selected.indices = old
            return

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

        _update_plot()

    def scan_table_source_callback(_attr, _old, _new):
        _update_preview()

    scan_table_source = ColumnDataSource(
        dict(file=[], scan=[], param=[], fit=[], export=[]))
    scan_table_source.on_change("data", scan_table_source_callback)

    scan_table = DataTable(
        source=scan_table_source,
        columns=[
            TableColumn(field="file", title="file", width=150),
            TableColumn(field="scan", title="scan", width=50),
            TableColumn(field="param",
                        title="param",
                        editor=NumberEditor(),
                        width=50),
            TableColumn(field="fit", title="Fit", width=50),
            TableColumn(field="export",
                        title="Export",
                        editor=CheckboxEditor(),
                        width=50),
        ],
        width=410,  # +60 because of the index column
        editable=True,
        autosize_mode="none",
    )

    def scan_table_source_callback(_attr, _old, _new):
        if scan_table_source.selected.indices:
            _update_plot()

    scan_table_source.selected.on_change("indices", scan_table_select_callback)
    scan_table_source.on_change("data", scan_table_source_callback)

    def _get_selected_scan():
        return det_data[scan_table_source.selected.indices[0]]

    def param_select_callback(_attr, _old, new):
        if new == "user defined":
            param = [None] * len(det_data)
        else:
            param = [scan[new] for scan in det_data]

        scan_table_source.data["param"] = param
        _update_param_plot()

    param_select = Select(
        title="Parameter:",
        options=["user defined", "temp", "mf", "h", "k", "l"],
        value="user defined",
        width=145,
    )
    param_select.on_change("value", param_select_callback)

    def fit_from_spinner_callback(_attr, _old, new):
        fit_from_span.location = new

    fit_from_spinner = Spinner(title="Fit from:", width=145)
    fit_from_spinner.on_change("value", fit_from_spinner_callback)

    def fit_to_spinner_callback(_attr, _old, new):
        fit_to_span.location = new

    fit_to_spinner = Spinner(title="to:", width=145)
    fit_to_spinner.on_change("value", fit_to_spinner_callback)

    def fitparams_add_dropdown_callback(click):
        # bokeh requires (str, str) for MultiSelect options
        new_tag = f"{click.item}-{fitparams_select.tags[0]}"
        fitparams_select.options.append((new_tag, click.item))
        fit_params[new_tag] = fitparams_factory(click.item)
        fitparams_select.tags[0] += 1

    fitparams_add_dropdown = Dropdown(
        label="Add fit function",
        menu=[
            ("Linear", "linear"),
            ("Gaussian", "gaussian"),
            ("Voigt", "voigt"),
            ("Pseudo Voigt", "pvoigt"),
            # ("Pseudo Voigt1", "pseudovoigt1"),
        ],
        width=145,
    )
    fitparams_add_dropdown.on_click(fitparams_add_dropdown_callback)

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

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

        if new:
            fitparams_table_source.data.update(fit_params[new[0]])
        else:
            fitparams_table_source.data.update(
                dict(param=[], value=[], vary=[], min=[], max=[]))

    fitparams_select = MultiSelect(options=[], height=120, width=145)
    fitparams_select.tags = [0]
    fitparams_select.on_change("value", fitparams_select_callback)

    def fitparams_remove_button_callback():
        if fitparams_select.value:
            sel_tag = fitparams_select.value[0]
            del fit_params[sel_tag]
            for elem in fitparams_select.options:
                if elem[0] == sel_tag:
                    fitparams_select.options.remove(elem)
                    break

            fitparams_select.value = []

    fitparams_remove_button = Button(label="Remove fit function", width=145)
    fitparams_remove_button.on_click(fitparams_remove_button_callback)

    def fitparams_factory(function):
        if function == "linear":
            params = ["slope", "intercept"]
        elif function == "gaussian":
            params = ["amplitude", "center", "sigma"]
        elif function == "voigt":
            params = ["amplitude", "center", "sigma", "gamma"]
        elif function == "pvoigt":
            params = ["amplitude", "center", "sigma", "fraction"]
        elif function == "pseudovoigt1":
            params = ["amplitude", "center", "g_sigma", "l_sigma", "fraction"]
        else:
            raise ValueError("Unknown fit function")

        n = len(params)
        fitparams = dict(
            param=params,
            value=[None] * n,
            vary=[True] * n,
            min=[None] * n,
            max=[None] * n,
        )

        if function == "linear":
            fitparams["value"] = [0, 1]
            fitparams["vary"] = [False, True]
            fitparams["min"] = [None, 0]

        elif function == "gaussian":
            fitparams["min"] = [0, None, None]

        return fitparams

    fitparams_table_source = ColumnDataSource(
        dict(param=[], value=[], vary=[], min=[], max=[]))
    fitparams_table = DataTable(
        source=fitparams_table_source,
        columns=[
            TableColumn(field="param", title="Parameter"),
            TableColumn(field="value", title="Value", editor=NumberEditor()),
            TableColumn(field="vary", title="Vary", editor=CheckboxEditor()),
            TableColumn(field="min", title="Min", editor=NumberEditor()),
            TableColumn(field="max", title="Max", editor=NumberEditor()),
        ],
        height=200,
        width=350,
        index_position=None,
        editable=True,
        auto_edit=True,
    )

    # start with `background` and `gauss` fit functions added
    fitparams_add_dropdown_callback(types.SimpleNamespace(item="linear"))
    fitparams_add_dropdown_callback(types.SimpleNamespace(item="gaussian"))
    fitparams_select.value = ["gaussian-1"]  # add selection to gauss

    fit_output_textinput = TextAreaInput(title="Fit results:",
                                         width=750,
                                         height=200)

    def proc_all_button_callback():
        for scan, export in zip(det_data, scan_table_source.data["export"]):
            if export:
                pyzebra.fit_scan(scan,
                                 fit_params,
                                 fit_from=fit_from_spinner.value,
                                 fit_to=fit_to_spinner.value)
                pyzebra.get_area(
                    scan,
                    area_method=AREA_METHODS[area_method_radiobutton.active],
                    lorentz=lorentz_checkbox.active,
                )

        _update_plot()
        _update_table()

        for scan in det_data:
            if "fit" in scan:
                options = list(scan["fit"].params.keys())
                fit_param_select.options = options
                fit_param_select.value = options[0]
                break
        _update_param_plot()

    proc_all_button = Button(label="Process All",
                             button_type="primary",
                             width=145)
    proc_all_button.on_click(proc_all_button_callback)

    def proc_button_callback():
        scan = _get_selected_scan()
        pyzebra.fit_scan(scan,
                         fit_params,
                         fit_from=fit_from_spinner.value,
                         fit_to=fit_to_spinner.value)
        pyzebra.get_area(
            scan,
            area_method=AREA_METHODS[area_method_radiobutton.active],
            lorentz=lorentz_checkbox.active,
        )

        _update_plot()
        _update_table()

        for scan in det_data:
            if "fit" in scan:
                options = list(scan["fit"].params.keys())
                fit_param_select.options = options
                fit_param_select.value = options[0]
                break
        _update_param_plot()

    proc_button = Button(label="Process Current", width=145)
    proc_button.on_click(proc_button_callback)

    area_method_div = Div(text="Intensity:", margin=(5, 5, 0, 5))
    area_method_radiobutton = RadioGroup(labels=["Function", "Area"],
                                         active=0,
                                         width=145)

    lorentz_checkbox = CheckboxGroup(labels=["Lorentz Correction"],
                                     width=145,
                                     margin=(13, 5, 5, 5))

    export_preview_textinput = TextAreaInput(title="Export file preview:",
                                             width=450,
                                             height=400)

    def _update_preview():
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_file = temp_dir + "/temp"
            export_data = []
            for s, export in zip(det_data, scan_table_source.data["export"]):
                if export:
                    export_data.append(s)

            # pyzebra.export_1D(export_data, temp_file, "fullprof")

            exported_content = ""
            file_content = []
            for ext in (".comm", ".incomm"):
                fname = temp_file + ext
                if os.path.isfile(fname):
                    with open(fname) as f:
                        content = f.read()
                        exported_content += f"{ext} file:\n" + content
                else:
                    content = ""
                file_content.append(content)

            js_data.data.update(content=file_content)
            export_preview_textinput.value = exported_content

    save_button = Button(label="Download File(s)",
                         button_type="success",
                         width=220)
    save_button.js_on_click(
        CustomJS(args={"js_data": js_data}, code=javaScript))

    fitpeak_controls = row(
        column(fitparams_add_dropdown, fitparams_select,
               fitparams_remove_button),
        fitparams_table,
        Spacer(width=20),
        column(fit_from_spinner, lorentz_checkbox, area_method_div,
               area_method_radiobutton),
        column(fit_to_spinner, proc_button, proc_all_button),
    )

    scan_layout = column(scan_table,
                         row(monitor_spinner, scan_motor_select, param_select))

    import_layout = column(
        proposal_textinput,
        file_select,
        row(file_open_button, file_append_button),
        upload_div,
        upload_button,
        append_upload_div,
        append_upload_button,
    )

    export_layout = column(export_preview_textinput, row(save_button))

    tab_layout = column(
        row(import_layout, scan_layout, plots, Spacer(width=30),
            export_layout),
        row(fitpeak_controls, fit_output_textinput),
    )

    return Panel(child=tab_layout, title="param study")
예제 #4
0
    def create(self):
        manufacturers = sorted(mpg["manufacturer"].unique())
        models = sorted(mpg["model"].unique())
        transmissions = sorted(mpg["trans"].unique())
        drives = sorted(mpg["drv"].unique())
        classes = sorted(mpg["class"].unique())

        manufacturer_select = Select(title="Manufacturer:", value="All", options=["All"] + manufacturers)
        manufacturer_select.on_change('value', self.on_manufacturer_change)
        model_select = Select(title="Model:", value="All", options=["All"] + models)
        model_select.on_change('value', self.on_model_change)
        transmission_select = Select(title="Transmission:", value="All", options=["All"] + transmissions)
        transmission_select.on_change('value', self.on_transmission_change)
        drive_select = Select(title="Drive:", value="All", options=["All"] + drives)
        drive_select.on_change('value', self.on_drive_change)
        class_select = Select(title="Class:", value="All", options=["All"] + classes)
        class_select.on_change('value', self.on_class_change)

        columns = [
            TableColumn(field="manufacturer", title="Manufacturer", editor=SelectEditor(options=manufacturers), formatter=StringFormatter(font_style="bold")),
            TableColumn(field="model",        title="Model",        editor=StringEditor(completions=models)),
            TableColumn(field="displ",        title="Displacement", editor=NumberEditor(step=0.1),              formatter=NumberFormatter(format="0.0")),
            TableColumn(field="year",         title="Year",         editor=IntEditor()),
            TableColumn(field="cyl",          title="Cylinders",    editor=IntEditor()),
            TableColumn(field="trans",        title="Transmission", editor=SelectEditor(options=transmissions)),
            TableColumn(field="drv",          title="Drive",        editor=SelectEditor(options=drives)),
            TableColumn(field="class",        title="Class",        editor=SelectEditor(options=classes)),
            TableColumn(field="cty",          title="City MPG",     editor=IntEditor()),
            TableColumn(field="hwy",          title="Highway MPG",  editor=IntEditor()),
        ]
        data_table = DataTable(source=self.source, columns=columns, editable=True)

        plot = Plot(title=None, x_range= DataRange1d(), y_range=DataRange1d(), plot_width=1000, plot_height=300)

        # Set up x & y axis
        plot.add_layout(LinearAxis(), 'below')
        yaxis = LinearAxis()
        plot.add_layout(yaxis, 'left')
        plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))

        # Add Glyphs
        cty_glyph = Circle(x="index", y="cty", fill_color="#396285", size=8, fill_alpha=0.5, line_alpha=0.5)
        hwy_glyph = Circle(x="index", y="hwy", fill_color="#CE603D", size=8, fill_alpha=0.5, line_alpha=0.5)
        cty = plot.add_glyph(self.source, cty_glyph)
        hwy = plot.add_glyph(self.source, hwy_glyph)

        # Add the tools
        tooltips = [
            ("Manufacturer", "@manufacturer"),
            ("Model", "@model"),
            ("Displacement", "@displ"),
            ("Year", "@year"),
            ("Cylinders", "@cyl"),
            ("Transmission", "@trans"),
            ("Drive", "@drv"),
            ("Class", "@class"),
        ]
        cty_hover_tool = HoverTool(renderers=[cty], tooltips=tooltips + [("City MPG", "@cty")])
        hwy_hover_tool = HoverTool(renderers=[hwy], tooltips=tooltips + [("Highway MPG", "@hwy")])
        select_tool = BoxSelectTool(renderers=[cty, hwy], dimensions=['width'])
        plot.add_tools(cty_hover_tool, hwy_hover_tool, select_tool)


        controls = VBox(children=[
            manufacturer_select, model_select, transmission_select,
             drive_select, class_select])
        top_panel = HBox(children=[controls, plot])
        layout = VBox(children=[top_panel, data_table])

        return layout
예제 #5
0
from bokeh.embed import file_html
from bokeh.models import (Circle, ColumnDataSource, CrosshairTool, CustomJS,
                          Grid, HoverTool, Legend, LegendItem, Line,
                          LinearAxis, Plot, Range1d, TapTool, WheelZoomTool)
from bokeh.resources import INLINE
from bokeh.util.browser import view

plot = Plot(x_range=Range1d(-10, 10),
            y_range=Range1d(-10, 10),
            plot_width=600,
            plot_height=600,
            toolbar_sticky=False)

xaxis = LinearAxis()
yaxis = LinearAxis()
xgrid = Grid(dimension=0, ticker=xaxis.ticker)
ygrid = Grid(dimension=1, ticker=yaxis.ticker)

plot.add_layout(xaxis, "below")
plot.add_layout(yaxis, "left")
plot.add_layout(xgrid)
plot.add_layout(ygrid)


def fds(x, y, e, n):
    d = [
        (x + 0 * e, y + 0 * e, 1, "red", "%s00" % n),
        (x + 1 * e, y + 1 * e, 1, "blue", "%s01" % n),
        (x + 2 * e, y + 2 * e, 1, "green", "%s02" % n),
        (x + 3 * e, y + 3 * e, 1, "violet", "%s03" % n),
        (x + 4 * e, y + 4 * e, 1, "pink", "%s04" % n),
예제 #6
0
def large_plot(n):
    from bokeh.models import (Plot, LinearAxis, Grid, GlyphRenderer,
                              ColumnDataSource, DataRange1d, PanTool,
                              ZoomInTool, ZoomOutTool, WheelZoomTool,
                              BoxZoomTool, BoxSelectTool, SaveTool, ResetTool)
    from bokeh.models.layouts import Column
    from bokeh.models.glyphs import Line

    col = Column()
    objects = set([col])

    for i in xrange(n):
        source = ColumnDataSource(data=dict(x=[0, i + 1], y=[0, i + 1]))
        xdr = DataRange1d()
        ydr = DataRange1d()
        plot = Plot(x_range=xdr, y_range=ydr)
        xaxis = LinearAxis(plot=plot)
        yaxis = LinearAxis(plot=plot)
        xgrid = Grid(plot=plot, dimension=0)
        ygrid = Grid(plot=plot, dimension=1)
        tickers = [
            xaxis.ticker, xaxis.formatter, yaxis.ticker, yaxis.formatter
        ]
        glyph = Line(x='x', y='y')
        renderer = GlyphRenderer(data_source=source, glyph=glyph)
        plot.renderers.append(renderer)
        pan = PanTool()
        zoom_in = ZoomInTool()
        zoom_out = ZoomOutTool()
        wheel_zoom = WheelZoomTool()
        box_zoom = BoxZoomTool()
        box_select = BoxSelectTool()
        save = SaveTool()
        reset = ResetTool()
        tools = [
            pan, zoom_in, zoom_out, wheel_zoom, box_zoom, box_select, save,
            reset
        ]
        plot.add_tools(*tools)
        col.children.append(plot)
        objects |= set([
            xdr,
            ydr,
            xaxis,
            yaxis,
            xgrid,
            ygrid,
            renderer,
            renderer.view,
            glyph,
            source,
            source.selected,
            source.selection_policy,
            plot,
            plot.x_scale,
            plot.y_scale,
            plot.toolbar,
            plot.title,
            box_zoom.overlay,
            box_select.overlay,
        ] + tickers + tools)

    return col, objects
예제 #7
0
def create_bar_chart(data, title, hover_tool, colors):
    """Creates a bar chart plot with the exact styling for the centcom
       dashboard. Pass in data as a dictionary, desired plot title,
       name of x axis, y axis and the hover tool HTML.
    """

    xdr = DataRange1d(bounds='auto')
    ydr = DataRange1d(bounds='auto')

    hover = HoverTool(tooltips="""
            <div>
            	<p><span style="font-weight: bold;">%s</span> - %s</p>
				<p>%s million %s passengers</p>
			</div>
    	""" % ("@airline", "@date{%b %Y}", "$y", "$name"),
                      formatters={'date': 'datetime'},
                      names=['domestic', 'international', 'total'])

    tools = [
        hover, 'pan', 'box_zoom', 'zoom_in', 'zoom_out', 'wheel_zoom', 'reset'
    ]

    plot = figure(title=title,
                  x_range=xdr,
                  y_range=ydr,
                  plot_width=1200,
                  plot_height=800,
                  h_symmetry=False,
                  v_symmetry=False,
                  min_border=0,
                  toolbar_location="above",
                  tools=tools,
                  outline_line_color="#666666",
                  x_axis_type='datetime',
                  border_fill_color='#DBECFC')

    plot.left[0].formatter.use_scientific = False

    legendItems = []

    for airline in data:

        color = colors[airline]
        source = ColumnDataSource(data=data[airline])
        legendItems.append(([airline,
                             "Domestic"], (plot.line(x='date',
                                                     y='domestic',
                                                     line_color=color,
                                                     line_width=2,
                                                     line_alpha=0.6,
                                                     line_dash='dashed',
                                                     source=source))))
        legendItems.append(([airline, "Domestic"],
                            plot.circle(x='date',
                                        y='domestic',
                                        size=5,
                                        fill_color=color,
                                        source=source,
                                        name='domestic',
                                        line_color=color)))
        legendItems[-1][1].hover_glyph = Circle(line_width=6,
                                                line_color=color,
                                                line_alpha=0.2,
                                                fill_color=color)

        source = ColumnDataSource(data=data[airline])
        legendItems.append(([airline, "Total"],
                            plot.line(x='date',
                                      y='total',
                                      line_color=color,
                                      line_width=2,
                                      line_alpha=0.6,
                                      source=source)))
        legendItems.append(([airline, "Total"],
                            plot.circle(x='date',
                                        y='total',
                                        size=8,
                                        fill_color=color,
                                        line_color=color,
                                        source=source,
                                        name='total')))
        legendItems[-1][1].hover_glyph = Circle(line_width=9,
                                                line_color=color,
                                                line_alpha=0.2,
                                                fill_color=color)

        source = ColumnDataSource(data=data[airline])
        legendItems.append(([airline, "International"],
                            plot.line(x='date',
                                      y='international',
                                      line_color=color,
                                      line_width=2,
                                      line_alpha=0.6,
                                      line_dash='dotted',
                                      source=source)))
        legendItems.append(([airline, "International"],
                            plot.circle(x='date',
                                        y='international',
                                        size=5,
                                        fill_color=color,
                                        line_color=color,
                                        source=source,
                                        name='international')))
        legendItems[-1][1].hover_glyph = Circle(line_width=6,
                                                line_color=color,
                                                line_alpha=0.2,
                                                fill_color=color)

#Create legend for airline
    legendAirlines = CategorialLegend(items=legendItems, click_policy='hide')
    plot.add_layout(legendAirlines, 'right')

    xaxis = LinearAxis()
    yaxis = LinearAxis()

    plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
    plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
    plot.toolbar.logo = None
    plot.min_border_top = 0
    plot.xgrid.grid_line_color = None
    plot.ygrid.grid_line_color = "#999999"
    plot.ygrid.grid_line_alpha = 0.1

    #Style Y axis
    plot.yaxis.axis_label = "Number of Passengers (Millions)"
    plot.yaxis.axis_label_text_font_size = '12pt'
    plot.yaxis.axis_label_text_font_style = 'normal'

    #Style X axis
    plot.xaxis.axis_label = "Year"
    plot.xaxis.major_label_orientation = 1
    plot.xaxis.axis_label_text_font_size = '12pt'
    plot.xaxis.axis_label_text_font_style = 'normal'
    plot.xaxis[0].formatter.days = '%b %Y'

    return plot
예제 #8
0
def generate_stacked_chart(data: dict,
                           text: dict,
                           width=1200,
                           height=800,
                           chart_type: str = 'Column'):
    months = data['months']
    energy_types = [key for key in sorted(data.keys()) if key != "months"]
    if len(energy_types) == 2:
        colors = ["red", "green"]
    elif len(energy_types) == 4:
        colors = ["orange", "red", "blue", "green"]
    else:
        colors = ['red']

    tools = ["pan", "wheel_zoom,save,reset"]

    plot = figure(title=text['title'],
                  x_range=months,
                  plot_height=height,
                  plot_width=width,
                  h_symmetry=False,
                  v_symmetry=False,
                  min_border=0,
                  toolbar_location="above",
                  tools=tools,
                  sizing_mode='scale_width',
                  outline_line_color="#666666",
                  active_scroll='wheel_zoom',
                  active_drag='pan')
    if chart_type == 'Column':
        source = ColumnDataSource(data)
        renderers = plot.vbar_stack(energy_types,
                                    x='months',
                                    width=0.8,
                                    color=colors,
                                    source=source,
                                    legend=[item for item in text['legend']]
                                    if text.get('legend') else None)

        for r in renderers:
            item = r.name
            tooltips = [("Koszt: ", "@%s{0.00} zł" % item),
                        ("Miesiąc: ", "@months")]
            if text.get("tooltip", None):
                additional_tooltips = [
                    ("{}: ".format(text["tooltip"]["energy_type"]["label"]),
                     text["tooltip"]["energy_type"]["value"]),
                    ("{}: ".format(text["tooltip"]["building"]["label"]),
                     text["tooltip"]["building"]["value"])
                ]
                for t in additional_tooltips:
                    tooltips.insert(0, t)
            hover = HoverTool(tooltips=tooltips, renderers=[r])
            plot.add_tools(hover)

    elif chart_type == 'Line':
        r = plot.multi_line(
            [[month for month in months] for item in energy_types],
            [data[type_energy] for type_energy in energy_types],
            color=colors,
            line_width=4)
        if text.get('legend', None):
            legend = Legend(items=[
                LegendItem(label=item, renderers=[r], index=index)
                for index, item in enumerate(text['legend'])
            ])

            plot.add_layout(legend)

    xaxis = LinearAxis()
    yaxis = LinearAxis()
    plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
    plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
    plot.title.text_font_size = '12pt'
    plot.toolbar.logo = None
    plot.min_border_top = 0
    plot.xgrid.grid_line_color = None
    plot.ygrid.grid_line_color = "#999999"
    plot.yaxis.axis_label = text['title']
    plot.ygrid.grid_line_alpha = 0.1
    plot.xaxis.axis_label = "Miesiąc"
    plot.xaxis.axis_label_text_font_size = "11pt"
    plot.xaxis.major_label_orientation = 1
    return plot
예제 #9
0
def create():
    det_data = {}
    fit_params = {}
    js_data = ColumnDataSource(
        data=dict(content=["", ""], fname=["", ""], ext=["", ""]))

    def proposal_textinput_callback(_attr, _old, new):
        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((".ccl", ".dat")):
                file_list.append((os.path.join(proposal_path, file), file))
        file_select.options = file_list
        file_open_button.disabled = False
        file_append_button.disabled = False

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

    def _init_datatable():
        scan_list = [s["idx"] for s in det_data]
        hkl = [f'{s["h"]} {s["k"]} {s["l"]}' for s in det_data]
        export = [s.get("active", True) for s in det_data]
        scan_table_source.data.update(
            scan=scan_list,
            hkl=hkl,
            fit=[0] * len(scan_list),
            export=export,
        )
        scan_table_source.selected.indices = []
        scan_table_source.selected.indices = [0]

        merge_options = [(str(i), f"{i} ({idx})")
                         for i, idx in enumerate(scan_list)]
        merge_from_select.options = merge_options
        merge_from_select.value = merge_options[0][0]

    file_select = MultiSelect(title="Available .ccl/.dat files:",
                              width=210,
                              height=250)

    def file_open_button_callback():
        nonlocal det_data
        det_data = []
        for f_name in file_select.value:
            with open(f_name) as file:
                base, ext = os.path.splitext(f_name)
                if det_data:
                    append_data = pyzebra.parse_1D(file, ext)
                    pyzebra.normalize_dataset(append_data,
                                              monitor_spinner.value)
                    pyzebra.merge_datasets(det_data, append_data)
                else:
                    det_data = pyzebra.parse_1D(file, ext)
                    pyzebra.normalize_dataset(det_data, monitor_spinner.value)
                    pyzebra.merge_duplicates(det_data)
                    js_data.data.update(fname=[base, base])

        _init_datatable()
        append_upload_button.disabled = False

    file_open_button = Button(label="Open New", width=100, disabled=True)
    file_open_button.on_click(file_open_button_callback)

    def file_append_button_callback():
        for f_name in file_select.value:
            with open(f_name) as file:
                _, ext = os.path.splitext(f_name)
                append_data = pyzebra.parse_1D(file, ext)

            pyzebra.normalize_dataset(append_data, monitor_spinner.value)
            pyzebra.merge_datasets(det_data, append_data)

        _init_datatable()

    file_append_button = Button(label="Append", width=100, disabled=True)
    file_append_button.on_click(file_append_button_callback)

    def upload_button_callback(_attr, _old, new):
        nonlocal det_data
        det_data = []
        for f_str, f_name in zip(new, upload_button.filename):
            with io.StringIO(base64.b64decode(f_str).decode()) as file:
                base, ext = os.path.splitext(f_name)
                if det_data:
                    append_data = pyzebra.parse_1D(file, ext)
                    pyzebra.normalize_dataset(append_data,
                                              monitor_spinner.value)
                    pyzebra.merge_datasets(det_data, append_data)
                else:
                    det_data = pyzebra.parse_1D(file, ext)
                    pyzebra.normalize_dataset(det_data, monitor_spinner.value)
                    pyzebra.merge_duplicates(det_data)
                    js_data.data.update(fname=[base, base])

        _init_datatable()
        append_upload_button.disabled = False

    upload_div = Div(text="or upload new .ccl/.dat files:",
                     margin=(5, 5, 0, 5))
    upload_button = FileInput(accept=".ccl,.dat", multiple=True, width=200)
    upload_button.on_change("value", upload_button_callback)

    def append_upload_button_callback(_attr, _old, new):
        for f_str, f_name in zip(new, append_upload_button.filename):
            with io.StringIO(base64.b64decode(f_str).decode()) as file:
                _, ext = os.path.splitext(f_name)
                append_data = pyzebra.parse_1D(file, ext)

            pyzebra.normalize_dataset(append_data, monitor_spinner.value)
            pyzebra.merge_datasets(det_data, append_data)

        _init_datatable()

    append_upload_div = Div(text="append extra files:", margin=(5, 5, 0, 5))
    append_upload_button = FileInput(accept=".ccl,.dat",
                                     multiple=True,
                                     width=200,
                                     disabled=True)
    append_upload_button.on_change("value", append_upload_button_callback)

    def monitor_spinner_callback(_attr, old, new):
        if det_data:
            pyzebra.normalize_dataset(det_data, new)
            _update_plot(_get_selected_scan())

    monitor_spinner = Spinner(title="Monitor:",
                              mode="int",
                              value=100_000,
                              low=1,
                              width=145)
    monitor_spinner.on_change("value", monitor_spinner_callback)

    def _update_table():
        fit_ok = [(1 if "fit" in scan else 0) for scan in det_data]
        scan_table_source.data.update(fit=fit_ok)

    def _update_plot(scan):
        scan_motor = scan["scan_motor"]

        y = scan["counts"]
        x = scan[scan_motor]

        plot.axis[0].axis_label = scan_motor
        plot_scatter_source.data.update(x=x,
                                        y=y,
                                        y_upper=y + np.sqrt(y),
                                        y_lower=y - np.sqrt(y))

        fit = scan.get("fit")
        if fit is not None:
            x_fit = np.linspace(x[0], x[-1], 100)
            plot_fit_source.data.update(x=x_fit, y=fit.eval(x=x_fit))

            x_bkg = []
            y_bkg = []
            xs_peak = []
            ys_peak = []
            comps = fit.eval_components(x=x_fit)
            for i, model in enumerate(fit_params):
                if "linear" in model:
                    x_bkg = x_fit
                    y_bkg = comps[f"f{i}_"]

                elif any(val in model
                         for val in ("gaussian", "voigt", "pvoigt")):
                    xs_peak.append(x_fit)
                    ys_peak.append(comps[f"f{i}_"])

            plot_bkg_source.data.update(x=x_bkg, y=y_bkg)
            plot_peak_source.data.update(xs=xs_peak, ys=ys_peak)

            fit_output_textinput.value = fit.fit_report()

        else:
            plot_fit_source.data.update(x=[], y=[])
            plot_bkg_source.data.update(x=[], y=[])
            plot_peak_source.data.update(xs=[], ys=[])
            fit_output_textinput.value = ""

    # Main plot
    plot = Plot(
        x_range=DataRange1d(),
        y_range=DataRange1d(only_visible=True),
        plot_height=470,
        plot_width=700,
    )

    plot.add_layout(LinearAxis(axis_label="Counts"), place="left")
    plot.add_layout(LinearAxis(axis_label="Scan motor"), place="below")

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

    plot_scatter_source = ColumnDataSource(
        dict(x=[0], y=[0], y_upper=[0], y_lower=[0]))
    plot_scatter = plot.add_glyph(
        plot_scatter_source, Scatter(x="x", y="y", line_color="steelblue"))
    plot.add_layout(
        Whisker(source=plot_scatter_source,
                base="x",
                upper="y_upper",
                lower="y_lower"))

    plot_fit_source = ColumnDataSource(dict(x=[0], y=[0]))
    plot_fit = plot.add_glyph(plot_fit_source, Line(x="x", y="y"))

    plot_bkg_source = ColumnDataSource(dict(x=[0], y=[0]))
    plot_bkg = plot.add_glyph(
        plot_bkg_source,
        Line(x="x", y="y", line_color="green", line_dash="dashed"))

    plot_peak_source = ColumnDataSource(dict(xs=[[0]], ys=[[0]]))
    plot_peak = plot.add_glyph(
        plot_peak_source,
        MultiLine(xs="xs", ys="ys", line_color="red", line_dash="dashed"))

    fit_from_span = Span(location=None, dimension="height", line_dash="dashed")
    plot.add_layout(fit_from_span)

    fit_to_span = Span(location=None, dimension="height", line_dash="dashed")
    plot.add_layout(fit_to_span)

    plot.add_layout(
        Legend(
            items=[
                ("data", [plot_scatter]),
                ("best fit", [plot_fit]),
                ("peak", [plot_peak]),
                ("linear", [plot_bkg]),
            ],
            location="top_left",
            click_policy="hide",
        ))

    plot.add_tools(PanTool(), WheelZoomTool(), ResetTool())
    plot.toolbar.logo = None

    # Scan select
    def scan_table_select_callback(_attr, old, new):
        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
            scan_table_source.selected.indices = old
            return

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

        _update_plot(det_data[new[0]])

    def scan_table_source_callback(_attr, _old, _new):
        _update_preview()

    scan_table_source = ColumnDataSource(
        dict(scan=[], hkl=[], fit=[], export=[]))
    scan_table_source.on_change("data", scan_table_source_callback)

    scan_table = DataTable(
        source=scan_table_source,
        columns=[
            TableColumn(field="scan", title="Scan", width=50),
            TableColumn(field="hkl", title="hkl", width=100),
            TableColumn(field="fit", title="Fit", width=50),
            TableColumn(field="export",
                        title="Export",
                        editor=CheckboxEditor(),
                        width=50),
        ],
        width=310,  # +60 because of the index column
        height=350,
        autosize_mode="none",
        editable=True,
    )

    scan_table_source.selected.on_change("indices", scan_table_select_callback)

    def _get_selected_scan():
        return det_data[scan_table_source.selected.indices[0]]

    merge_from_select = Select(title="scan:", width=145)

    def merge_button_callback():
        scan_into = _get_selected_scan()
        scan_from = det_data[int(merge_from_select.value)]

        if scan_into is scan_from:
            print("WARNING: Selected scans for merging are identical")
            return

        pyzebra.merge_scans(scan_into, scan_from)
        _update_plot(_get_selected_scan())

    merge_button = Button(label="Merge into current", width=145)
    merge_button.on_click(merge_button_callback)

    def restore_button_callback():
        pyzebra.restore_scan(_get_selected_scan())
        _update_plot(_get_selected_scan())

    restore_button = Button(label="Restore scan", width=145)
    restore_button.on_click(restore_button_callback)

    def fit_from_spinner_callback(_attr, _old, new):
        fit_from_span.location = new

    fit_from_spinner = Spinner(title="Fit from:", width=145)
    fit_from_spinner.on_change("value", fit_from_spinner_callback)

    def fit_to_spinner_callback(_attr, _old, new):
        fit_to_span.location = new

    fit_to_spinner = Spinner(title="to:", width=145)
    fit_to_spinner.on_change("value", fit_to_spinner_callback)

    def fitparams_add_dropdown_callback(click):
        # bokeh requires (str, str) for MultiSelect options
        new_tag = f"{click.item}-{fitparams_select.tags[0]}"
        fitparams_select.options.append((new_tag, click.item))
        fit_params[new_tag] = fitparams_factory(click.item)
        fitparams_select.tags[0] += 1

    fitparams_add_dropdown = Dropdown(
        label="Add fit function",
        menu=[
            ("Linear", "linear"),
            ("Gaussian", "gaussian"),
            ("Voigt", "voigt"),
            ("Pseudo Voigt", "pvoigt"),
            # ("Pseudo Voigt1", "pseudovoigt1"),
        ],
        width=145,
    )
    fitparams_add_dropdown.on_click(fitparams_add_dropdown_callback)

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

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

        if new:
            fitparams_table_source.data.update(fit_params[new[0]])
        else:
            fitparams_table_source.data.update(
                dict(param=[], value=[], vary=[], min=[], max=[]))

    fitparams_select = MultiSelect(options=[], height=120, width=145)
    fitparams_select.tags = [0]
    fitparams_select.on_change("value", fitparams_select_callback)

    def fitparams_remove_button_callback():
        if fitparams_select.value:
            sel_tag = fitparams_select.value[0]
            del fit_params[sel_tag]
            for elem in fitparams_select.options:
                if elem[0] == sel_tag:
                    fitparams_select.options.remove(elem)
                    break

            fitparams_select.value = []

    fitparams_remove_button = Button(label="Remove fit function", width=145)
    fitparams_remove_button.on_click(fitparams_remove_button_callback)

    def fitparams_factory(function):
        if function == "linear":
            params = ["slope", "intercept"]
        elif function == "gaussian":
            params = ["amplitude", "center", "sigma"]
        elif function == "voigt":
            params = ["amplitude", "center", "sigma", "gamma"]
        elif function == "pvoigt":
            params = ["amplitude", "center", "sigma", "fraction"]
        elif function == "pseudovoigt1":
            params = ["amplitude", "center", "g_sigma", "l_sigma", "fraction"]
        else:
            raise ValueError("Unknown fit function")

        n = len(params)
        fitparams = dict(
            param=params,
            value=[None] * n,
            vary=[True] * n,
            min=[None] * n,
            max=[None] * n,
        )

        if function == "linear":
            fitparams["value"] = [0, 1]
            fitparams["vary"] = [False, True]
            fitparams["min"] = [None, 0]

        elif function == "gaussian":
            fitparams["min"] = [0, None, None]

        return fitparams

    fitparams_table_source = ColumnDataSource(
        dict(param=[], value=[], vary=[], min=[], max=[]))
    fitparams_table = DataTable(
        source=fitparams_table_source,
        columns=[
            TableColumn(field="param", title="Parameter"),
            TableColumn(field="value", title="Value", editor=NumberEditor()),
            TableColumn(field="vary", title="Vary", editor=CheckboxEditor()),
            TableColumn(field="min", title="Min", editor=NumberEditor()),
            TableColumn(field="max", title="Max", editor=NumberEditor()),
        ],
        height=200,
        width=350,
        index_position=None,
        editable=True,
        auto_edit=True,
    )

    # start with `background` and `gauss` fit functions added
    fitparams_add_dropdown_callback(types.SimpleNamespace(item="linear"))
    fitparams_add_dropdown_callback(types.SimpleNamespace(item="gaussian"))
    fitparams_select.value = ["gaussian-1"]  # add selection to gauss

    fit_output_textinput = TextAreaInput(title="Fit results:",
                                         width=750,
                                         height=200)

    def proc_all_button_callback():
        for scan, export in zip(det_data, scan_table_source.data["export"]):
            if export:
                pyzebra.fit_scan(scan,
                                 fit_params,
                                 fit_from=fit_from_spinner.value,
                                 fit_to=fit_to_spinner.value)
                pyzebra.get_area(
                    scan,
                    area_method=AREA_METHODS[area_method_radiobutton.active],
                    lorentz=lorentz_checkbox.active,
                )

        _update_plot(_get_selected_scan())
        _update_table()

    proc_all_button = Button(label="Process All",
                             button_type="primary",
                             width=145)
    proc_all_button.on_click(proc_all_button_callback)

    def proc_button_callback():
        scan = _get_selected_scan()
        pyzebra.fit_scan(scan,
                         fit_params,
                         fit_from=fit_from_spinner.value,
                         fit_to=fit_to_spinner.value)
        pyzebra.get_area(
            scan,
            area_method=AREA_METHODS[area_method_radiobutton.active],
            lorentz=lorentz_checkbox.active,
        )

        _update_plot(scan)
        _update_table()

    proc_button = Button(label="Process Current", width=145)
    proc_button.on_click(proc_button_callback)

    area_method_div = Div(text="Intensity:", margin=(5, 5, 0, 5))
    area_method_radiobutton = RadioGroup(labels=["Function", "Area"],
                                         active=0,
                                         width=145)

    lorentz_checkbox = CheckboxGroup(labels=["Lorentz Correction"],
                                     width=145,
                                     margin=(13, 5, 5, 5))

    export_preview_textinput = TextAreaInput(title="Export file preview:",
                                             width=500,
                                             height=400)

    def _update_preview():
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_file = temp_dir + "/temp"
            export_data = []
            for s, export in zip(det_data, scan_table_source.data["export"]):
                if export:
                    export_data.append(s)

            pyzebra.export_1D(
                export_data,
                temp_file,
                export_target_select.value,
                hkl_precision=int(hkl_precision_select.value),
            )

            exported_content = ""
            file_content = []
            for ext in EXPORT_TARGETS[export_target_select.value]:
                fname = temp_file + ext
                if os.path.isfile(fname):
                    with open(fname) as f:
                        content = f.read()
                        exported_content += f"{ext} file:\n" + content
                else:
                    content = ""
                file_content.append(content)

            js_data.data.update(content=file_content)
            export_preview_textinput.value = exported_content

    def export_target_select_callback(_attr, _old, new):
        js_data.data.update(ext=EXPORT_TARGETS[new])
        _update_preview()

    export_target_select = Select(title="Export target:",
                                  options=list(EXPORT_TARGETS.keys()),
                                  value="fullprof",
                                  width=80)
    export_target_select.on_change("value", export_target_select_callback)
    js_data.data.update(ext=EXPORT_TARGETS[export_target_select.value])

    def hkl_precision_select_callback(_attr, _old, _new):
        _update_preview()

    hkl_precision_select = Select(title="hkl precision:",
                                  options=["2", "3", "4"],
                                  value="2",
                                  width=80)
    hkl_precision_select.on_change("value", hkl_precision_select_callback)

    save_button = Button(label="Download File(s)",
                         button_type="success",
                         width=200)
    save_button.js_on_click(
        CustomJS(args={"js_data": js_data}, code=javaScript))

    fitpeak_controls = row(
        column(fitparams_add_dropdown, fitparams_select,
               fitparams_remove_button),
        fitparams_table,
        Spacer(width=20),
        column(fit_from_spinner, lorentz_checkbox, area_method_div,
               area_method_radiobutton),
        column(fit_to_spinner, proc_button, proc_all_button),
    )

    scan_layout = column(
        scan_table,
        row(monitor_spinner, column(Spacer(height=19), restore_button)),
        row(column(Spacer(height=19), merge_button), merge_from_select),
    )

    import_layout = column(
        proposal_textinput,
        file_select,
        row(file_open_button, file_append_button),
        upload_div,
        upload_button,
        append_upload_div,
        append_upload_button,
    )

    export_layout = column(
        export_preview_textinput,
        row(export_target_select, hkl_precision_select,
            column(Spacer(height=19), row(save_button))),
    )

    tab_layout = column(
        row(import_layout, scan_layout, plot, Spacer(width=30), export_layout),
        row(fitpeak_controls, fit_output_textinput),
    )

    return Panel(child=tab_layout, title="ccl integrate")
예제 #10
0
TOOLBAR_STICKY = True

#1
plot1 = figure(title="Streaming data at %.1f Hz" % (1e3 / g.DATA_FREQ_VAL),
               x_axis_type=None,
               plot_height=120,
               plot_width=800,
               tools=g.TOOLS1,
               toolbar_location=TOOLBAR_LOCATION,
               toolbar_sticky=TOOLBAR_STICKY,
               active_drag='xbox_select',
               active_tap=None,
               active_scroll='xwheel_zoom')
xaxis1 = TimeAxis()
plot1.add_layout(xaxis1, 'below')
plot1.add_layout(Grid(dimension=0, ticker=xaxis1.ticker))
plot1.x_range.update(follow='end',
                     follow_interval=FOLLOW_INTERVAL,
                     range_padding=0.0,
                     min_interval=2 * xaxis1.ticker.tickers[0].min_interval)

color = brewer['Paired'][4][1]
line1 = plot1.line(x='t', y='f', source=source1, color=color)
circle1 = plot1.circle(x='t', y='f', source=source1, color=color)

plot1.add_tools(
    CustomHover(
        tooltips=[
            ("force", "$~y{0.000}"),
            ("time", "$xaxis_f"),
        ],
예제 #11
0
파일: app2.py 프로젝트: sametrie/aec
def create_bar_chart(data,
                     title,
                     x_name,
                     y_name,
                     hover_tool=None,
                     width=1200,
                     height=300):
    """Creates a bar chart plot, uses centcom dashboard styling.
    Parameters:
    - data, dict
    - title, str
    - names of x and y axes, str
    - hover tool, html"""
    source = ColumnDataSource(data)  # Gets the data for the plot
    # From the data gets the axis names
    xdr = FactorRange(factors=data[x_name])
    ydr = Range1d(start=0, end=max(data[y_name]) * 1.5)

    tools = []

    if hover_tool:  # turns on the over tool if exists
        tools = [
            hover_tool,
        ]

    # Defines the plot main figure
    plot = figure(
        title=title,
        x_range=xdr,  # value ranges
        y_range=ydr,
        plot_width=width,
        plot_height=height,
        h_symmetry=False,
        v_symmetry=False,
        min_borders=0,
        toolbar_location="above",
        tools=tools,
        responsive=True,
        outline_line_color="#666666")

    # Defines the plot's shape as a vertical bar and sets its parameters
    glyph = VBar(x=x_name,
                 top=y_name,
                 bottom=0,
                 width=.8,
                 fill_color="#e12127")

    # Adds the glyph to the plot with the data
    plot.add_glyph(source, glyph)

    # Defines the x, y axes
    xaxis = LinearAxis()
    yaxis = LinearAxis()

    plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
    plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
    plot.toolbar.logo = None
    plot.min_border_top = 0

    plot.xaxis.axis_label = "Days after app deployment"
    plot.yaxis.axis_label = "Bugs found"

    plot.xaxis.major_label_orientation = 1

    plot.xgrid.grid_line_color = None
    plot.ygrid.grid_line_color = "#999999"
    plot.ygrid.grid_line_alpha = 0.1

    return plot
예제 #12
0
def create(palm):
    connected = False
    current_message = None
    stream_t = 0

    doc = curdoc()

    # Streaked and reference waveforms plot
    waveform_plot = Plot(
        title=Title(text="eTOF waveforms"),
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=PLOT_CANVAS_HEIGHT,
        plot_width=PLOT_CANVAS_WIDTH,
        toolbar_location="right",
    )

    # ---- tools
    waveform_plot.toolbar.logo = None
    waveform_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(),
                            ResetTool())

    # ---- axes
    waveform_plot.add_layout(LinearAxis(axis_label="Photon energy, eV"),
                             place="below")
    waveform_plot.add_layout(LinearAxis(axis_label="Intensity",
                                        major_label_orientation="vertical"),
                             place="left")

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

    # ---- line glyphs
    waveform_source = ColumnDataSource(
        dict(x_str=[], y_str=[], x_ref=[], y_ref=[]))
    waveform_ref_line = waveform_plot.add_glyph(
        waveform_source, Line(x="x_ref", y="y_ref", line_color="blue"))
    waveform_str_line = waveform_plot.add_glyph(
        waveform_source, Line(x="x_str", y="y_str", line_color="red"))

    # ---- legend
    waveform_plot.add_layout(
        Legend(items=[("reference",
                       [waveform_ref_line]), ("streaked",
                                              [waveform_str_line])]))
    waveform_plot.legend.click_policy = "hide"

    # Cross-correlation plot
    xcorr_plot = Plot(
        title=Title(text="Waveforms cross-correlation"),
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=PLOT_CANVAS_HEIGHT,
        plot_width=PLOT_CANVAS_WIDTH,
        toolbar_location="right",
    )

    # ---- tools
    xcorr_plot.toolbar.logo = None
    xcorr_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(),
                         ResetTool())

    # ---- axes
    xcorr_plot.add_layout(LinearAxis(axis_label="Energy shift, eV"),
                          place="below")
    xcorr_plot.add_layout(LinearAxis(axis_label="Cross-correlation",
                                     major_label_orientation="vertical"),
                          place="left")

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

    # ---- line glyphs
    xcorr_source = ColumnDataSource(dict(lags=[], xcorr=[]))
    xcorr_plot.add_glyph(xcorr_source,
                         Line(x="lags", y="xcorr", line_color="purple"))

    # ---- vertical span
    xcorr_center_span = Span(location=0, dimension="height")
    xcorr_plot.add_layout(xcorr_center_span)

    # Delays plot
    pulse_delay_plot = Plot(
        title=Title(text="Pulse delays"),
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=PLOT_CANVAS_HEIGHT,
        plot_width=PLOT_CANVAS_WIDTH,
        toolbar_location="right",
    )

    # ---- tools
    pulse_delay_plot.toolbar.logo = None
    pulse_delay_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(),
                               ResetTool())

    # ---- axes
    pulse_delay_plot.add_layout(LinearAxis(axis_label="Pulse number"),
                                place="below")
    pulse_delay_plot.add_layout(
        LinearAxis(axis_label="Pulse delay (uncalib), eV",
                   major_label_orientation="vertical"),
        place="left",
    )

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

    # ---- line glyphs
    pulse_delay_source = ColumnDataSource(dict(x=[], y=[]))
    pulse_delay_plot.add_glyph(pulse_delay_source,
                               Line(x="x", y="y", line_color="steelblue"))

    # Pulse lengths plot
    pulse_length_plot = Plot(
        title=Title(text="Pulse lengths"),
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=PLOT_CANVAS_HEIGHT,
        plot_width=PLOT_CANVAS_WIDTH,
        toolbar_location="right",
    )

    # ---- tools
    pulse_length_plot.toolbar.logo = None
    pulse_length_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(),
                                ResetTool())

    # ---- axes
    pulse_length_plot.add_layout(LinearAxis(axis_label="Pulse number"),
                                 place="below")
    pulse_length_plot.add_layout(
        LinearAxis(axis_label="Pulse length (uncalib), eV",
                   major_label_orientation="vertical"),
        place="left",
    )

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

    # ---- line glyphs
    pulse_length_source = ColumnDataSource(dict(x=[], y=[]))
    pulse_length_plot.add_glyph(pulse_length_source,
                                Line(x="x", y="y", line_color="steelblue"))

    # Image buffer slider
    def buffer_slider_callback(_attr, _old, new):
        message = receiver.data_buffer[new]
        doc.add_next_tick_callback(partial(update, message=message))

    buffer_slider = Slider(
        start=0,
        end=59,
        value=0,
        step=1,
        title="Buffered Image",
        callback_policy="throttle",
        callback_throttle=500,
    )
    buffer_slider.on_change("value", buffer_slider_callback)

    # Connect toggle button
    def connect_toggle_callback(state):
        nonlocal connected
        if state:
            connected = True
            connect_toggle.label = "Connecting"
            connect_toggle.button_type = "default"

        else:
            connected = False
            connect_toggle.label = "Connect"
            connect_toggle.button_type = "default"

    connect_toggle = Toggle(label="Connect", button_type="default", width=250)
    connect_toggle.on_click(connect_toggle_callback)

    # Intensity stream reset button
    def reset_button_callback():
        nonlocal stream_t
        stream_t = 1  # keep the latest point in order to prevent full axis reset

    reset_button = Button(label="Reset", button_type="default", width=250)
    reset_button.on_click(reset_button_callback)

    # Stream update coroutine
    async def update(message):
        nonlocal stream_t
        if connected and receiver.state == "receiving":
            y_ref = message[receiver.reference].value[np.newaxis, :]
            y_str = message[receiver.streaked].value[np.newaxis, :]

            delay, length, debug_data = palm.process({
                "0": y_ref,
                "1": y_str
            },
                                                     debug=True)
            prep_data, lags, corr_res_uncut, _ = debug_data

            waveform_source.data.update(
                x_str=palm.energy_range,
                y_str=prep_data["1"][0, :],
                x_ref=palm.energy_range,
                y_ref=prep_data["0"][0, :],
            )

            xcorr_source.data.update(lags=lags, xcorr=corr_res_uncut[0, :])
            xcorr_center_span.location = delay[0]

            pulse_delay_source.stream({
                "x": [stream_t],
                "y": [delay]
            },
                                      rollover=120)
            pulse_length_source.stream({
                "x": [stream_t],
                "y": [length]
            },
                                       rollover=120)

            stream_t += 1

    # Periodic callback to fetch data from receiver
    async def internal_periodic_callback():
        nonlocal current_message
        if waveform_plot.inner_width is None:
            # wait for the initialization to finish, thus skip this periodic callback
            return

        if connected:
            if receiver.state == "polling":
                connect_toggle.label = "Polling"
                connect_toggle.button_type = "warning"

            elif receiver.state == "stopped":
                connect_toggle.label = "Not available"
                connect_toggle.button_type = "danger"

            elif receiver.state == "receiving":
                connect_toggle.label = "Receiving"
                connect_toggle.button_type = "success"

                # Set slider to the right-most position
                if len(receiver.data_buffer) > 1:
                    buffer_slider.end = len(receiver.data_buffer) - 1
                    buffer_slider.value = len(receiver.data_buffer) - 1

                if receiver.data_buffer:
                    current_message = receiver.data_buffer[-1]

        doc.add_next_tick_callback(partial(update, message=current_message))

    doc.add_periodic_callback(internal_periodic_callback, 1000)

    # assemble
    tab_layout = column(
        row(
            column(waveform_plot, xcorr_plot),
            Spacer(width=30),
            column(buffer_slider, row(connect_toggle, reset_button)),
        ),
        row(pulse_delay_plot, Spacer(width=10), pulse_length_plot),
    )

    return Panel(child=tab_layout, title="Stream")
예제 #13
0
def create():
    det_data = {}
    roi_selection = {}

    upload_div = Div(text="Open .cami file:")

    def upload_button_callback(_attr, _old, new):
        with io.StringIO(base64.b64decode(new).decode()) as file:
            h5meta_list = pyzebra.parse_h5meta(file)
            file_list = h5meta_list["filelist"]
            filelist.options = file_list
            filelist.value = file_list[0]

    upload_button = FileInput(accept=".cami")
    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 auto_toggle.active:
            im_max = int(np.max(current_image))
            im_min = int(np.min(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

    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])
        overview_plot_y_image_source.data.update(image=[overview_y], dw=[n_y])

        if frame_button_group.active == 0:  # Frame
            overview_plot_x.axis[1].axis_label = "Frame"
            overview_plot_y.axis[1].axis_label = "Frame"

            overview_plot_x_image_source.data.update(y=[0], dh=[n_im])
            overview_plot_y_image_source.data.update(y=[0], dh=[n_im])

        elif frame_button_group.active == 1:  # Omega
            overview_plot_x.axis[1].axis_label = "Omega"
            overview_plot_y.axis[1].axis_label = "Omega"

            om = det_data["rot_angle"]
            om_start = om[0]
            om_end = (om[-1] - om[0]) * n_im / (n_im - 1)
            overview_plot_x_image_source.data.update(y=[om_start], dh=[om_end])
            overview_plot_y_image_source.data.update(y=[om_start], dh=[om_end])

    def filelist_callback(_attr, _old, new):
        nonlocal det_data
        det_data = pyzebra.read_detector_data(new)

        index_spinner.value = 0
        index_spinner.high = det_data["data"].shape[0] - 1
        update_image(0)
        update_overview_plot()

    filelist = Select()
    filelist.on_change("value", filelist_callback)

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

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

    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_H * 3,
        plot_width=IMAGE_W * 3,
        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))],
            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)

    plot.add_glyph(image_source, h_glyph)
    plot.add_glyph(image_source, k_glyph)
    plot.add_glyph(image_source, l_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=200,
        plot_width=IMAGE_W * 3,
        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_H * 3,
        plot_width=200,
        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"), ("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 range
    frame_range = DataRange1d()
    det_x_range = DataRange1d()
    overview_plot_x = Plot(
        title=Title(text="Projections on X-axis"),
        x_range=det_x_range,
        y_range=frame_range,
        plot_height=400,
        plot_width=400,
        toolbar_location="left",
    )

    # ---- 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=[1],
             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 = DataRange1d()
    overview_plot_y = Plot(
        title=Title(text="Projections on Y-axis"),
        x_range=det_y_range,
        y_range=frame_range,
        plot_height=400,
        plot_width=400,
        toolbar_location="left",
    )

    # ---- 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(axis_label="Frame",
                                          major_label_orientation="vertical"),
                               place="left")

    # ---- 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=[1],
             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")

    def frame_button_group_callback(_active):
        update_overview_plot()

    frame_button_group = RadioButtonGroup(labels=["Frames", "Omega"], active=0)
    frame_button_group.on_click(frame_button_group_callback)

    roi_avg_plot = Plot(
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=IMAGE_H * 3,
        plot_width=IMAGE_W * 3,
        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()))
    colormap.on_change("value", colormap_callback)
    colormap.value = "plasma"

    radio_button_group = RadioButtonGroup(labels=["nb", "nb_bi"], active=0)

    STEP = 1

    # ---- colormap auto toggle button
    def auto_toggle_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()

    auto_toggle = Toggle(label="Auto Range",
                         active=True,
                         button_type="default")
    auto_toggle.on_click(auto_toggle_callback)

    # ---- colormap display max value
    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(
        title="Maximal Display Value:",
        low=0 + STEP,
        value=1,
        step=STEP,
        disabled=auto_toggle.active,
    )
    display_max_spinner.on_change("value", display_max_spinner_callback)

    # ---- colormap display min value
    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(
        title="Minimal Display Value:",
        high=1 - STEP,
        value=0,
        step=STEP,
        disabled=auto_toggle.active,
    )
    display_min_spinner.on_change("value", display_min_spinner_callback)

    def hkl_button_callback():
        index = index_spinner.value
        setup_type = "nb_bi" if radio_button_group.active else "nb"
        h, k, l = calculate_hkl(det_data, index, setup_type)
        image_source.data.update(h=[h], k=[k], l=[l])

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

    selection_list = TextAreaInput(rows=7)

    def selection_button_callback():
        nonlocal roi_selection
        selection = [
            int(np.floor(det_x_range.start)),
            int(np.ceil(det_x_range.end)),
            int(np.floor(det_y_range.start)),
            int(np.ceil(det_y_range.end)),
            int(np.floor(frame_range.start)),
            int(np.ceil(frame_range.end)),
        ]

        filename_id = filelist.value[-8:-4]
        if filename_id in roi_selection:
            roi_selection[f"{filename_id}"].append(selection)
        else:
            roi_selection[f"{filename_id}"] = [selection]

        selection_list.value = str(roi_selection)

    selection_button = Button(label="Add selection")
    selection_button.on_click(selection_button_callback)

    # Final layout
    layout_image = column(
        gridplot([[proj_v, None], [plot, proj_h]], merge_tools=False),
        row(index_spinner))
    colormap_layout = column(colormap, auto_toggle, display_max_spinner,
                             display_min_spinner)
    hkl_layout = column(radio_button_group, hkl_button)

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

    tab_layout = row(
        column(
            upload_div,
            upload_button,
            filelist,
            layout_image,
            row(colormap_layout, hkl_layout),
        ),
        column(
            roi_avg_plot,
            layout_overview,
            row(selection_button, selection_list),
        ),
    )

    return Panel(child=tab_layout, title="Data Viewer")
예제 #14
0
def make_scatter_plot(source,
                      data,
                      country,
                      xname,
                      yname,
                      xax=False,
                      yax=False):
    # sets range and borders for plot
    xdr = DataRange1d(bounds=None)
    ydr = DataRange1d(bounds=None)
    mbl = 40 if yax else 0
    mbb = 40 if xax else 0
    plot = figure(x_range=xdr,
                  y_range=ydr,
                  background_fill_color="#efe8e2",
                  border_fill_color='white',
                  plot_width=200 + mbl,
                  plot_height=200 + mbb,
                  min_border_left=2 + mbl,
                  min_border_right=2,
                  min_border_top=2,
                  min_border_bottom=2 + mbb,
                  title=country)

    # plots points
    circle = Circle(x=xname,
                    y=yname,
                    fill_color="blue",
                    fill_alpha=0.2,
                    size=4,
                    line_color="blue")
    plot.add_glyph(source, circle)

    # calculates and plots regression line
    a, b, mse = make_regression_line(data, xname, yname)
    mse_mean = mse.mean()
    print(xname, yname, mse_mean)
    x = data[xname]
    plot.line(x, a * x + b, color='red')
    plot.axis.visible = False

    # makes axis according to place in matrix
    xticker = BasicTicker()
    if xax:
        xaxis = LinearAxis()
        xaxis.axis_label = xname
        plot.add_layout(xaxis, 'below')
        xticker = xaxis.ticker
    plot.add_layout(Grid(dimension=0, ticker=xticker))

    yticker = BasicTicker()
    if yax:
        yaxis = LinearAxis()
        yaxis.axis_label = yname
        yaxis.major_label_orientation = 'vertical'
        plot.add_layout(yaxis, 'left')
        yticker = yaxis.ticker

    plot.add_layout(Grid(dimension=1, ticker=yticker))

    return plot
예제 #15
0
    def __init__(self, n_rectangles=1000, clear_interval=20000, **kwargs):
        """
        kwargs are applied to the bokeh.models.plots.Plot constructor
        """
        self.n_rectangles = n_rectangles
        self.clear_interval = clear_interval
        self.last = 0

        self.source = ColumnDataSource(data=dict(start=[],
                                                 duration=[],
                                                 key=[],
                                                 name=[],
                                                 color=[],
                                                 worker=[],
                                                 y=[],
                                                 worker_thread=[],
                                                 alpha=[]))

        x_range = DataRange1d()
        y_range = DataRange1d(range_padding=0)

        self.root = Plot(title=Title(text="Task Stream"),
                         id='bk-task-stream-plot',
                         x_range=x_range,
                         y_range=y_range,
                         toolbar_location="above",
                         min_border_right=35,
                         **kwargs)

        self.root.add_glyph(
            self.source,
            Rect(x="start",
                 y="y",
                 width="duration",
                 height=0.8,
                 fill_color="color",
                 line_color="color",
                 line_alpha=0.6,
                 fill_alpha="alpha",
                 line_width=3))

        self.root.add_layout(DatetimeAxis(axis_label="Time"), "below")

        ticker = BasicTicker(num_minor_ticks=0)
        self.root.add_layout(
            LinearAxis(axis_label="Worker Core", ticker=ticker), "left")
        self.root.add_layout(
            Grid(dimension=1, grid_line_alpha=0.4, ticker=ticker))

        hover = HoverTool(point_policy="follow_mouse",
                          tooltips="""
                <div>
                    <span style="font-size: 12px; font-weight: bold;">@name:</span>&nbsp;
                    <span style="font-size: 10px; font-family: Monaco, monospace;">@duration</span>
                    <span style="font-size: 10px;">ms</span>&nbsp;
                </div>
                """)

        # export = ExportTool()
        # export.register_plot(self.root)

        self.root.add_tools(
            hover,
            # export,
            BoxZoomTool(),
            ResetTool(reset_size=False),
            PanTool(dimensions="width"),
            WheelZoomTool(dimensions="width"))

        # Required for update callback
        self.task_stream_index = [0]
예제 #16
0
def create_bar_chart(data,
                     title,
                     x_name,
                     y_name,
                     x_label,
                     y_label,
                     hover_tool=None,
                     width=1200,
                     height=500):
    """Creates a bar chart plot with the exact styling for the centcom
       dashboard. Pass in data as a dictionary, desired plot title,
       name of x axis, y axis and the hover tool HTML.
    """
    source = ColumnDataSource(data)
    xdr = FactorRange(factors=data[x_name])
    ydr = Range1d(start=0, end=max(data[y_name]) * 1.5)

    tools = []
    if hover_tool:
        tools = [
            hover_tool,
        ]

    plot = figure(title=title,
                  x_range=xdr,
                  y_range=ydr,
                  plot_width=width,
                  plot_height=height,
                  h_symmetry=False,
                  v_symmetry=False,
                  min_border=0,
                  toolbar_location="above",
                  tools=tools,
                  sizing_mode='scale_width',
                  outline_line_color="#666666")

    glyph = VBar(x=x_name,
                 top=y_name,
                 bottom=0,
                 width=.8,
                 fill_color="#141d99")
    plot.add_glyph(source, glyph)

    xaxis = LinearAxis()
    yaxis = LinearAxis()

    plot.title.text_font_size = '15pt'
    plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
    plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
    plot.toolbar.logo = None
    plot.min_border_top = 0
    plot.xgrid.grid_line_color = None
    plot.ygrid.grid_line_color = "#999999"
    plot.yaxis.axis_label = y_label
    plot.yaxis.axis_label_text_font_size = '15pt'
    plot.yaxis.major_label_text_font_size = '12pt'
    plot.ygrid.grid_line_alpha = 0.1
    plot.xaxis.axis_label = x_label
    plot.xaxis.major_label_orientation = 1
    plot.xaxis.axis_label_text_font_size = '15pt'
    plot.xaxis.major_label_text_font_size = '12pt'

    return plot
예제 #17
0
def create(palm):
    fit_max = 1
    fit_min = 0

    doc = curdoc()

    # THz calibration plot
    scan_plot = Plot(
        title=Title(text="THz calibration"),
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=PLOT_CANVAS_HEIGHT,
        plot_width=PLOT_CANVAS_WIDTH,
        toolbar_location="right",
    )

    # ---- tools
    scan_plot.toolbar.logo = None
    scan_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(), ResetTool())

    # ---- axes
    scan_plot.add_layout(LinearAxis(axis_label="Stage delay motor"),
                         place="below")
    scan_plot.add_layout(LinearAxis(axis_label="Energy shift, eV",
                                    major_label_orientation="vertical"),
                         place="left")

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

    # ---- circle cluster glyphs
    scan_circle_source = ColumnDataSource(dict(x=[], y=[]))
    scan_plot.add_glyph(scan_circle_source,
                        Circle(x="x", y="y", line_alpha=0, fill_alpha=0.5))

    # ---- circle glyphs
    scan_avg_circle_source = ColumnDataSource(dict(x=[], y=[]))
    scan_plot.add_glyph(
        scan_avg_circle_source,
        Circle(x="x", y="y", line_color="purple", fill_color="purple"))

    # ---- line glyphs
    fit_line_source = ColumnDataSource(dict(x=[], y=[]))
    scan_plot.add_glyph(fit_line_source, Line(x="x",
                                              y="y",
                                              line_color="purple"))

    # THz calibration folder path text input
    def path_textinput_callback(_attr, _old_value, _new_value):
        update_load_dropdown_menu()
        path_periodic_update()

    path_textinput = TextInput(title="THz calibration path:",
                               value=os.path.join(os.path.expanduser("~")),
                               width=510)
    path_textinput.on_change("value", path_textinput_callback)

    # THz calibration eco scans dropdown
    def scans_dropdown_callback(_attr, _old_value, new_value):
        scans_dropdown.label = new_value

    scans_dropdown = Dropdown(label="ECO scans",
                              button_type="default",
                              menu=[])
    scans_dropdown.on_change("value", scans_dropdown_callback)

    # ---- eco scans periodic update
    def path_periodic_update():
        new_menu = []
        if os.path.isdir(path_textinput.value):
            for entry in os.scandir(path_textinput.value):
                if entry.is_file() and entry.name.endswith(".json"):
                    new_menu.append((entry.name, entry.name))
        scans_dropdown.menu = sorted(new_menu, reverse=True)

    doc.add_periodic_callback(path_periodic_update, 5000)

    # Calibrate button
    def calibrate_button_callback():
        palm.calibrate_thz(
            path=os.path.join(path_textinput.value, scans_dropdown.value))
        fit_max_spinner.value = np.ceil(palm.thz_calib_data.index.values.max())
        fit_min_spinner.value = np.floor(
            palm.thz_calib_data.index.values.min())
        update_calibration_plot()

    def update_calibration_plot():
        scan_plot.xaxis.axis_label = f"{palm.thz_motor_name}, {palm.thz_motor_unit}"

        scan_circle_source.data.update(
            x=np.repeat(palm.thz_calib_data.index,
                        palm.thz_calib_data["peak_shift"].apply(len)).tolist(),
            y=np.concatenate(
                palm.thz_calib_data["peak_shift"].values).tolist(),
        )

        scan_avg_circle_source.data.update(
            x=palm.thz_calib_data.index.tolist(),
            y=palm.thz_calib_data["peak_shift_mean"].tolist())

        x = np.linspace(fit_min, fit_max, 100)
        y = palm.thz_slope * x + palm.thz_intersect
        fit_line_source.data.update(x=np.round(x, decimals=5),
                                    y=np.round(y, decimals=5))

        calib_const_div.text = f"""
        thz_slope = {palm.thz_slope}
        """

    calibrate_button = Button(label="Calibrate THz",
                              button_type="default",
                              width=250)
    calibrate_button.on_click(calibrate_button_callback)

    # THz fit maximal value text input
    def fit_max_spinner_callback(_attr, old_value, new_value):
        nonlocal fit_max
        if new_value > fit_min:
            fit_max = new_value
            palm.calibrate_thz(
                path=os.path.join(path_textinput.value, scans_dropdown.value),
                fit_range=(fit_min, fit_max),
            )
            update_calibration_plot()
        else:
            fit_max_spinner.value = old_value

    fit_max_spinner = Spinner(title="Maximal fit value:",
                              value=fit_max,
                              step=0.1)
    fit_max_spinner.on_change("value", fit_max_spinner_callback)

    # THz fit maximal value text input
    def fit_min_spinner_callback(_attr, old_value, new_value):
        nonlocal fit_min
        if new_value < fit_max:
            fit_min = new_value
            palm.calibrate_thz(
                path=os.path.join(path_textinput.value, scans_dropdown.value),
                fit_range=(fit_min, fit_max),
            )
            update_calibration_plot()
        else:
            fit_min_spinner.value = old_value

    fit_min_spinner = Spinner(title="Minimal fit value:",
                              value=fit_min,
                              step=0.1)
    fit_min_spinner.on_change("value", fit_min_spinner_callback)

    # Save calibration button
    def save_button_callback():
        palm.save_thz_calib(path=path_textinput.value)
        update_load_dropdown_menu()

    save_button = Button(label="Save", button_type="default", width=250)
    save_button.on_click(save_button_callback)

    # Load calibration button
    def load_dropdown_callback(_attr, _old_value, new_value):
        palm.load_thz_calib(os.path.join(path_textinput.value, new_value))
        update_calibration_plot()

    def update_load_dropdown_menu():
        new_menu = []
        calib_file_ext = ".palm_thz"
        if os.path.isdir(path_textinput.value):
            for entry in os.scandir(path_textinput.value):
                if entry.is_file() and entry.name.endswith((calib_file_ext)):
                    new_menu.append(
                        (entry.name[:-len(calib_file_ext)], entry.name))
            load_dropdown.button_type = "default"
            load_dropdown.menu = sorted(new_menu, reverse=True)
        else:
            load_dropdown.button_type = "danger"
            load_dropdown.menu = new_menu

    doc.add_next_tick_callback(update_load_dropdown_menu)
    doc.add_periodic_callback(update_load_dropdown_menu, 5000)

    load_dropdown = Dropdown(label="Load", menu=[], width=250)
    load_dropdown.on_change("value", load_dropdown_callback)

    # Calibration constants
    calib_const_div = Div(text=f"""
        thz_slope = {0}
        """)

    # assemble
    tab_layout = column(
        row(
            scan_plot,
            Spacer(width=30),
            column(
                path_textinput,
                scans_dropdown,
                calibrate_button,
                fit_max_spinner,
                fit_min_spinner,
                row(save_button, load_dropdown),
                calib_const_div,
            ),
        ))

    return Panel(child=tab_layout, title="THz Calibration")
def plotprotein(sequence, other_binding, dna_binding, metal_binding, active,
                variant_location):
    sequence = [i for i in sequence]
    print(len(sequence))
    sequence += [''] * (3000 - len(sequence))
    print(sequence)

    print(variant_location)
    if variant_location > 50:
        start_seq = variant_location - 50
    else:
        start_seq = 0
    if variant_location + 50 < len(sequence):
        end_seq = variant_location + 50
    else:
        end_seq = 3000
    x_values = range(0, 3000)
    #x_values = range(starting_value, value)
    source1 = ColumnDataSource(
        dict(x=x_values[start_seq:end_seq],
             y=other_binding[start_seq:end_seq],
             names=sequence[start_seq:end_seq]))
    source2 = ColumnDataSource(
        dict(x=x_values[start_seq:end_seq],
             y=dna_binding[start_seq:end_seq],
             names=sequence[start_seq:end_seq]))
    source3 = ColumnDataSource(
        dict(x=x_values[start_seq:end_seq],
             y=metal_binding[start_seq:end_seq],
             names=sequence[start_seq:end_seq]))
    source4 = ColumnDataSource(
        dict(x=x_values[start_seq:end_seq],
             y=active[start_seq:end_seq],
             names=sequence[start_seq:end_seq]))
    glyph1 = Line(x="x", y="y", line_color="red", line_width=3, line_alpha=0.6)
    glyph2 = Line(x="x",
                  y="y",
                  line_color="blue",
                  line_width=3,
                  line_alpha=0.6)
    glyph3 = Line(x="x",
                  y="y",
                  line_color="green",
                  line_width=3,
                  line_alpha=0.6)
    glyph4 = Line(x="x",
                  y="y",
                  line_color="orange",
                  line_width=3,
                  line_alpha=0.6)
    plot = Plot(title=None,
                plot_height=150,
                plot_width=1000,
                min_border=0,
                toolbar_location=None)
    plot.add_glyph(source1, glyph1)
    plot.add_glyph(source2, glyph2)
    plot.add_glyph(source3, glyph3)
    plot.add_glyph(source4, glyph4)
    plot.add_layout(
        Span(location=variant_location, dimension='height',
             line_color='black'))
    xaxis = LinearAxis()
    #YOUR_FONT_SIZE = 10
    labels = LabelSet(x='x',
                      y=1,
                      text='names',
                      level='glyph',
                      x_offset=-1,
                      y_offset=5,
                      source=source1,
                      render_mode='canvas',
                      text_font_size='5pt')
    plot.add_layout(labels)
    yaxis = LinearAxis()
    plot.add_layout(yaxis, 'left')
    plot.yaxis.bounds = (0, 1)
    plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
    plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
    plot.y_range = Range1d(-0.1, 1.5)
    show(plot)
예제 #19
0
def create(palm):
    energy_min = palm.energy_range.min()
    energy_max = palm.energy_range.max()
    energy_npoints = palm.energy_range.size

    current_results = (0, 0, 0, 0)

    doc = curdoc()

    # Streaked and reference waveforms plot
    waveform_plot = Plot(
        title=Title(text="eTOF waveforms"),
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=PLOT_CANVAS_HEIGHT,
        plot_width=PLOT_CANVAS_WIDTH,
        toolbar_location='right',
    )

    # ---- tools
    waveform_plot.toolbar.logo = None
    waveform_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(),
                            ResetTool())

    # ---- axes
    waveform_plot.add_layout(LinearAxis(axis_label='Photon energy, eV'),
                             place='below')
    waveform_plot.add_layout(LinearAxis(axis_label='Intensity',
                                        major_label_orientation='vertical'),
                             place='left')

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

    # ---- line glyphs
    waveform_source = ColumnDataSource(
        dict(x_str=[], y_str=[], x_ref=[], y_ref=[]))
    waveform_ref_line = waveform_plot.add_glyph(
        waveform_source, Line(x='x_ref', y='y_ref', line_color='blue'))
    waveform_str_line = waveform_plot.add_glyph(
        waveform_source, Line(x='x_str', y='y_str', line_color='red'))

    # ---- legend
    waveform_plot.add_layout(
        Legend(items=[("reference",
                       [waveform_ref_line]), ("streaked",
                                              [waveform_str_line])]))
    waveform_plot.legend.click_policy = "hide"

    # Cross-correlation plot
    xcorr_plot = Plot(
        title=Title(text="Waveforms cross-correlation"),
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=PLOT_CANVAS_HEIGHT,
        plot_width=PLOT_CANVAS_WIDTH,
        toolbar_location='right',
    )

    # ---- tools
    xcorr_plot.toolbar.logo = None
    xcorr_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(),
                         ResetTool())

    # ---- axes
    xcorr_plot.add_layout(LinearAxis(axis_label='Energy shift, eV'),
                          place='below')
    xcorr_plot.add_layout(LinearAxis(axis_label='Cross-correlation',
                                     major_label_orientation='vertical'),
                          place='left')

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

    # ---- line glyphs
    xcorr_source = ColumnDataSource(dict(lags=[], xcorr1=[], xcorr2=[]))
    xcorr_plot.add_glyph(
        xcorr_source,
        Line(x='lags', y='xcorr1', line_color='purple', line_dash='dashed'))
    xcorr_plot.add_glyph(xcorr_source,
                         Line(x='lags', y='xcorr2', line_color='purple'))

    # ---- vertical span
    xcorr_center_span = Span(location=0, dimension='height')
    xcorr_plot.add_layout(xcorr_center_span)

    # Delays plot
    pulse_delay_plot = Plot(
        title=Title(text="Pulse delays"),
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=PLOT_CANVAS_HEIGHT,
        plot_width=PLOT_CANVAS_WIDTH,
        toolbar_location='right',
    )

    # ---- tools
    pulse_delay_plot.toolbar.logo = None
    pulse_delay_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(),
                               ResetTool())

    # ---- axes
    pulse_delay_plot.add_layout(LinearAxis(axis_label='Pulse number'),
                                place='below')
    pulse_delay_plot.add_layout(
        LinearAxis(axis_label='Pulse delay (uncalib), eV',
                   major_label_orientation='vertical'),
        place='left',
    )

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

    # ---- line glyphs
    pulse_delay_source = ColumnDataSource(dict(pulse=[], delay=[]))
    pulse_delay_plot.add_glyph(
        pulse_delay_source, Line(x='pulse', y='delay', line_color='steelblue'))

    # ---- vertical span
    pulse_delay_plot_span = Span(location=0, dimension='height')
    pulse_delay_plot.add_layout(pulse_delay_plot_span)

    # Pulse lengths plot
    pulse_length_plot = Plot(
        title=Title(text="Pulse lengths"),
        x_range=DataRange1d(),
        y_range=DataRange1d(),
        plot_height=PLOT_CANVAS_HEIGHT,
        plot_width=PLOT_CANVAS_WIDTH,
        toolbar_location='right',
    )

    # ---- tools
    pulse_length_plot.toolbar.logo = None
    pulse_length_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(),
                                ResetTool())

    # ---- axes
    pulse_length_plot.add_layout(LinearAxis(axis_label='Pulse number'),
                                 place='below')
    pulse_length_plot.add_layout(
        LinearAxis(axis_label='Pulse length (uncalib), eV',
                   major_label_orientation='vertical'),
        place='left',
    )

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

    # ---- line glyphs
    pulse_length_source = ColumnDataSource(dict(x=[], y=[]))
    pulse_length_plot.add_glyph(pulse_length_source,
                                Line(x='x', y='y', line_color='steelblue'))

    # ---- vertical span
    pulse_length_plot_span = Span(location=0, dimension='height')
    pulse_length_plot.add_layout(pulse_length_plot_span)

    # Folder path text input
    def path_textinput_callback(_attr, _old, new):
        save_textinput.value = new
        path_periodic_update()

    path_textinput = TextInput(title="Folder Path:",
                               value=os.path.join(os.path.expanduser('~')),
                               width=510)
    path_textinput.on_change('value', path_textinput_callback)

    # Saved runs dropdown menu
    def h5_update(pulse, delays, debug_data):
        prep_data, lags, corr_res_uncut, corr_results = debug_data

        waveform_source.data.update(
            x_str=palm.energy_range,
            y_str=prep_data['1'][pulse, :],
            x_ref=palm.energy_range,
            y_ref=prep_data['0'][pulse, :],
        )

        xcorr_source.data.update(lags=lags,
                                 xcorr1=corr_res_uncut[pulse, :],
                                 xcorr2=corr_results[pulse, :])

        xcorr_center_span.location = delays[pulse]
        pulse_delay_plot_span.location = pulse
        pulse_length_plot_span.location = pulse

    # this placeholder function should be reassigned in 'saved_runs_dropdown_callback'
    h5_update_fun = lambda pulse: None

    def saved_runs_dropdown_callback(_attr, _old, new):
        if new != "Saved Runs":
            nonlocal h5_update_fun, current_results
            saved_runs_dropdown.label = new
            filepath = os.path.join(path_textinput.value, new)
            tags, delays, lengths, debug_data = palm.process_hdf5_file(
                filepath, debug=True)
            current_results = (new, tags, delays, lengths)

            if autosave_checkbox.active:
                save_button_callback()

            pulse_delay_source.data.update(pulse=np.arange(len(delays)),
                                           delay=delays)
            pulse_length_source.data.update(x=np.arange(len(lengths)),
                                            y=lengths)
            h5_update_fun = partial(h5_update,
                                    delays=delays,
                                    debug_data=debug_data)

            pulse_slider.end = len(delays) - 1
            pulse_slider.value = 0
            h5_update_fun(0)

    saved_runs_dropdown = Dropdown(label="Saved Runs",
                                   button_type='primary',
                                   menu=[])
    saved_runs_dropdown.on_change('value', saved_runs_dropdown_callback)

    # ---- saved run periodic update
    def path_periodic_update():
        new_menu = []
        if os.path.isdir(path_textinput.value):
            for entry in os.scandir(path_textinput.value):
                if entry.is_file() and entry.name.endswith(('.hdf5', '.h5')):
                    new_menu.append((entry.name, entry.name))
        saved_runs_dropdown.menu = sorted(new_menu, reverse=True)

    doc.add_periodic_callback(path_periodic_update, 5000)

    # Pulse number slider
    def pulse_slider_callback(_attr, _old, new):
        h5_update_fun(pulse=new)

    pulse_slider = Slider(
        start=0,
        end=99999,
        value=0,
        step=1,
        title="Pulse ID",
        callback_policy='throttle',
        callback_throttle=500,
    )
    pulse_slider.on_change('value', pulse_slider_callback)

    # Energy maximal range value text input
    def energy_max_textinput_callback(_attr, old, new):
        nonlocal energy_max
        try:
            new_value = float(new)
            if new_value > energy_min:
                energy_max = new_value
                palm.energy_range = np.linspace(energy_min, energy_max,
                                                energy_npoints)
                saved_runs_dropdown_callback('', '', saved_runs_dropdown.label)
            else:
                energy_max_textinput.value = old

        except ValueError:
            energy_max_textinput.value = old

    energy_max_textinput = TextInput(title='Maximal Energy, eV:',
                                     value=str(energy_max))
    energy_max_textinput.on_change('value', energy_max_textinput_callback)

    # Energy minimal range value text input
    def energy_min_textinput_callback(_attr, old, new):
        nonlocal energy_min
        try:
            new_value = float(new)
            if new_value < energy_max:
                energy_min = new_value
                palm.energy_range = np.linspace(energy_min, energy_max,
                                                energy_npoints)
                saved_runs_dropdown_callback('', '', saved_runs_dropdown.label)
            else:
                energy_min_textinput.value = old

        except ValueError:
            energy_min_textinput.value = old

    energy_min_textinput = TextInput(title='Minimal Energy, eV:',
                                     value=str(energy_min))
    energy_min_textinput.on_change('value', energy_min_textinput_callback)

    # Energy number of interpolation points text input
    def energy_npoints_textinput_callback(_attr, old, new):
        nonlocal energy_npoints
        try:
            new_value = int(new)
            if new_value > 1:
                energy_npoints = new_value
                palm.energy_range = np.linspace(energy_min, energy_max,
                                                energy_npoints)
                saved_runs_dropdown_callback('', '', saved_runs_dropdown.label)
            else:
                energy_npoints_textinput.value = old

        except ValueError:
            energy_npoints_textinput.value = old

    energy_npoints_textinput = TextInput(
        title='Number of interpolation points:', value=str(energy_npoints))
    energy_npoints_textinput.on_change('value',
                                       energy_npoints_textinput_callback)

    # Save location
    save_textinput = TextInput(title="Save Folder Path:",
                               value=os.path.join(os.path.expanduser('~')))

    # Autosave checkbox
    autosave_checkbox = CheckboxButtonGroup(labels=["Auto Save"],
                                            active=[],
                                            width=250)

    # Save button
    def save_button_callback():
        if current_results[0]:
            filename, tags, delays, lengths = current_results
            save_filename = os.path.splitext(filename)[0] + '.csv'
            df = pd.DataFrame({
                'pulse_id': tags,
                'pulse_delay': delays,
                'pulse_length': lengths
            })
            df.to_csv(os.path.join(save_textinput.value, save_filename),
                      index=False)

    save_button = Button(label="Save Results",
                         button_type='default',
                         width=250)
    save_button.on_click(save_button_callback)

    # assemble
    tab_layout = column(
        row(
            column(waveform_plot, xcorr_plot),
            Spacer(width=30),
            column(
                path_textinput,
                saved_runs_dropdown,
                pulse_slider,
                Spacer(height=30),
                energy_min_textinput,
                energy_max_textinput,
                energy_npoints_textinput,
                Spacer(height=30),
                save_textinput,
                autosave_checkbox,
                save_button,
            ),
        ),
        row(pulse_delay_plot, Spacer(width=10), pulse_length_plot),
    )

    return Panel(child=tab_layout, title="HDF5 File")
예제 #20
0
def large_plot(n: int) -> Tuple[Model, Set[Model]]:
    from bokeh.models import (
        BoxSelectTool,
        BoxZoomTool,
        Column,
        ColumnDataSource,
        DataRange1d,
        GlyphRenderer,
        Grid,
        Line,
        LinearAxis,
        PanTool,
        Plot,
        ResetTool,
        SaveTool,
        WheelZoomTool,
        ZoomInTool,
        ZoomOutTool,
    )

    col = Column()
    objects: Set[Model] = {col}

    for i in range(n):
        source = ColumnDataSource(data=dict(x=[0, i + 1], y=[0, i + 1]))
        xdr = DataRange1d()
        ydr = DataRange1d()
        plot = Plot(x_range=xdr, y_range=ydr)
        xaxis = LinearAxis()
        plot.add_layout(xaxis, "below")
        yaxis = LinearAxis()
        plot.add_layout(yaxis, "left")
        xgrid = Grid(dimension=0)
        plot.add_layout(xgrid, "center")
        ygrid = Grid(dimension=1)
        plot.add_layout(ygrid, "center")
        tickers = [
            xaxis.ticker, xaxis.formatter, yaxis.ticker, yaxis.formatter
        ]
        glyph = Line(x='x', y='y')
        renderer = GlyphRenderer(data_source=source, glyph=glyph)
        plot.renderers.append(renderer)
        pan = PanTool()
        zoom_in = ZoomInTool()
        zoom_out = ZoomOutTool()
        wheel_zoom = WheelZoomTool()
        box_zoom = BoxZoomTool()
        box_select = BoxSelectTool()
        save = SaveTool()
        reset = ResetTool()
        tools = [
            pan, zoom_in, zoom_out, wheel_zoom, box_zoom, box_select, save,
            reset
        ]
        plot.add_tools(*tools)
        col.children.append(plot)
        objects |= set([
            xdr,
            ydr,
            xaxis,
            xaxis.major_label_policy,
            yaxis,
            yaxis.major_label_policy,
            xgrid,
            ygrid,
            renderer,
            renderer.view,
            glyph,
            source,
            source.selected,
            source.selection_policy,
            plot,
            plot.x_scale,
            plot.y_scale,
            plot.toolbar,
            plot.title,
            box_zoom.overlay,
            box_select.overlay,
        ] + tickers + tools)

    return col, objects
예제 #21
0
def create_bar_chart(data,
                     title,
                     x_name,
                     y_name,
                     hover_tool=None,
                     width=1200,
                     height=300):
    """Creates a bar chart plot with the exact styling for the centcom
       dashboard. Pass in data as a dictionary, desired plot title,
       name of x axis, y axis and the hover tool HTML.
    """
    source = ColumnDataSource(data)
    xdr = FactorRange(factors=data[x_name])
    ydr = Range1d(start=0, end=max(data[y_name]) * 1.5)

    callback = CustomJS(args=dict(source=source),
                        code="""
    var data = source.data;
    
    console.log("data[bugs] : " +data['bugs']);
    console.log("source data : " + data);

    var geometry = cb_data['geometries'];
        /// calculate x and y
        var x = geometry[0].x
        var y = geometry[0].y

    console.log("geometry : " + geometry[0]);
    console.log("x : " + x);
    console.log("y : " + y);
    var b = cb_obj.data;
    console.log("cb_obj-data : "+ b);
    console.log("cb_obj selected : " + cb_obj.selected);
    console.log("cb_obj selected indices : " + cb_obj.selected.indices);
    
    //This one works to give indices from 0-last
    console.log(cb_obj.selected['1d'].indices)
    if ($(".hover_bkgr_fricc").length){
    document.getElementById('id_index').value= parseInt(cb_obj.selected['1d'].indices) + 1 ; 
    $('.hover_bkgr_fricc').show();
    }

    """)
    tap_tool = TapTool(callback=callback)

    plot = figure(title=title,
                  x_range=xdr,
                  y_range=ydr,
                  plot_width=width,
                  plot_height=height,
                  h_symmetry=False,
                  v_symmetry=False,
                  min_border=0,
                  toolbar_location="above",
                  tools=[hover_tool, tap_tool,
                         CrosshairTool()],
                  responsive=True,
                  outline_line_color="#666666")

    glyph = VBar(x=x_name,
                 top=y_name,
                 bottom=0,
                 width=.8,
                 fill_color="#e12127")
    plot.add_glyph(source, glyph)

    xaxis = LinearAxis()
    yaxis = LinearAxis()

    plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
    plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
    plot.toolbar.logo = None
    plot.min_border_top = 0
    plot.xgrid.grid_line_color = None
    plot.ygrid.grid_line_color = "#999999"
    plot.yaxis.axis_label = "Bugs found"
    plot.ygrid.grid_line_alpha = 0.1
    plot.xaxis.axis_label = "Days after app deployment"
    plot.xaxis.major_label_orientation = 1
    return plot
예제 #22
0
    def __init__(
        self,
        plot_height=894,
        plot_width=854,
        image_height=100,
        image_width=100,
        x_start=None,
        x_end=None,
        y_start=None,
        y_end=None,
    ):
        """Initialize image view plot.

        Args:
            plot_height (int, optional): Height of plot area in screen pixels. Defaults to 894.
            plot_width (int, optional): Width of plot area in screen pixels. Defaults to 854.
            image_height (int, optional): Image height in pixels. Defaults to 100.
            image_width (int, optional): Image width in pixels. Defaults to 100.
            x_start (int, optional): Initial x-axis start value. If None, then equals to 0.
                Defaults to None.
            x_end (int, optional): Initial x-axis end value. If None, then equals to image_width.
                Defaults to None.
            y_start (int, optional): Initial y-axis start value. If None, then equals to 0.
                Defaults to None.
            y_end (int, optional): Initial y-axis end value. If None, then equals to image_height.
                Defaults to None.
        """
        if x_start is None:
            x_start = 0

        if x_end is None:
            x_end = image_width

        if y_start is None:
            y_start = 0

        if y_end is None:
            y_end = image_height

        self.zoom_views = []

        plot = Plot(
            x_range=Range1d(x_start, x_end, bounds=(0, image_width)),
            y_range=Range1d(y_start, y_end, bounds=(0, image_height)),
            plot_height=plot_height,
            plot_width=plot_width,
            toolbar_location="left",
        )
        self.plot = plot

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

        hovertool = HoverTool(tooltips=[("intensity", "@image")],
                              names=["image_glyph"])

        plot.add_tools(PanTool(), WheelZoomTool(maintain_focus=False),
                       SaveTool(), ResetTool(), hovertool)
        plot.toolbar.active_scroll = plot.tools[1]

        # ---- 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
        self._image_source = ColumnDataSource(
            dict(
                image=[np.zeros((1, 1), dtype="float32")],
                x=[x_start],
                y=[y_start],
                dw=[x_end - x_start],
                dh=[y_end - y_start],
            ))

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

        # This avoids double update of image values on a client, see
        # https://github.com/bokeh/bokeh/issues/7079
        # https://github.com/bokeh/bokeh/issues/7299
        image_renderer.view.source = ColumnDataSource()

        # ---- pixel value text glyph
        self._pvalue_source = ColumnDataSource(dict(x=[], y=[], text=[]))
        plot.add_glyph(
            self._pvalue_source,
            Text(
                x="x",
                y="y",
                text="text",
                text_align="center",
                text_baseline="middle",
                text_color="white",
            ),
        )

        # ---- horizontal and vertical projection line glyphs
        self._hproj_source = ColumnDataSource(dict(x=[], y=[]))
        plot.add_glyph(self._hproj_source,
                       Line(x="x", y="y", line_color="greenyellow"))

        self._vproj_source = ColumnDataSource(dict(x=[], y=[]))
        plot.add_glyph(self._vproj_source,
                       Line(x="x", y="y", line_color="greenyellow"))

        proj_toggle = CheckboxGroup(labels=["Inner Projections"],
                                    default_size=145)
        self.proj_toggle = proj_toggle
예제 #23
0
plot.add_tools(
    PanTool(),
    BoxZoomTool(),
    WheelZoomTool(maintain_focus=False),
    SaveTool(),
    ResetTool(),
)

plot.add_layout(
    LinearAxis(axis_label="pulse_id",
               formatter=BasicTickFormatter(use_scientific=False)),
    place="below",
)
plot.add_layout(LinearAxis(), place="left")

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

step_source = ColumnDataSource(dict(x=[], y=[]))
step = plot.add_glyph(
    step_source,
    Step(x="x", y="y", mode="after", line_color="steelblue", line_width=2))

step_nobkg_source = ColumnDataSource(dict(x=[], y=[]))
step_nobkg = plot.add_glyph(
    step_nobkg_source,
    Step(x="x", y="y", mode="after", line_color="firebrick", line_width=2))

plot.add_layout(
    Legend(
        items=[("ROI Pump-probe", [step]),
예제 #24
0
    TableColumn(field="cty", title="City MPG", editor=IntEditor()),
    TableColumn(field="hwy", title="Highway MPG", editor=IntEditor()),
]
data_table = DataTable(source=source, columns=columns, editable=True)

xdr = DataRange1d()
ydr = DataRange1d()
plot = Plot(title=None,
            x_range=xdr,
            y_range=ydr,
            plot_width=1000,
            plot_height=300)
xaxis = LinearAxis(plot=plot)
plot.below.append(xaxis)
yaxis = LinearAxis(plot=plot)
ygrid = Grid(plot=plot, dimension=1, ticker=yaxis.ticker)
plot.left.append(yaxis)
cty_glyph = Circle(x="index",
                   y="cty",
                   fill_color="#396285",
                   size=8,
                   fill_alpha=0.5,
                   line_alpha=0.5)
hwy_glyph = Circle(x="index",
                   y="hwy",
                   fill_color="#CE603D",
                   size=8,
                   fill_alpha=0.5,
                   line_alpha=0.5)
cty = GlyphRenderer(data_source=source, glyph=cty_glyph)
hwy = GlyphRenderer(data_source=source, glyph=hwy_glyph)
예제 #25
0
# "Emmigrants Men / Women[2014-2017]
plot1 = Plot(title=None,
             plot_width=700,
             plot_height=600,
             min_border=0,
             toolbar_location=None)

glyph_m = HBar(y="years",
               right="men",
               left=1000,
               height=0.31,
               fill_color=Category20[10][0])
plot1.add_glyph(source_m, glyph_m)

glyph_w = HBar(y="years",
               left="women",
               right=-1000,
               height=0.31,
               fill_color=Category20[10][1])
plot1.add_glyph(source_w, glyph_w)

xaxis = LinearAxis()
plot1.add_layout(xaxis, 'below')
yaxis = LinearAxis()
plot1.add_layout(yaxis, 'left')
plot1.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
#plot1.add_layout(Grid(dimension=1, ticker=yaxis.ticker))

show(gridplot([[plot1]]))
export_png(plot1, filename=filepath + "__4-B.png")
 def make_correlation_datatable(correl_df):
     """
     the input datframe must have columns ['Target (as string)', 'Hedge (as string)', 'Correlation ( as float )']
     :param correl_df:
     :return:
     """
     correl_df.reset_index(inplace=True)
     source = ColumnDataSource(correl_df)
     target_ts_asset = sorted(correl_df["Target"].unique())
     hedge_ts_asset = sorted(correl_df["Hedge"].unique())
     columns = [
         TableColumn(field="Target",
                     title="Target Timeseries",
                     formatter=StringFormatter(font_style="bold",
                                               text_color='red')),
         TableColumn(field="Hedge",
                     title="Hedge Timeseries",
                     formatter=StringFormatter(font_style="bold",
                                               text_color='blue')),
         TableColumn(field="Correlation",
                     title="Correlation",
                     formatter=StringFormatter(font_style="bold",
                                               text_color='darkgreen'))
     ]
     data_table = DataTable(source=source,
                            columns=columns,
                            editable=False,
                            width=1000)
     plot = Plot(title=Title(
         text="Correlations, Target vs. Hedge Timeseries)", align="center"),
                 x_range=DataRange1d(),
                 y_range=DataRange1d(),
                 plot_width=1000,
                 plot_height=300)
     # Set up x & y axis
     plot.add_layout(LinearAxis(), 'below')
     yaxis = LinearAxis()
     plot.add_layout(yaxis, 'left')
     plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
     # Add Glyphs
     correlation_glyph = Circle(x="index",
                                y="Correlation",
                                fill_color="#396285",
                                size=8,
                                fill_alpha=0.5,
                                line_alpha=0.5)
     target_glyph = Circle(x="index",
                           y="Target",
                           fill_color="#396285",
                           size=8,
                           fill_alpha=0.5,
                           line_alpha=0.5)
     hedge_glyph = Circle(x="index",
                          y="Hedge",
                          fill_color="#396285",
                          size=8,
                          fill_alpha=0.5,
                          line_alpha=0.5)
     correlation = plot.add_glyph(source, correlation_glyph)
     target = plot.add_glyph(source, target_glyph)
     hedge = plot.add_glyph(source, hedge_glyph)
     # Add the tools
     tooltips = [("Correlation", "@Correlation"), ("Target", "@Target"),
                 ("Hedge", "@Hedge")]
     correlation_hover_tool = HoverTool(renderers=[correlation],
                                        tooltips=tooltips)
     target_hover_tool = HoverTool(renderers=[target], tooltips=tooltips)
     hedge_hover_tool = HoverTool(renderers=[hedge], tooltips=tooltips)
     select_tool = BoxSelectTool(renderers=[target, hedge, correlation],
                                 dimensions='width')
     plot.add_tools(target_hover_tool, hedge_hover_tool,
                    correlation_hover_tool, select_tool)
     layout = Column(plot, data_table)
     the_doc = Document()
     the_doc.add_root(layout)
     return the_doc
예제 #27
0
sprint["MedalLine"]    = sprint.Medal.map(lambda medal: line_color[medal])
sprint["SelectedName"] = sprint[["Name", "Medal", "Year"]].apply(tuple, axis=1).map(lambda args: selected_name(*args))

source = ColumnDataSource(sprint)

xdr = Range1d(start=sprint.MetersBack.max()+2, end=0)                  # XXX: +2 is poor-man's padding (otherwise misses last tick)
ydr = DataRange1d(range_padding=0.05) # XXX: should be 2 years (both sides)

plot = Plot(x_range=xdr, y_range=ydr, plot_width=1000, plot_height=600, toolbar_location=None, outline_line_color=None)
plot.title.text = "Usain Bolt vs. 116 years of Olympic sprinters"

xticker = SingleIntervalTicker(interval=5, num_minor_ticks=0)
xaxis = LinearAxis(ticker=xticker, axis_line_color=None, major_tick_line_color=None,
    axis_label="Meters behind 2012 Bolt", axis_label_text_font_size="10pt", axis_label_text_font_style="bold")
plot.add_layout(xaxis, "below")
xgrid = Grid(dimension=0, ticker=xaxis.ticker, grid_line_dash="dashed")
plot.add_layout(xgrid)
yticker = SingleIntervalTicker(interval=12, num_minor_ticks=0)
yaxis = LinearAxis(ticker=yticker, major_tick_in=-5, major_tick_out=10)
plot.add_layout(yaxis, "right")

radius = dict(value=5, units="screen")
medal_glyph = Circle(x="MetersBack", y="Year", radius=radius, fill_color="MedalFill", line_color="MedalLine", fill_alpha=0.5)
medal = plot.add_glyph(source, medal_glyph)

athlete_glyph = Text(x="MetersBack", y="Year", x_offset=10, text="SelectedName",
    text_align="left", text_baseline="middle", text_font_size="9pt")
athlete = plot.add_glyph(source, athlete_glyph)

no_olympics_glyph = Text(x=7.5, y=1942, text=["No Olympics in 1940 or 1944"],
    text_align="center", text_baseline="middle",
    def make_example_datatable():
        source = ColumnDataSource(mpg)
        print(source.column_names)
        manufacturers = sorted(mpg["manufacturer"].unique())
        models = sorted(mpg["model"].unique())
        transmissions = sorted(mpg["trans"].unique())
        drives = sorted(mpg["drv"].unique())
        classes = sorted(mpg["class"].unique())

        columns = [
            TableColumn(field="manufacturer",
                        title="Manufacturer",
                        editor=SelectEditor(options=manufacturers),
                        formatter=StringFormatter(font_style="bold")),
            TableColumn(field="model",
                        title="Model",
                        editor=StringEditor(completions=models)),
            TableColumn(field="displ",
                        title="Displacement",
                        editor=NumberEditor(step=0.1),
                        formatter=NumberFormatter(format="0.0")),
            TableColumn(field="year", title="Year", editor=IntEditor()),
            TableColumn(field="cyl", title="Cylinders", editor=IntEditor()),
            TableColumn(field="trans",
                        title="Transmission",
                        editor=SelectEditor(options=transmissions)),
            TableColumn(field="drv",
                        title="Drive",
                        editor=SelectEditor(options=drives)),
            TableColumn(field="class",
                        title="Class",
                        editor=SelectEditor(options=classes)),
            TableColumn(field="cty", title="City MPG", editor=IntEditor()),
            TableColumn(field="hwy", title="Highway MPG", editor=IntEditor()),
        ]
        data_table = DataTable(source=source,
                               columns=columns,
                               editable=True,
                               width=1000)
        plot = Plot(title=None,
                    x_range=DataRange1d(),
                    y_range=DataRange1d(),
                    plot_width=1000,
                    plot_height=300)
        # Set up x & y axis
        plot.add_layout(LinearAxis(), 'below')
        yaxis = LinearAxis()
        plot.add_layout(yaxis, 'left')
        plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))

        # Add Glyphs
        cty_glyph = Circle(x="index",
                           y="cty",
                           fill_color="#396285",
                           size=8,
                           fill_alpha=0.5,
                           line_alpha=0.5)
        hwy_glyph = Circle(x="index",
                           y="hwy",
                           fill_color="#CE603D",
                           size=8,
                           fill_alpha=0.5,
                           line_alpha=0.5)
        cty = plot.add_glyph(source, cty_glyph)
        hwy = plot.add_glyph(source, hwy_glyph)

        # Add the tools
        tooltips = [
            ("Manufacturer", "@manufacturer"),
            ("Model", "@model"),
            ("Displacement", "@displ"),
            ("Year", "@year"),
            ("Cylinders", "@cyl"),
            ("Transmission", "@trans"),
            ("Drive", "@drv"),
            ("Class", "@class"),
        ]
        cty_hover_tool = HoverTool(renderers=[cty],
                                   tooltips=tooltips + [("City MPG", "@cty")])
        hwy_hover_tool = HoverTool(renderers=[hwy],
                                   tooltips=tooltips +
                                   [("Highway MPG", "@hwy")])
        select_tool = BoxSelectTool(renderers=[cty, hwy], dimensions='width')
        plot.add_tools(cty_hover_tool, hwy_hover_tool, select_tool)
        layout = Column(plot, data_table)
        doc = Document()
        doc.add_root(layout)
        return doc
예제 #29
0
    ))

xdr = DataRange1d()
ydr = DataRange1d()

plot = Plot(title=None,
            x_range=xdr,
            y_range=ydr,
            plot_width=300,
            plot_height=300,
            h_symmetry=False,
            v_symmetry=False,
            min_border=0,
            toolbar_location=None)

glyph = HexTile(q="q", r="r", size=1, fill_color="#fb9a99", line_color="white")
plot.add_glyph(source, glyph)

xaxis = LinearAxis()
plot.add_layout(xaxis, 'below')

yaxis = LinearAxis()
plot.add_layout(yaxis, 'left')

plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))

curdoc().add_root(plot)

show(plot)
예제 #30
0
def create_bar_chart(data,
                     title,
                     x_name,
                     y_name,
                     hover_tool=None,
                     width=100,
                     height=100):
    """Creates a bar chart plot with the exact styling for the centcom
       dashboard. Pass in data as a dictionary, desired plot title,
       name of x axis, y axis and the hover tool HTML.
    """
    # import ipdb; ipdb.set_trace()
    vid = deepcopy(data)
    video_id = vid.pop('video_id', None)
    data_sorted = sort_dict(vid, x_name, y_name)
    title = "ID " + video_id + " " + title

    source = ColumnDataSource(data_sorted)
    xdr = FactorRange(factors=[str(i) for i in data_sorted[x_name]])
    ydr = Range1d(start=0, end=1.01)

    tools = []
    if hover_tool:
        tools = [
            hover_tool,
        ]

    plot = figure(title=title,
                  x_range=xdr,
                  y_range=ydr,
                  plot_width=width,
                  plot_height=height,
                  h_symmetry=False,
                  v_symmetry=False,
                  min_border=0,
                  toolbar_location="above",
                  tools=tools,
                  responsive=True,
                  outline_line_color="#666666")

    glyph = VBar(x=x_name,
                 top=y_name,
                 bottom=0,
                 width=.8,
                 fill_color="#e12127")
    plot.add_glyph(source, glyph)

    xaxis = LinearAxis()
    yaxis = LinearAxis()

    plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
    plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
    plot.toolbar.logo = None
    plot.min_border_top = 0
    plot.xgrid.grid_line_color = None
    plot.ygrid.grid_line_color = "#999999"
    plot.yaxis.axis_label = "Probability"
    plot.ygrid.grid_line_alpha = 0.1
    plot.xaxis.axis_label = "Class"
    plot.xaxis.major_label_orientation = 1
    return plot